diff --git a/.github/workflows/build-arm64-image.yaml b/.github/workflows/build-arm64-image.yaml index 4d4e4f33273e..d20e96aa663e 100644 --- a/.github/workflows/build-arm64-image.yaml +++ b/.github/workflows/build-arm64-image.yaml @@ -24,7 +24,7 @@ env: jobs: build: name: Build arm64 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 diff --git a/.github/workflows/build-kube-ovn-base-dpdk.yaml b/.github/workflows/build-kube-ovn-base-dpdk.yaml index 626bf736e541..3bc926fd46fe 100644 --- a/.github/workflows/build-kube-ovn-base-dpdk.yaml +++ b/.github/workflows/build-kube-ovn-base-dpdk.yaml @@ -23,7 +23,7 @@ jobs: - release-1.12 - release-1.12-mc name: Build AMD64 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 if: (github.event.inputs.branch || matrix.branch) == matrix.branch @@ -58,7 +58,7 @@ jobs: needs: - build-amd64 name: push - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 if: (github.event.inputs.branch || matrix.branch) == matrix.branch diff --git a/.github/workflows/build-kube-ovn-base.yaml b/.github/workflows/build-kube-ovn-base.yaml index 54620cbbc027..59029dcf3273 100644 --- a/.github/workflows/build-kube-ovn-base.yaml +++ b/.github/workflows/build-kube-ovn-base.yaml @@ -27,7 +27,7 @@ jobs: - release-1.9 - release-1.12-mc name: Build AMD64 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 if: (github.event.inputs.branch || matrix.branch) == matrix.branch @@ -62,7 +62,7 @@ jobs: - release-1.9 - release-1.12-mc name: Build ARM64 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 if: (github.event.inputs.branch || matrix.branch) == matrix.branch @@ -105,7 +105,7 @@ jobs: - build-arm64 - build-amd64 name: push - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 if: (github.event.inputs.branch || matrix.branch) == matrix.branch diff --git a/.github/workflows/build-kube-ovn-test.yaml b/.github/workflows/build-kube-ovn-test.yaml index 3315745710ce..bac7de0b4bff 100644 --- a/.github/workflows/build-kube-ovn-test.yaml +++ b/.github/workflows/build-kube-ovn-test.yaml @@ -7,7 +7,7 @@ env: jobs: build: name: Build Test - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 diff --git a/.github/workflows/build-windows.yaml b/.github/workflows/build-windows.yaml index 6ffc33d297cc..c15aa8019bff 100644 --- a/.github/workflows/build-windows.yaml +++ b/.github/workflows/build-windows.yaml @@ -28,7 +28,7 @@ env: jobs: filter: name: Path Filter - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 outputs: build-ovs-ovn: ${{ steps.filter.outputs.windows-ovs-ovn }} build-kube-ovn: ${{ steps.filter.outputs.windows-kube-ovn }} diff --git a/.github/workflows/build-x86-image.yaml b/.github/workflows/build-x86-image.yaml index dd58f3c4c4f2..9314c96544e2 100644 --- a/.github/workflows/build-x86-image.yaml +++ b/.github/workflows/build-x86-image.yaml @@ -23,14 +23,14 @@ concurrency: env: GO_VERSION: '' KIND_VERSION: v0.23.0 - GOSEC_VERSION: '2.20.0' - HELM_VERSION: v3.14.4 - SUBMARINER_VERSION: '0.17.1' + GOLANGCI_LINT_VERSION: 'v1.59.1' + HELM_VERSION: v3.15.3 + SUBMARINER_VERSION: '0.18.0' jobs: build-kube-ovn-base: name: Build kube-ovn-base - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 outputs: build-base: ${{ steps.check.outputs.build-base }} steps: @@ -77,7 +77,7 @@ jobs: build-kube-ovn-dpdk-base: name: Build kube-ovn-dpdk-base - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 outputs: build-dpdk-base: ${{ steps.check.outputs.build-dpdk-base }} steps: @@ -124,7 +124,7 @@ jobs: build-kube-ovn: name: Build kube-ovn - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: - build-kube-ovn-base - build-kube-ovn-dpdk-base @@ -167,14 +167,9 @@ jobs: go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo make ut - - name: Install gosec + - name: Install golangci-lint run: | - tmp=$(mktemp -d) - archive="gosec_${{ env.GOSEC_VERSION }}_$(go env GOHOSTOS)_$(go env GOHOSTARCH).tar.gz" - wget -q -O "$tmp/$archive" https://github.com/securego/gosec/releases/download/v${{ env.GOSEC_VERSION }}/$archive - tar --no-same-owner -C "$tmp" -xzf "$tmp/$archive" - install "$tmp/gosec" /usr/local/bin - rm -rf $tmp + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin $GOLANGCI_LINT_VERSION - name: Download base images if: needs.build-kube-ovn-base.outputs.build-base == 1 @@ -303,7 +298,7 @@ jobs: build-vpc-nat-gateway: name: Build vpc-nat-gateway - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: jlumbroso/free-disk-space@v1.3.1 with: @@ -330,7 +325,7 @@ jobs: build-e2e-binaries: name: Build E2E Binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: - uses: actions/checkout@v4 @@ -409,7 +404,7 @@ jobs: netpol-path-filter: name: Network Policy Path Filter if: github.event_name != 'pull_request' - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 outputs: test-netpol: ${{ steps.filter.outputs.kube-ovn-controller }} steps: @@ -446,7 +441,7 @@ jobs: needs: - build-kube-ovn - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 25 strategy: fail-fast: false @@ -538,10 +533,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-${{ matrix.ip-family }} - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-${{ matrix.ip-family }} - name: Install Kube-OVN id: install @@ -641,7 +634,7 @@ jobs: - build-kube-ovn - build-e2e-binaries - netpol-path-filter - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 90 strategy: fail-fast: false @@ -730,10 +723,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-${{ matrix.ip-family }} - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-${{ matrix.ip-family }} - name: Install Kube-OVN id: install @@ -828,7 +819,7 @@ jobs: needs: - build-kube-ovn - netpol-path-filter - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 30 strategy: fail-fast: false @@ -893,10 +884,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-${{ matrix.ip-family }} - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-${{ matrix.ip-family }} - name: Install Kube-OVN id: install @@ -988,7 +977,7 @@ jobs: needs: - build-kube-ovn - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 40 strategy: fail-fast: false @@ -1075,10 +1064,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-${{ matrix.ip-family }} - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-${{ matrix.ip-family }} - name: Install Kube-OVN id: install @@ -1173,14 +1160,14 @@ jobs: done - name: Cleanup - run: sh -x dist/images/cleanup.sh + run: timeout -k 10 180 sh -x dist/images/cleanup.sh kube-ovn-ic-conformance-e2e: name: Kube-OVN IC Conformance E2E needs: - build-kube-ovn - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -1261,10 +1248,8 @@ jobs: - name: Create kind clusters run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-ovn-ic-${{ matrix.ip-family }} - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-ovn-ic-${{ matrix.ip-family }} - name: Install Kube-OVN id: install @@ -1339,7 +1324,7 @@ jobs: needs: - build-kube-ovn - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 10 strategy: fail-fast: false @@ -1420,10 +1405,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-${{ matrix.ip-family }} - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-${{ matrix.ip-family }} - name: Install Kube-OVN id: install @@ -1486,7 +1469,7 @@ jobs: chart-test: name: Chart Installation/Uninstallation Test needs: build-kube-ovn - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -1523,10 +1506,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init - name: Install Kube-OVN id: install @@ -1544,7 +1525,7 @@ jobs: underlay-logical-gateway-installation-test: name: Underlay Logical Gateway Installation Test needs: build-kube-ovn - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -1575,10 +1556,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-dual - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-dual - name: Install Kube-OVN id: install @@ -1589,12 +1568,12 @@ jobs: run: make check-kube-ovn-pod-restarts - name: Cleanup - run: sh -x dist/images/cleanup.sh + run: timeout -k 10 180 sh -x dist/images/cleanup.sh no-ovn-lb-test: name: Disable OVN LB Test needs: build-kube-ovn - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -1625,10 +1604,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init - name: Install Kube-OVN without LoadBalancer id: install @@ -1641,12 +1618,12 @@ jobs: run: make check-kube-ovn-pod-restarts - name: Cleanup - run: sh -x dist/images/cleanup.sh + run: timeout -k 10 180 sh -x dist/images/cleanup.sh no-np-test: name: Disable Network Policy Test needs: build-kube-ovn - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -1677,10 +1654,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init - name: Install Kube-OVN id: install @@ -1693,7 +1668,7 @@ jobs: run: make check-kube-ovn-pod-restarts - name: Cleanup - run: sh -x dist/images/cleanup.sh + run: timeout -k 10 180 sh -x dist/images/cleanup.sh lb-svc-e2e: name: LB Service E2E @@ -1701,7 +1676,7 @@ jobs: - build-kube-ovn - build-vpc-nat-gateway - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -1782,10 +1757,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init - name: Install Multus and Kube-OVN id: install @@ -1846,7 +1819,7 @@ jobs: needs: - build-kube-ovn - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -1921,10 +1894,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init - name: Install Kube-OVN with webhook id: install @@ -1957,7 +1928,7 @@ jobs: installation-compatibility-test: name: Installation Compatibility Test needs: build-kube-ovn - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -1990,10 +1961,8 @@ jobs: env: k8s_version: v1.23.17 run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init - name: Install Kube-OVN id: install @@ -2017,14 +1986,14 @@ jobs: path: installation-compatibility-test-ko-log.tar.gz - name: Cleanup - run: sh -x dist/images/cleanup.sh + run: timeout -k 10 180 sh -x dist/images/cleanup.sh cilium-chaining-e2e: name: Cilium Chaining E2E needs: - build-kube-ovn - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 30 strategy: fail-fast: false @@ -2116,10 +2085,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-cilium-chaining-${{ matrix.ip-family }} - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-cilium-chaining-${{ matrix.ip-family }} - name: Install Kube-OVN with Cilium chaining id: install @@ -2179,14 +2146,14 @@ jobs: run: make check-kube-ovn-pod-restarts - name: Cleanup - run: sh -x dist/images/cleanup.sh + run: timeout -k 10 180 sh -x dist/images/cleanup.sh kube-ovn-ha-e2e: name: Kube-OVN HA E2E needs: - build-kube-ovn - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 15 strategy: fail-fast: false @@ -2273,10 +2240,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-ha-${{ matrix.ip-family }} - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-ha-${{ matrix.ip-family }} - name: Install Kube-OVN id: install @@ -2314,13 +2279,13 @@ jobs: run: make check-kube-ovn-pod-restarts - name: Cleanup - run: sh -x dist/images/cleanup.sh + run: timeout -k 10 180 sh -x dist/images/cleanup.sh kube-ovn-submariner-conformance-e2e: name: Kube-OVN Submariner Conformance E2E needs: - build-kube-ovn - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 60 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -2377,10 +2342,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init-ovn-submariner - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init-ovn-submariner - name: Install Kube-OVN and Submariner id: install @@ -2409,7 +2372,7 @@ jobs: run: make check-kube-ovn-pod-restarts - name: Cleanup - run: sh -x dist/images/cleanup.sh + run: timeout -k 10 180 sh -x dist/images/cleanup.sh iptables-vpc-nat-gw-conformance-e2e: name: Iptables VPC NAT Gateway E2E @@ -2417,7 +2380,7 @@ jobs: - build-kube-ovn - build-vpc-nat-gateway - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -2498,10 +2461,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init - name: Install Kube-OVN with VPC NAT gateway enabled id: install @@ -2562,7 +2523,7 @@ jobs: needs: - build-kube-ovn - build-e2e-binaries - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: - uses: jlumbroso/free-disk-space@v1.3.1 @@ -2636,10 +2597,8 @@ jobs: - name: Create kind cluster run: | - sudo pip3 install jinjanator - sudo --preserve-env=CI PATH=~/.local/bin:$PATH make kind-init - sudo cp -r /root/.kube/ ~/.kube/ - sudo chown -R $(id -un). ~/.kube/ + pipx install jinjanator + make kind-init - name: Install Kube-OVN id: install @@ -2724,7 +2683,7 @@ jobs: - kube-ovn-ha-e2e - kube-ovn-submariner-conformance-e2e if: always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: jlumbroso/free-disk-space@v1.3.1 with: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index fc5d7432e04a..6440d733f13b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -24,7 +24,7 @@ env: jobs: analyze: name: Analyze - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml deleted file mode 100644 index 6a01606c53ff..000000000000 --- a/.github/workflows/lint.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: golangci-lint -on: - push: - tags: - - v* - branches: - - master - - main - pull_request: - -concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" - cancel-in-progress: true - -env: - GO_VERSION: '' - -jobs: - golangci: - name: lint - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION || '' }} - go-version-file: go.mod - check-latest: true - cache: false - - - name: golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. - version: latest - - # Optional: working directory, useful for monorepos - # working-directory: somedir - - # Optional: golangci-lint command line arguments. - args: --timeout 20m --verbose - # Optional: show only new issues if it's a pull request. The default value is `false`. - # only-new-issues: true diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index fd2d7c3d4046..7dab65923dcf 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -11,7 +11,7 @@ concurrency: jobs: build: name: Publish Images - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.golangci.yml b/.golangci.yml index 10ba84a7e655..4e4ddf5afdc2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -15,6 +15,13 @@ linters: - unconvert - unused - errcheck + - gosec + - govet + - perfsprint + - usestdlibvars + - loggercheck + - whitespace + - errorlint issues: max-same-issues: 0 @@ -31,10 +38,20 @@ issues: - linters: - revive text: "VpcDnsList should be VpcDNSList" # api param not change + - linters: + - gosec + path: _test\.go + - linters: + - gosec + path: test/ linters-settings: goimports: local-prefixes: github.com/kubeovn/kube-ovn gofumpt: extra-rules: true + perfsprint: + strconcat: false + errorlint: + asserts: false diff --git a/Makefile b/Makefile index c764ec564be3..45ad280f5a4a 100644 --- a/Makefile +++ b/Makefile @@ -27,21 +27,21 @@ endif CONTROL_PLANE_TAINTS = node-role.kubernetes.io/master node-role.kubernetes.io/control-plane -FRR_VERSION = 9.0.2 +FRR_VERSION = 9.1.1 FRR_IMAGE = quay.io/frrouting/frr:$(FRR_VERSION) -CLAB_IMAGE = ghcr.io/srl-labs/clab:0.54.2 +CLAB_IMAGE = ghcr.io/srl-labs/clab:0.56.0 MULTUS_VERSION = v4.0.2 MULTUS_IMAGE = ghcr.io/k8snetworkplumbingwg/multus-cni:$(MULTUS_VERSION)-thick MULTUS_YAML = https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/$(MULTUS_VERSION)/deployments/multus-daemonset-thick.yml -METALLB_VERSION = 0.14.5 +METALLB_VERSION = 0.14.7 METALLB_CHART_REPO = https://metallb.github.io/metallb METALLB_CONTROLLER_IMAGE = quay.io/metallb/controller:v$(METALLB_VERSION) METALLB_SPEAKER_IMAGE = quay.io/metallb/speaker:v$(METALLB_VERSION) -KUBEVIRT_VERSION = v1.2.1 +KUBEVIRT_VERSION = v1.3.0 KUBEVIRT_OPERATOR_IMAGE = quay.io/kubevirt/virt-operator:$(KUBEVIRT_VERSION) KUBEVIRT_API_IMAGE = quay.io/kubevirt/virt-api:$(KUBEVIRT_VERSION) KUBEVIRT_CONTROLLER_IMAGE = quay.io/kubevirt/virt-controller:$(KUBEVIRT_VERSION) @@ -50,16 +50,16 @@ KUBEVIRT_LAUNCHER_IMAGE = quay.io/kubevirt/virt-launcher:$(KUBEVIRT_VERSION) KUBEVIRT_OPERATOR_YAML = https://github.com/kubevirt/kubevirt/releases/download/$(KUBEVIRT_VERSION)/kubevirt-operator.yaml KUBEVIRT_CR_YAML = https://github.com/kubevirt/kubevirt/releases/download/$(KUBEVIRT_VERSION)/kubevirt-cr.yaml -CILIUM_VERSION = 1.15.5 +CILIUM_VERSION = 1.15.7 CILIUM_IMAGE_REPO = quay.io/cilium -CERT_MANAGER_VERSION = v1.14.5 +CERT_MANAGER_VERSION = v1.15.1 CERT_MANAGER_CONTROLLER = quay.io/jetstack/cert-manager-controller:$(CERT_MANAGER_VERSION) CERT_MANAGER_CAINJECTOR = quay.io/jetstack/cert-manager-cainjector:$(CERT_MANAGER_VERSION) CERT_MANAGER_WEBHOOK = quay.io/jetstack/cert-manager-webhook:$(CERT_MANAGER_VERSION) CERT_MANAGER_YAML = https://github.com/cert-manager/cert-manager/releases/download/$(CERT_MANAGER_VERSION)/cert-manager.yaml -SUBMARINER_VERSION = $(shell echo $${SUBMARINER_VERSION:-0.17.1}) +SUBMARINER_VERSION = $(shell echo $${SUBMARINER_VERSION:-0.18.0}) SUBMARINER_OPERATOR = quay.io/submariner/submariner-operator:$(SUBMARINER_VERSION) SUBMARINER_GATEWAY = quay.io/submariner/submariner-gateway:$(SUBMARINER_VERSION) SUBMARINER_LIGHTHOUSE_AGENT = quay.io/submariner/lighthouse-agent:$(SUBMARINER_VERSION) @@ -78,7 +78,7 @@ DEEPFLOW_GRAFANA_NODE_PORT = 30080 DEEPFLOW_MAPPED_PORTS = $(DEEPFLOW_SERVER_NODE_PORT),$(DEEPFLOW_SERVER_GRPC_PORT),$(DEEPFLOW_SERVER_HTTP_PORT),$(DEEPFLOW_GRAFANA_NODE_PORT) DEEPFLOW_CTL_URL = https://deepflow-ce.oss-cn-beijing.aliyuncs.com/bin/ctl/$(DEEPFLOW_VERSION)/linux/$(shell arch | sed 's|x86_64|amd64|' | sed 's|aarch64|arm64|')/deepflow-ctl -KWOK_VERSION = v0.5.2 +KWOK_VERSION = v0.6.0 KWOK_IMAGE = registry.k8s.io/kwok/kwok:$(KWOK_VERSION) VPC_NAT_GW_IMG = $(REGISTRY)/vpc-nat-gateway:$(VERSION) @@ -972,16 +972,7 @@ uninstall: .PHONY: lint lint: - @gofmt -d . - @if [ $$(gofmt -l . | wc -l) -ne 0 ]; then \ - echo "Code differs from gofmt's style" 1>&2 && exit 1; \ - fi - @GOOS=linux go vet ./... - @GOOS=linux gosec -exclude-dir=test -exclude-dir=pkg/client ./... - -.PHONY: gofumpt -gofumpt: - gofumpt -w -extra . + golangci-lint run -v .PHONY: lint-windows lint-windows: @@ -1026,3 +1017,9 @@ clean: .PHONY: changelog changelog: ./hack/changelog.sh > CHANGELOG.md + +.PHONY: local-dev +local-dev: build-go + docker buildx build --platform linux/amd64 -t $(REGISTRY)/kube-ovn:$(RELEASE_TAG) --build-arg VERSION=$(RELEASE_TAG) -o type=docker -f dist/images/Dockerfile dist/images/ + docker buildx build --platform linux/amd64 -t $(REGISTRY)/vpc-nat-gateway:$(RELEASE_TAG) -o type=docker -f dist/images/vpcnatgateway/Dockerfile dist/images/vpcnatgateway + @$(MAKE) kind-init kind-install \ No newline at end of file diff --git a/charts/kube-ovn/templates/central-deploy.yaml b/charts/kube-ovn/templates/central-deploy.yaml index 03a1bab7a4ad..5947e162fbed 100644 --- a/charts/kube-ovn/templates/central-deploy.yaml +++ b/charts/kube-ovn/templates/central-deploy.yaml @@ -45,10 +45,15 @@ spec: image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} command: + - bash - /kube-ovn/start-db.sh securityContext: + runAsUser: 0 + privileged: false capabilities: - add: ["SYS_NICE"] + add: + - NET_BIND_SERVICE + - SYS_NICE env: - name: ENABLE_SSL value: "{{ .Values.networking.ENABLE_SSL }}" diff --git a/charts/kube-ovn/templates/controller-deploy.yaml b/charts/kube-ovn/templates/controller-deploy.yaml index c5f908a71340..5c43dd6a178f 100644 --- a/charts/kube-ovn/templates/controller-deploy.yaml +++ b/charts/kube-ovn/templates/controller-deploy.yaml @@ -116,6 +116,13 @@ spec: - --keep-vm-ip={{- .Values.func.ENABLE_KEEP_VM_IP }} - --enable-metrics={{- .Values.networking.ENABLE_METRICS }} - --node-local-dns-ip={{- .Values.networking.NODE_LOCAL_DNS_IP }} + - --secure-serving={{- .Values.func.SECURE_SERVING }} + securityContext: + runAsUser: 0 + privileged: false + capabilities: + add: + - NET_BIND_SERVICE env: - name: ENABLE_SSL value: "{{ .Values.networking.ENABLE_SSL }}" @@ -123,6 +130,10 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace - name: KUBE_NAMESPACE valueFrom: fieldRef: @@ -133,6 +144,10 @@ spec: fieldPath: spec.nodeName - name: OVN_DB_IPS value: "{{ .Values.MASTER_NODES | default (include "kubeovn.nodeIPs" .) }}" + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP - name: POD_IPS valueFrom: fieldRef: @@ -154,12 +169,14 @@ spec: exec: command: - /kube-ovn/kube-ovn-controller-healthcheck + - --tls={{- .Values.func.SECURE_SERVING }} periodSeconds: 3 timeoutSeconds: 45 livenessProbe: exec: command: - /kube-ovn/kube-ovn-controller-healthcheck + - --tls={{- .Values.func.SECURE_SERVING }} initialDelaySeconds: 300 periodSeconds: 7 failureThreshold: 5 diff --git a/charts/kube-ovn/templates/monitor-deploy.yaml b/charts/kube-ovn/templates/monitor-deploy.yaml index 5099feb2b7be..88bf77c29853 100644 --- a/charts/kube-ovn/templates/monitor-deploy.yaml +++ b/charts/kube-ovn/templates/monitor-deploy.yaml @@ -44,6 +44,7 @@ spec: imagePullPolicy: {{ .Values.image.pullPolicy }} command: ["/kube-ovn/start-ovn-monitor.sh"] args: + - --secure-serving={{- .Values.func.SECURE_SERVING }} - --log_file=/var/log/kube-ovn/kube-ovn-monitor.log - --logtostderr=false - --alsologtostderr=true @@ -58,6 +59,18 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP - name: POD_IPS valueFrom: fieldRef: diff --git a/charts/kube-ovn/templates/ovn-CR.yaml b/charts/kube-ovn/templates/ovn-CR.yaml index 6f0ae15e9a19..fcee62795102 100644 --- a/charts/kube-ovn/templates/ovn-CR.yaml +++ b/charts/kube-ovn/templates/ovn-CR.yaml @@ -154,7 +154,27 @@ rules: verbs: - get - list - + - apiGroups: + - "policy.networking.k8s.io" + resources: + - adminnetworkpolicies + - baselineadminnetworkpolicies + verbs: + - get + - list + - watch + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -239,7 +259,18 @@ rules: - get - list - watch - + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -262,3 +293,15 @@ rules: - daemonsets verbs: - get + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/charts/kube-ovn/templates/ovn-CRB.yaml b/charts/kube-ovn/templates/ovn-CRB.yaml index 9230d90035b3..7cc43d84e51e 100644 --- a/charts/kube-ovn/templates/ovn-CRB.yaml +++ b/charts/kube-ovn/templates/ovn-CRB.yaml @@ -10,7 +10,20 @@ subjects: - kind: ServiceAccount name: ovn namespace: {{ .Values.namespace }} - +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ovn + namespace: {{ .Values.namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: ovn + namespace: {{ .Values.namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -38,7 +51,20 @@ subjects: - kind: ServiceAccount name: kube-ovn-cni namespace: {{ .Values.namespace }} - +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kube-ovn-cni + namespace: {{ .Values.namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: kube-ovn-cni + namespace: {{ .Values.namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -52,3 +78,17 @@ subjects: - kind: ServiceAccount name: kube-ovn-app namespace: {{ .Values.namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kube-ovn-app + namespace: {{ .Values.namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: kube-ovn-app + namespace: {{ .Values.namespace }} diff --git a/charts/kube-ovn/templates/ovncni-ds.yaml b/charts/kube-ovn/templates/ovncni-ds.yaml index c293407e31d2..d5b4ad0914b6 100644 --- a/charts/kube-ovn/templates/ovncni-ds.yaml +++ b/charts/kube-ovn/templates/ovncni-ds.yaml @@ -82,9 +82,16 @@ spec: - --kubelet-dir={{ .Values.kubelet_conf.KUBELET_DIR }} - --enable-tproxy={{ .Values.func.ENABLE_TPROXY }} - --ovs-vsctl-concurrency={{ .Values.performance.OVS_VSCTL_CONCURRENCY }} + - --secure-serving={{- .Values.func.SECURE_SERVING }} securityContext: runAsUser: 0 - privileged: true + privileged: false + capabilities: + add: + - NET_ADMIN + - NET_BIND_SERVICE + - NET_RAW + - SYS_ADMIN env: - name: ENABLE_SSL value: "{{ .Values.networking.ENABLE_SSL }}" @@ -96,6 +103,14 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace - name: POD_IPS valueFrom: fieldRef: @@ -117,7 +132,7 @@ spec: name: cni-conf - mountPath: /run/openvswitch name: host-run-ovs - mountPropagation: Bidirectional + mountPropagation: HostToContainer - mountPath: /run/ovn name: host-run-ovn - mountPath: /host/var/run/dbus diff --git a/charts/kube-ovn/templates/ovsovn-ds.yaml b/charts/kube-ovn/templates/ovsovn-ds.yaml index 8e11d767abbb..04cdaf767046 100644 --- a/charts/kube-ovn/templates/ovsovn-ds.yaml +++ b/charts/kube-ovn/templates/ovsovn-ds.yaml @@ -62,7 +62,13 @@ spec: {{- end }} securityContext: runAsUser: 0 - privileged: true + privileged: false + capabilities: + add: + - NET_ADMIN + - NET_BIND_SERVICE + - SYS_MODULE + - SYS_NICE env: - name: ENABLE_SSL value: "{{ .Values.networking.ENABLE_SSL }}" diff --git a/charts/kube-ovn/values.yaml b/charts/kube-ovn/values.yaml index 94884e3f400f..5cc9f63ba045 100644 --- a/charts/kube-ovn/values.yaml +++ b/charts/kube-ovn/values.yaml @@ -68,6 +68,7 @@ func: CHECK_GATEWAY: true LOGICAL_GATEWAY: false ENABLE_BIND_LOCAL_IP: true + SECURE_SERVING: false U2O_INTERCONNECTION: false ENABLE_TPROXY: false ENABLE_IC: false diff --git a/cmd/controller/controller.go b/cmd/controller/controller.go index 0c98312addfa..faf30e00f7dc 100644 --- a/cmd/controller/controller.go +++ b/cmd/controller/controller.go @@ -3,25 +3,27 @@ package controller import ( "context" "fmt" + "net" "net/http" "net/http/pprof" "os" - "strings" "time" - "github.com/prometheus/client_golang/prometheus/promhttp" v1 "k8s.io/api/authorization/v1" apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/leaderelection" "k8s.io/client-go/tools/leaderelection/resourcelock" "k8s.io/client-go/tools/record" "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/manager/signals" kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" "github.com/kubeovn/kube-ovn/pkg/controller" + "github.com/kubeovn/kube-ovn/pkg/metrics" "github.com/kubeovn/kube-ovn/pkg/util" "github.com/kubeovn/kube-ovn/versions" ) @@ -31,19 +33,10 @@ const ovnLeaderResource = "kube-ovn-controller" func CmdMain() { defer klog.Flush() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go func() { - stopCh := signals.SetupSignalHandler().Done() - <-stopCh - cancel() - }() + ctx := signals.SetupSignalHandler() klog.Infof(versions.String()) - controller.InitClientGoMetrics() - controller.InitWorkQueueMetrics() - util.InitKlogMetrics() config, err := controller.ParseFlags() if err != nil { util.LogFatalAndExit(err, "failed to parse config") @@ -52,44 +45,50 @@ func CmdMain() { if err := checkPermission(config); err != nil { util.LogFatalAndExit(err, "failed to check permission") } + utilruntime.Must(kubeovnv1.AddToScheme(scheme.Scheme)) go func() { - mux := http.NewServeMux() - if config.EnableMetrics { - mux.Handle("/metrics", promhttp.Handler()) - } if config.EnablePprof { + mux := http.NewServeMux() mux.HandleFunc("/debug/pprof/", pprof.Index) mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) mux.HandleFunc("/debug/pprof/profile", pprof.Profile) mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) mux.HandleFunc("/debug/pprof/trace", pprof.Trace) - } - addr := "0.0.0.0" - if os.Getenv("ENABLE_BIND_LOCAL_IP") == "true" { - podIpsEnv := os.Getenv("POD_IPS") - podIps := strings.Split(podIpsEnv, ",") - // when pod in dual mode, golang can't support bind v4 and v6 address in the same time, - // so not support bind local ip when in dual mode - if len(podIps) == 1 { - addr = podIps[0] - if util.CheckProtocol(podIps[0]) == kubeovnv1.ProtocolIPv6 { - addr = fmt.Sprintf("[%s]", podIps[0]) - } + listerner, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: int(config.PprofPort)}) + if err != nil { + util.LogFatalAndExit(err, "failed to listen on %s", util.JoinHostPort("127.0.0.1", config.PprofPort)) } + svr := manager.Server{ + Name: "pprof", + Server: &http.Server{ + Handler: mux, + MaxHeaderBytes: 1 << 20, + IdleTimeout: 90 * time.Second, + ReadHeaderTimeout: 32 * time.Second, + }, + Listener: listerner, + } + go func() { + if err = svr.Start(ctx); err != nil { + util.LogFatalAndExit(err, "failed to run pprof server") + } + }() + } + + if !config.EnableMetrics { + return } - // conform to Gosec G114 - // https://github.com/securego/gosec#available-rules - server := &http.Server{ - Addr: fmt.Sprintf("%s:%d", addr, config.PprofPort), - ReadHeaderTimeout: 3 * time.Second, - Handler: mux, + metrics.InitKlogMetrics() + metrics.InitClientGoMetrics() + addr := util.JoinHostPort(util.GetDefaultListenAddr(), config.PprofPort) + if err := metrics.Run(ctx, config.KubeRestConfig, addr, config.SecureServing); err != nil { + util.LogFatalAndExit(err, "failed to run metrics server") } - util.LogFatalAndExit(server.ListenAndServe(), "failed to listen and server on %s", server.Addr) + <-ctx.Done() }() - // ctx, cancel := context.WithCancel(context.Background()) recorder := record.NewBroadcaster().NewRecorder(scheme.Scheme, apiv1.EventSource{ Component: ovnLeaderResource, Host: os.Getenv(util.HostnameEnv), diff --git a/cmd/controller_health_check/controller_health_check.go b/cmd/controller_health_check/controller_health_check.go index 0c38a82d4896..7e04769210fe 100644 --- a/cmd/controller_health_check/controller_health_check.go +++ b/cmd/controller_health_check/controller_health_check.go @@ -1,37 +1,49 @@ package controller_health_check import ( - "fmt" - "net" + "flag" "os" - "strings" "time" - kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" + "github.com/spf13/pflag" + "k8s.io/klog/v2" + "github.com/kubeovn/kube-ovn/pkg/util" ) func CmdMain() { - addr := "127.0.0.1:10660" - if os.Getenv("ENABLE_BIND_LOCAL_IP") == "true" { - podIpsEnv := os.Getenv("POD_IPS") - podIps := strings.Split(podIpsEnv, ",") - // when pod in dual mode, golang can't support bind v4 and v6 address in the same time, - // so not support bind local ip when in dual mode - if len(podIps) == 1 { - addr = fmt.Sprintf("%s:10660", podIps[0]) - if util.CheckProtocol(podIps[0]) == kubeovnv1.ProtocolIPv6 { - addr = fmt.Sprintf("[%s]:10660", podIps[0]) + tls := pflag.Bool("tls", false, "Whether kube-ovn-controller uses TLS") + + klogFlags := flag.NewFlagSet("klog", flag.ExitOnError) + klog.InitFlags(klogFlags) + + // sync the glog and klog flags. + pflag.CommandLine.VisitAll(func(f1 *pflag.Flag) { + f2 := klogFlags.Lookup(f1.Name) + if f2 != nil { + value := f1.Value.String() + if err := f2.Value.Set(value); err != nil { + util.LogFatalAndExit(err, "failed to set pflag") } } + }) + + pflag.CommandLine.AddGoFlagSet(klogFlags) + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() + + addr := "127.0.0.1:10660" + if os.Getenv("ENABLE_BIND_LOCAL_IP") == "true" { + addr = util.JoinHostPort(os.Getenv("POD_IP"), 10660) } - conn, err := net.DialTimeout("tcp", addr, 3*time.Second) - if err != nil { - util.LogFatalAndExit(err, "failed to probe the socket") + if *tls { + addr = "tls://" + addr + } else { + addr = "tcp://" + addr } - err = conn.Close() - if err != nil { - util.LogFatalAndExit(err, "failed to close connection") + + if err := util.DialTCP(addr, time.Second, false); err != nil { + util.LogFatalAndExit(err, "failed to probe the socket") } } diff --git a/cmd/daemon/cniserver.go b/cmd/daemon/cniserver.go index 448ea42da7b1..00d0b0e164a3 100644 --- a/cmd/daemon/cniserver.go +++ b/cmd/daemon/cniserver.go @@ -1,7 +1,9 @@ package daemon import ( + "errors" "fmt" + "net" "net/http" "net/http/pprof" "os" @@ -9,14 +11,15 @@ import ( "strings" "time" - "github.com/prometheus/client_golang/prometheus/promhttp" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubeinformers "k8s.io/client-go/informers" "k8s.io/klog/v2" - "k8s.io/sample-controller/pkg/signals" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" kubeovninformer "github.com/kubeovn/kube-ovn/pkg/client/informers/externalversions" "github.com/kubeovn/kube-ovn/pkg/daemon" + "github.com/kubeovn/kube-ovn/pkg/metrics" "github.com/kubeovn/kube-ovn/pkg/ovs" "github.com/kubeovn/kube-ovn/pkg/util" "github.com/kubeovn/kube-ovn/versions" @@ -26,7 +29,7 @@ func CmdMain() { defer klog.Flush() daemon.InitMetrics() - util.InitKlogMetrics() + metrics.InitKlogMetrics() config := daemon.ParseFlags() klog.Infof(versions.String()) @@ -59,7 +62,8 @@ func CmdMain() { util.LogFatalAndExit(err, "failed to do the OS initialization") } - stopCh := signals.SetupSignalHandler().Done() + ctx := signals.SetupSignalHandler() + stopCh := ctx.Done() podInformerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(config.KubeClient, 0, kubeinformers.WithTweakListOptions(func(listOption *v1.ListOptions) { listOption.FieldSelector = fmt.Sprintf("spec.nodeName=%s", config.NodeName) @@ -84,44 +88,57 @@ func CmdMain() { util.LogFatalAndExit(err, "failed to mv cni config file") } - mux := http.NewServeMux() - if config.EnableMetrics { - mux.Handle("/metrics", promhttp.Handler()) - } - if config.EnablePprof { - mux.HandleFunc("/debug/pprof/", pprof.Index) - mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) - mux.HandleFunc("/debug/pprof/profile", pprof.Profile) - mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) - mux.HandleFunc("/debug/pprof/trace", pprof.Trace) - } - addr := util.GetDefaultListenAddr() - if config.EnableVerboseConnCheck { go func() { - connListenaddr := fmt.Sprintf("%s:%d", addr, config.TCPConnCheckPort) + connListenaddr := util.JoinHostPort(addr, config.TCPConnCheckPort) if err := util.TCPConnectivityListen(connListenaddr); err != nil { util.LogFatalAndExit(err, "failed to start TCP listen on addr %s", addr) } }() go func() { - connListenaddr := fmt.Sprintf("%s:%d", addr, config.UDPConnCheckPort) + connListenaddr := util.JoinHostPort(addr, config.UDPConnCheckPort) if err := util.UDPConnectivityListen(connListenaddr); err != nil { util.LogFatalAndExit(err, "failed to start UDP listen on addr %s", addr) } }() } - // conform to Gosec G114 - // https://github.com/securego/gosec#available-rules - server := &http.Server{ - Addr: fmt.Sprintf("%s:%d", addr, config.PprofPort), - ReadHeaderTimeout: 3 * time.Second, - Handler: mux, + if config.EnablePprof { + mux := http.NewServeMux() + mux.HandleFunc("/debug/pprof/", pprof.Index) + mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + + listerner, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: int(config.PprofPort)}) + if err != nil { + util.LogFatalAndExit(err, "failed to listen on %s", util.JoinHostPort("127.0.0.1", config.PprofPort)) + } + svr := manager.Server{ + Name: "pprof", + Server: &http.Server{ + Handler: mux, + MaxHeaderBytes: 1 << 20, + IdleTimeout: 90 * time.Second, + ReadHeaderTimeout: 32 * time.Second, + }, + Listener: listerner, + } + go func() { + if err = svr.Start(ctx); err != nil { + util.LogFatalAndExit(err, "failed to run pprof server") + } + }() + } + + listenAddr := util.JoinHostPort(addr, config.PprofPort) + if err = metrics.Run(ctx, nil, listenAddr, config.SecureServing); err != nil { + util.LogFatalAndExit(err, "failed to run metrics server") } - util.LogFatalAndExit(server.ListenAndServe(), "failed to listen and serve on %s", server.Addr) + <-stopCh } func mvCNIConf(configDir, configFile, confName string) error { @@ -159,7 +176,7 @@ func initChassisAnno(cfg *daemon.Configuration) error { chassesName := strings.TrimSpace(string(chassisID)) if chassesName == "" { // not ready yet - err = fmt.Errorf("chassis id is empty") + err = errors.New("chassis id is empty") klog.Error(err) return err } diff --git a/cmd/daemon/init.go b/cmd/daemon/init.go index bf094065afdb..333a95c407ec 100644 --- a/cmd/daemon/init.go +++ b/cmd/daemon/init.go @@ -14,7 +14,7 @@ func initForOS() error { // disable checksum for genev_sys_6081 as default cmd := exec.Command("sh", "-c", "ethtool -K genev_sys_6081 tx off") if err := cmd.Run(); err != nil { - err := fmt.Errorf("failed to set checksum off for genev_sys_6081, %v", err) + err := fmt.Errorf("failed to set checksum off for genev_sys_6081, %w", err) // should not affect cni pod running if failed, just record err log klog.Error(err) } diff --git a/cmd/ovn_ic_controller/ovn_ic_controller.go b/cmd/ovn_ic_controller/ovn_ic_controller.go index 570637898bd4..610c3cb107e7 100644 --- a/cmd/ovn_ic_controller/ovn_ic_controller.go +++ b/cmd/ovn_ic_controller/ovn_ic_controller.go @@ -2,7 +2,7 @@ package ovn_ic_controller import ( "k8s.io/klog/v2" - "k8s.io/sample-controller/pkg/signals" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" "github.com/kubeovn/kube-ovn/pkg/ovn_ic_controller" "github.com/kubeovn/kube-ovn/pkg/util" diff --git a/cmd/ovn_monitor/ovn_monitor.go b/cmd/ovn_monitor/ovn_monitor.go index 86fb5ae86294..648d4572ab11 100644 --- a/cmd/ovn_monitor/ovn_monitor.go +++ b/cmd/ovn_monitor/ovn_monitor.go @@ -1,21 +1,20 @@ package ovn_monitor import ( - "fmt" - "net/http" "os" "strings" - "time" - "github.com/prometheus/client_golang/prometheus/promhttp" "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" - kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" + "github.com/kubeovn/kube-ovn/pkg/metrics" ovn "github.com/kubeovn/kube-ovn/pkg/ovnmonitor" "github.com/kubeovn/kube-ovn/pkg/util" "github.com/kubeovn/kube-ovn/versions" ) +const port = 10661 + func CmdMain() { defer klog.Flush() @@ -25,39 +24,23 @@ func CmdMain() { util.LogFatalAndExit(err, "failed to parse config") } + addr := config.ListenAddress + if os.Getenv("ENABLE_BIND_LOCAL_IP") == "true" { + if ips := strings.Split(os.Getenv("POD_IPS"), ","); len(ips) == 1 { + addr = util.JoinHostPort(ips[0], port) + } + } + exporter := ovn.NewExporter(config) if err = exporter.StartConnection(); err != nil { klog.Errorf("%s failed to connect db socket properly: %s", ovn.GetExporterName(), err) go exporter.TryClientConnection() } exporter.StartOvnMetrics() - mux := http.NewServeMux() - if config.EnableMetrics { - mux.Handle(config.MetricsPath, promhttp.Handler()) - klog.Infoln("Listening on", config.ListenAddress) - } - - // conform to Gosec G114 - // https://github.com/securego/gosec#available-rules - - addr := config.ListenAddress - if os.Getenv("ENABLE_BIND_LOCAL_IP") == "true" { - podIpsEnv := os.Getenv("POD_IPS") - podIps := strings.Split(podIpsEnv, ",") - // when pod in dual mode, golang can't support bind v4 and v6 address in the same time, - // so not support bind local ip when in dual mode - if len(podIps) == 1 { - addr = fmt.Sprintf("%s:10661", podIps[0]) - if util.CheckProtocol(podIps[0]) == kubeovnv1.ProtocolIPv6 { - addr = fmt.Sprintf("[%s]:10661", podIps[0]) - } - } - } - server := &http.Server{ - Addr: addr, - ReadHeaderTimeout: 3 * time.Second, - Handler: mux, + ctx := signals.SetupSignalHandler() + if err = metrics.Run(ctx, nil, addr, config.SecureServing); err != nil { + util.LogFatalAndExit(err, "failed to run metrics server") } - util.LogFatalAndExit(server.ListenAndServe(), "failed to listen and server on %s", config.ListenAddress) + <-ctx.Done() } diff --git a/cmd/pinger/pinger.go b/cmd/pinger/pinger.go index a3f7d5c67728..342d5f4a4073 100644 --- a/cmd/pinger/pinger.go +++ b/cmd/pinger/pinger.go @@ -1,13 +1,12 @@ package pinger import ( - "net/http" _ "net/http/pprof" // #nosec - "time" - "github.com/prometheus/client_golang/prometheus/promhttp" "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "github.com/kubeovn/kube-ovn/pkg/metrics" "github.com/kubeovn/kube-ovn/pkg/pinger" "github.com/kubeovn/kube-ovn/pkg/util" "github.com/kubeovn/kube-ovn/versions" @@ -21,22 +20,17 @@ func CmdMain() { if err != nil { util.LogFatalAndExit(err, "failed to parse config") } + + ctx := signals.SetupSignalHandler() if config.Mode == "server" { if config.EnableMetrics { - pinger.InitPingerMetrics() - util.InitKlogMetrics() - - mux := http.NewServeMux() - mux.Handle("/metrics", promhttp.Handler()) go func() { - // conform to Gosec G114 - // https://github.com/securego/gosec#available-rules - server := &http.Server{ - Addr: util.JoinHostPort("0.0.0.0", config.Port), - ReadHeaderTimeout: 3 * time.Second, - Handler: mux, + pinger.InitPingerMetrics() + metrics.InitKlogMetrics() + if err := metrics.Run(ctx, nil, util.JoinHostPort("0.0.0.0", config.Port), false); err != nil { + util.LogFatalAndExit(err, "failed to run metrics server") } - util.LogFatalAndExit(server.ListenAndServe(), "failed to listen and serve on %s", server.Addr) + <-ctx.Done() }() } @@ -52,5 +46,5 @@ func CmdMain() { } } } - pinger.StartPinger(config) + pinger.StartPinger(config, ctx.Done()) } diff --git a/cmd/speaker/speaker.go b/cmd/speaker/speaker.go index 8372e36eefe1..0a9441ab7292 100644 --- a/cmd/speaker/speaker.go +++ b/cmd/speaker/speaker.go @@ -7,7 +7,7 @@ import ( "github.com/prometheus/client_golang/prometheus/promhttp" "k8s.io/klog/v2" - "k8s.io/sample-controller/pkg/signals" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" "github.com/kubeovn/kube-ovn/pkg/speaker" "github.com/kubeovn/kube-ovn/pkg/util" diff --git a/dist/images/Dockerfile.base b/dist/images/Dockerfile.base index c6584a61f467..ddeedc94885e 100644 --- a/dist/images/Dockerfile.base +++ b/dist/images/Dockerfile.base @@ -1,5 +1,5 @@ # syntax = docker/dockerfile:experimental -FROM ubuntu:22.04 AS ovs-builder +FROM ubuntu:24.04 AS ovs-builder ARG ARCH ARG LEGACY @@ -53,7 +53,9 @@ RUN cd /usr/src/ && git clone -b branch-24.03 --depth=1 https://github.com/ovn-o # fix lr-lb dnat with multiple distributed gateway ports curl -s https://github.com/kubeovn/ovn/commit/c092b1f74ab2dfcc8d814e7a96d0ed99a1d4ec22.patch | git apply && \ # northd: skip arp/nd request for lrp addresses from localnet ports - curl -s https://github.com/kubeovn/ovn/commit/1aa952f2f1b348739d2585618a6f2afff2ed4501.patch | git apply + curl -s https://github.com/kubeovn/ovn/commit/1aa952f2f1b348739d2585618a6f2afff2ed4501.patch | git apply && \ + # ovn-controller: make activation strategy work for single chassis + curl -s https://github.com/kubeovn/ovn/commit/487cd1c6c0cc9def7cedaaaf3dd4bc99c23974c4.patch | git apply RUN apt install -y build-essential fakeroot \ autoconf automake bzip2 debhelper-compat dh-exec dh-python dh-sequence-python3 dh-sequence-sphinxdoc \ @@ -82,7 +84,7 @@ RUN mkdir /packages/ && \ cp /usr/src/ovn-*deb /packages && \ cd /packages && rm -f *source* *doc* *datapath* *docker* *vtep* *test* *dev* -FROM ubuntu:22.04 +FROM ubuntu:24.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt update && apt upgrade -y && apt install ca-certificates python3 hostname libunwind8 netbase \ @@ -106,7 +108,7 @@ ARG ARCH ARG CNI_VERSION=v1.5.1 RUN curl -sSf -L --retry 5 https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-${ARCH}-${CNI_VERSION}.tgz | tar -xz -C . ./loopback ./portmap ./macvlan -ARG KUBE_VERSION="v1.30.2" +ARG KUBE_VERSION="v1.30.3" RUN curl -L https://dl.k8s.io/${KUBE_VERSION}/kubernetes-client-linux-${ARCH}.tar.gz | tar -xz -C . && cp ./kubernetes/client/bin/kubectl /usr/bin/kubectl \ && chmod +x /usr/bin/kubectl && rm -rf ./kubernetes @@ -116,13 +118,6 @@ RUN curl -sSf -L --retry 3 -o /usr/local/bin/bfdd-control https://github.com/bob curl -sSf -L --retry 3 -o /usr/local/bin/bfdd-beacon https://github.com/bobz965/bfd-binary-for-kube-ovn-cni/releases/download/${BFDD_VERSION}/bfdd-beacon && \ chmod +x /usr/local/bin/bfdd-control /usr/local/bin/bfdd-beacon -RUN curl -sSf -L --retry 3 -O https://launchpad.net/ubuntu/+archive/primary/+files/libipset13_7.17-1ubuntu1_${ARCH}.deb && \ - dpkg -i libipset13_7.17-1ubuntu1_${ARCH}.deb && \ - rm -f libipset13_7.17-1ubuntu1_${ARCH}.deb -RUN curl -sSf -L --retry 3 -O https://launchpad.net/ubuntu/+archive/primary/+files/ipset_7.17-1ubuntu1_${ARCH}.deb && \ - dpkg -i ipset_7.17-1ubuntu1_${ARCH}.deb && \ - rm -f ipset_7.17-1ubuntu1_${ARCH}.deb - RUN --mount=type=bind,target=/packages,from=ovs-builder,source=/packages \ dpkg -i /packages/openvswitch-*.deb /packages/python3-openvswitch*.deb && \ dpkg -i --ignore-depends=openvswitch-switch,openvswitch-common /packages/ovn-*.deb && \ diff --git a/dist/images/Dockerfile.base-dpdk b/dist/images/Dockerfile.base-dpdk index bccb7cda4e06..d8b0cdd0c921 100644 --- a/dist/images/Dockerfile.base-dpdk +++ b/dist/images/Dockerfile.base-dpdk @@ -1,5 +1,5 @@ # syntax = docker/dockerfile:experimental -FROM ubuntu:23.04 AS ovs-builder +FROM ubuntu:24.04 AS ovs-builder ARG ARCH ARG DPDK_VERSION=23.11.1 @@ -87,7 +87,7 @@ RUN mkdir /packages/ && \ cp /usr/src/ovn-*deb /packages && \ cd /packages && rm -f *source* *doc* *datapath* *docker* *vtep* *test* *dev* -FROM ubuntu:23.04 +FROM ubuntu:24.04 ARG DEBIAN_FRONTEND=noninteractive ENV PIP_BREAK_SYSTEM_PACKAGES=1 diff --git a/dist/images/install.sh b/dist/images/install.sh index 4000dea468da..03a0fdd69746 100755 --- a/dist/images/install.sh +++ b/dist/images/install.sh @@ -38,6 +38,7 @@ ENABLE_BIND_LOCAL_IP=${ENABLE_BIND_LOCAL_IP:-true} ENABLE_TPROXY=${ENABLE_TPROXY:-false} OVS_VSCTL_CONCURRENCY=${OVS_VSCTL_CONCURRENCY:-100} ENABLE_COMPACT=${ENABLE_COMPACT:-false} +SECURE_SERVING=${SECURE_SERVING:-false} # debug DEBUG_WRAPPER=${DEBUG_WRAPPER:-} @@ -3084,6 +3085,27 @@ rules: verbs: - get - list + - apiGroups: + - "policy.networking.k8s.io" + resources: + - adminnetworkpolicies + - baselineadminnetworkpolicies + verbs: + - get + - list + - watch + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -3097,6 +3119,20 @@ subjects: - kind: ServiceAccount name: ovn namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ovn + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: ovn + namespace: kube-system EOF cat < kube-ovn-cni-sa.yaml @@ -3160,6 +3196,18 @@ rules: - get - list - watch + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -3173,6 +3221,20 @@ subjects: - kind: ServiceAccount name: kube-ovn-cni namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kube-ovn-cni + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: kube-ovn-cni + namespace: kube-system EOF cat < kube-ovn-app-sa.yaml @@ -3204,6 +3266,18 @@ rules: - daemonsets verbs: - get + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -3217,6 +3291,20 @@ subjects: - kind: ServiceAccount name: kube-ovn-app namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kube-ovn-app + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: kube-ovn-app + namespace: kube-system EOF kubectl apply -f kube-ovn-crd.yaml @@ -3330,10 +3418,15 @@ spec: image: "$REGISTRY/kube-ovn:$VERSION" imagePullPolicy: $IMAGE_PULL_POLICY command: + - bash - /kube-ovn/start-db.sh securityContext: + runAsUser: 0 + privileged: false capabilities: - add: ["SYS_NICE"] + add: + - NET_BIND_SERVICE + - SYS_NICE env: - name: ENABLE_SSL value: "$ENABLE_SSL" @@ -3657,7 +3750,13 @@ spec: - /kube-ovn/start-ovs.sh securityContext: runAsUser: 0 - privileged: true + privileged: false + capabilities: + add: + - NET_ADMIN + - NET_BIND_SERVICE + - SYS_MODULE + - SYS_NICE env: - name: ENABLE_SSL value: "$ENABLE_SSL" @@ -4058,6 +4157,13 @@ spec: - --enable-lb-svc=$ENABLE_LB_SVC - --keep-vm-ip=$ENABLE_KEEP_VM_IP - --node-local-dns-ip=$NODE_LOCAL_DNS_IP + - --secure-serving=${SECURE_SERVING} + securityContext: + runAsUser: 0 + privileged: false + capabilities: + add: + - NET_BIND_SERVICE env: - name: ENABLE_SSL value: "$ENABLE_SSL" @@ -4065,6 +4171,10 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace - name: KUBE_NAMESPACE valueFrom: fieldRef: @@ -4075,6 +4185,10 @@ spec: fieldPath: spec.nodeName - name: OVN_DB_IPS value: $addresses + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP - name: POD_IPS valueFrom: fieldRef: @@ -4096,12 +4210,14 @@ spec: exec: command: - /kube-ovn/kube-ovn-controller-healthcheck + - --tls=${SECURE_SERVING} periodSeconds: 3 timeoutSeconds: 45 livenessProbe: exec: command: - /kube-ovn/kube-ovn-controller-healthcheck + - --tls=${SECURE_SERVING} initialDelaySeconds: 300 periodSeconds: 7 failureThreshold: 5 @@ -4199,9 +4315,16 @@ spec: - --kubelet-dir=$KUBELET_DIR - --enable-tproxy=$ENABLE_TPROXY - --ovs-vsctl-concurrency=$OVS_VSCTL_CONCURRENCY + - --secure-serving=${SECURE_SERVING} securityContext: runAsUser: 0 - privileged: true + privileged: false + capabilities: + add: + - NET_ADMIN + - NET_BIND_SERVICE + - NET_RAW + - SYS_ADMIN env: - name: ENABLE_SSL value: "$ENABLE_SSL" @@ -4217,6 +4340,14 @@ spec: valueFrom: fieldRef: fieldPath: status.podIPs + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace - name: ENABLE_BIND_LOCAL_IP value: "$ENABLE_BIND_LOCAL_IP" - name: DBUS_SYSTEM_BUS_ADDRESS @@ -4234,7 +4365,7 @@ spec: name: cni-conf - mountPath: /run/openvswitch name: host-run-ovs - mountPropagation: Bidirectional + mountPropagation: HostToContainer - mountPath: /run/ovn name: host-run-ovn - mountPath: /host/var/run/dbus @@ -4242,7 +4373,7 @@ spec: mountPropagation: HostToContainer - mountPath: /var/run/netns name: host-ns - mountPropagation: Bidirectional + mountPropagation: HostToContainer - mountPath: /var/log/kube-ovn name: kube-ovn-log - mountPath: /var/log/openvswitch @@ -4482,6 +4613,7 @@ spec: imagePullPolicy: $IMAGE_PULL_POLICY command: ["/kube-ovn/start-ovn-monitor.sh"] args: + - --secure-serving=${SECURE_SERVING} - --log_file=/var/log/kube-ovn/kube-ovn-monitor.log - --logtostderr=false - --alsologtostderr=true @@ -4496,6 +4628,18 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP - name: POD_IPS valueFrom: fieldRef: diff --git a/dist/images/start-db.sh b/dist/images/start-db.sh index c160f1832528..aea83910f25a 100755 --- a/dist/images/start-db.sh +++ b/dist/images/start-db.sh @@ -41,6 +41,9 @@ SB_CLUSTER_PORT=${SB_CLUSTER_PORT:-6644} ENABLE_SSL=${ENABLE_SSL:-false} ENABLE_BIND_LOCAL_IP=${ENABLE_BIND_LOCAL_IP:-false} +echo "ENABLE_SSL is set to $ENABLE_SSL" +echo "ENABLE_BIND_LOCAL_IP is set to $ENABLE_BIND_LOCAL_IP" + DB_ADDR=:: DB_ADDRESSES=:: if [[ $ENABLE_BIND_LOCAL_IP == "true" ]]; then @@ -49,11 +52,9 @@ if [[ $ENABLE_BIND_LOCAL_IP == "true" ]]; then fi SSL_OPTIONS= -function ssl_options() { - if "$ENABLE_SSL" != "false" ]; then - SSL_OPTIONS="-p /var/run/tls/key -c /var/run/tls/cert -C /var/run/tls/cacert" - fi -} +if [ "$ENABLE_SSL" != "false" ]; then + SSL_OPTIONS="-p /var/run/tls/key -c /var/run/tls/cert -C /var/run/tls/cacert" +fi . /usr/share/openvswitch/scripts/ovs-lib || exit 1 @@ -139,6 +140,7 @@ function is_clustered { function set_nb_version_compatibility() { if [ -n "$OVN_VERSION_COMPATIBILITY" ]; then if ! ovn-nbctl --db=$(gen_conn_str 6641) $SSL_OPTIONS get NB_Global . options | grep -q version_compatibility=; then + echo "setting ovn NB_Global option version_compatibility to ${OVN_VERSION_COMPATIBILITY}" ovn-nbctl --db=$(gen_conn_str 6641) $SSL_OPTIONS set NB_Global . options:version_compatibility=${OVN_VERSION_COMPATIBILITY} return fi diff --git a/dist/images/start-ovs.sh b/dist/images/start-ovs.sh index f802eb2431f8..2fd8eddf3bf2 100755 --- a/dist/images/start-ovs.sh +++ b/dist/images/start-ovs.sh @@ -16,11 +16,11 @@ echo "OVN_REMOTE_PROBE_INTERVAL is set to $OVN_REMOTE_PROBE_INTERVAL" echo "OVN_REMOTE_OPENFLOW_INTERVAL is set to $OVN_REMOTE_OPENFLOW_INTERVAL" # Check required kernel module -modinfo openvswitch -modinfo geneve +modinfo -m openvswitch +modinfo -m geneve # CentOS 8 might not load iptables module by default, which will hurt nat function -if modinfo ip_tables; then +if modinfo -m ip_tables; then modprobe ip_tables fi diff --git a/dist/images/upgrade-ovs.sh b/dist/images/upgrade-ovs.sh index 33232bc755cc..cfde7f7e6f5e 100755 --- a/dist/images/upgrade-ovs.sh +++ b/dist/images/upgrade-ovs.sh @@ -10,11 +10,9 @@ OVN_VERSION_COMPATIBILITY=${OVN_VERSION_COMPATIBILITY:-} UPDATE_STRATEGY=`kubectl -n kube-system get ds ovs-ovn -o jsonpath='{.spec.updateStrategy.type}'` SSL_OPTIONS= -function ssl_options() { - if "$ENABLE_SSL" != "false" ]; then - SSL_OPTIONS="-p /var/run/tls/key -c /var/run/tls/cert -C /var/run/tls/cacert" - fi -} +if [ "$ENABLE_SSL" != "false" ]; then + SSL_OPTIONS="-p /var/run/tls/key -c /var/run/tls/cert -C /var/run/tls/cacert" +fi function gen_conn_str { if [[ -z "${OVN_DB_IPS}" ]]; then @@ -38,7 +36,7 @@ nb_addr="$(gen_conn_str 6641)" while true; do if [ x`ovn-nbctl --db=$nb_addr $SSL_OPTIONS get NB_Global . options | grep -o 'version_compatibility='` != "x" ]; then value=`ovn-nbctl --db=$nb_addr $SSL_OPTIONS get NB_Global . options:version_compatibility | sed -e 's/^"//' -e 's/"$//'` - echo "ovn NB_Global option version_compatibility is set to $value" + echo "ovn NB_Global option version_compatibility is already set to $value" if [ "$value" = "$OVN_VERSION_COMPATIBILITY" -o "$value" = "_$OVN_VERSION_COMPATIBILITY" ]; then break fi diff --git a/go.mod b/go.mod index 2685c9d81ced..039af8274e37 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,13 @@ go 1.22.5 require ( github.com/Microsoft/go-winio v0.6.2 - github.com/Microsoft/hcsshim v0.12.4 + github.com/Microsoft/hcsshim v0.12.5 github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e github.com/cenkalti/backoff/v4 v4.3.0 github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 - github.com/containernetworking/cni v1.2.2 + github.com/containernetworking/cni v1.2.3 github.com/containernetworking/plugins v1.5.1 - github.com/docker/docker v27.0.3+incompatible + github.com/docker/docker v27.1.0+incompatible github.com/emicklei/go-restful/v3 v3.12.1 github.com/evanphx/json-patch/v5 v5.9.0 github.com/go-logr/stdr v1.2.2 @@ -22,7 +22,7 @@ require ( github.com/kubeovn/gonetworkmanager/v2 v2.0.0-20230905082151-e28c4d73a589 github.com/kubeovn/ovsdb v0.0.0-20240410091831-5dd26006c475 github.com/mdlayher/arp v0.0.0-20220512170110-6706a2966875 - github.com/moby/sys/mountinfo v0.7.1 + github.com/moby/sys/mountinfo v0.7.2 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 github.com/osrg/gobgp/v3 v3.28.0 @@ -34,7 +34,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 - github.com/vishvananda/netlink v1.2.1-beta.2.0.20240524165444-4d4ba1473f21 + github.com/vishvananda/netlink v1.2.1-beta.2.0.20240713210050-d13535d71ed3 go.uber.org/mock v0.4.0 golang.org/x/mod v0.19.0 golang.org/x/sys v0.22.0 @@ -42,18 +42,19 @@ require ( google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 gopkg.in/k8snetworkplumbingwg/multus-cni.v4 v4.0.2 - k8s.io/api v0.30.2 - k8s.io/apimachinery v0.30.2 + k8s.io/api v0.30.3 + k8s.io/apimachinery v0.30.3 + k8s.io/apiserver v0.30.3 k8s.io/client-go v12.0.0+incompatible k8s.io/klog/v2 v2.130.1 - k8s.io/kubectl v0.30.2 - k8s.io/kubernetes v1.30.2 - k8s.io/pod-security-admission v0.30.2 - k8s.io/sample-controller v0.30.2 - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 - kubevirt.io/api v1.2.0 - kubevirt.io/client-go v1.2.0 + k8s.io/kubectl v0.30.3 + k8s.io/kubernetes v1.30.3 + k8s.io/pod-security-admission v0.30.3 + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 + kubevirt.io/api v1.3.0 + kubevirt.io/client-go v1.3.0 sigs.k8s.io/controller-runtime v0.18.4 + sigs.k8s.io/network-policy-api v0.1.5 ) require ( @@ -206,9 +207,9 @@ require ( go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect go.etcd.io/etcd/client/v3 v3.5.14 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.52.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.53.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect @@ -220,18 +221,18 @@ require ( go.starlark.net v0.0.0-20231121155337-90ade8b19d09 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/term v0.21.0 // indirect + golang.org/x/term v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/tools v0.23.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/api v0.186.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect gopkg.in/evanphx/json-patch.v5 v5.9.0 // indirect gopkg.in/gcfg.v1 v1.2.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -240,21 +241,20 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.30.2 // indirect - k8s.io/apiserver v0.30.2 // indirect - k8s.io/cli-runtime v0.30.2 // indirect - k8s.io/cloud-provider v0.30.2 // indirect - k8s.io/cluster-bootstrap v0.30.2 // indirect - k8s.io/component-base v0.30.2 // indirect - k8s.io/component-helpers v0.30.2 // indirect - k8s.io/controller-manager v0.30.2 // indirect - k8s.io/cri-api v0.30.2 // indirect - k8s.io/csi-translation-lib v0.30.2 // indirect + k8s.io/apiextensions-apiserver v0.30.3 // indirect + k8s.io/cli-runtime v0.30.3 // indirect + k8s.io/cloud-provider v0.30.3 // indirect + k8s.io/cluster-bootstrap v0.30.3 // indirect + k8s.io/component-base v0.30.3 // indirect + k8s.io/component-helpers v0.30.3 // indirect + k8s.io/controller-manager v0.30.3 // indirect + k8s.io/cri-api v0.30.3 // indirect + k8s.io/csi-translation-lib v0.30.3 // indirect k8s.io/dynamic-resource-allocation v0.0.0 // indirect - k8s.io/kms v0.30.2 // indirect - k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect + k8s.io/kms v0.30.3 // indirect + k8s.io/kube-openapi v0.30.0 // indirect k8s.io/kube-scheduler v0.0.0 // indirect - k8s.io/kubelet v0.30.2 // indirect + k8s.io/kubelet v0.30.3 // indirect k8s.io/legacy-cloud-providers v0.0.0 // indirect k8s.io/mount-utils v0.0.0 // indirect kubevirt.io/containerized-data-importer-api v1.58.1 // indirect @@ -271,32 +271,33 @@ replace ( github.com/mdlayher/arp => github.com/kubeovn/arp v0.0.0-20240218024213-d9612a263f68 github.com/openshift/client-go => github.com/openshift/client-go v0.0.1 github.com/ovn-org/libovsdb => github.com/kubeovn/libovsdb v0.0.0-20240218023647-f0bc3ce57fcd - k8s.io/api => k8s.io/api v0.30.2 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.30.2 - k8s.io/apimachinery => k8s.io/apimachinery v0.30.2 - k8s.io/apiserver => k8s.io/apiserver v0.30.2 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.30.2 - k8s.io/client-go => k8s.io/client-go v0.30.2 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.30.2 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.30.2 - k8s.io/code-generator => k8s.io/code-generator v0.30.2 - k8s.io/component-base => k8s.io/component-base v0.30.2 - k8s.io/component-helpers => k8s.io/component-helpers v0.30.2 - k8s.io/controller-manager => k8s.io/controller-manager v0.30.2 - k8s.io/cri-api => k8s.io/cri-api v0.30.2 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.30.2 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.30.2 - k8s.io/endpointslice => k8s.io/endpointslice v0.30.2 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.30.2 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.30.2 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.30.2 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.30.2 - k8s.io/kubectl => k8s.io/kubectl v0.30.2 - k8s.io/kubelet => k8s.io/kubelet v0.30.2 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.30.2 - k8s.io/metrics => k8s.io/metrics v0.30.2 - k8s.io/mount-utils => k8s.io/mount-utils v0.30.2 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.30.2 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.30.2 - kubevirt.io/client-go => github.com/kubeovn/kubevirt-client-go v0.0.0-20240430072310-d367a71d7cd7 + k8s.io/api => k8s.io/api v0.30.3 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.30.3 + k8s.io/apimachinery => k8s.io/apimachinery v0.30.3 + k8s.io/apiserver => k8s.io/apiserver v0.30.3 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.30.3 + k8s.io/client-go => k8s.io/client-go v0.30.3 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.30.3 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.30.3 + k8s.io/code-generator => k8s.io/code-generator v0.30.3 + k8s.io/component-base => k8s.io/component-base v0.30.3 + k8s.io/component-helpers => k8s.io/component-helpers v0.30.3 + k8s.io/controller-manager => k8s.io/controller-manager v0.30.3 + k8s.io/cri-api => k8s.io/cri-api v0.30.3 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.30.3 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.30.3 + k8s.io/endpointslice => k8s.io/endpointslice v0.30.3 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.30.3 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.30.3 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f + k8s.io/kube-proxy => k8s.io/kube-proxy v0.30.3 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.30.3 + k8s.io/kubectl => k8s.io/kubectl v0.30.3 + k8s.io/kubelet => k8s.io/kubelet v0.30.3 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.30.3 + k8s.io/metrics => k8s.io/metrics v0.30.3 + k8s.io/mount-utils => k8s.io/mount-utils v0.30.3 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.30.3 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.30.3 + kubevirt.io/client-go => github.com/kubeovn/kubevirt-client-go v0.0.0-20240719051923-4613ee8d79ec ) diff --git a/go.sum b/go.sum index e6a88d6c80c8..2e70acf6c1fc 100644 --- a/go.sum +++ b/go.sum @@ -616,8 +616,8 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= 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.12.4 h1:Ev7YUMHAHoWNm+aDSPzc5W9s6E2jyL1szpVDJeZ/Rr4= -github.com/Microsoft/hcsshim v0.12.4/go.mod h1:Iyl1WVpZzr+UkzjekHZbV8o5Z9ZkxNGx6CtY2Qg/JVQ= +github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0= +github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= @@ -671,9 +671,15 @@ github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNS 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= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= +github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4= github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -708,8 +714,8 @@ github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oL github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY= github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= -github.com/containernetworking/cni v1.2.2 h1:9IbP6KJQQxVKo4hhnm8r50YcVKrJbJu3Dqw+Rbt1vYk= -github.com/containernetworking/cni v1.2.2/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M= +github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM= +github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M= github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ= github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= @@ -730,8 +736,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= 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 v27.0.3+incompatible h1:aBGI9TeQ4MPlhquTQKq9XbK79rKFVwXNUAYz9aXyEBE= -github.com/docker/docker v27.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.1.0+incompatible h1:rEHVQc4GZ0MIQKifQPHSFGV/dVgaZafgRf8fCPtDYBs= +github.com/docker/docker v27.1.0+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= @@ -747,7 +753,6 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M= github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.15.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -792,7 +797,6 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= @@ -831,11 +835,9 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre 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-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= @@ -855,6 +857,9 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -959,6 +964,7 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0 h1:e+8XbKB6IMn8A4OAyZccO4pYfB3s7bt6azNIPE7AnPg= github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -996,13 +1002,11 @@ github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2e github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= @@ -1030,6 +1034,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= @@ -1042,7 +1047,6 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 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= @@ -1091,14 +1095,15 @@ github.com/kubeovn/go-iptables v0.0.0-20230322103850-8619a8ab3dca h1:fTMjoho2et9 github.com/kubeovn/go-iptables v0.0.0-20230322103850-8619a8ab3dca/go.mod h1:jY1XeGzkx8ASNJ+SqQSxTESNXARkjvt+I6IJOTnzIjw= github.com/kubeovn/gonetworkmanager/v2 v2.0.0-20230905082151-e28c4d73a589 h1:y9exo1hjCsq7jsGUzt11kxhTiEGrGSQ0ZqibAiZk2PQ= github.com/kubeovn/gonetworkmanager/v2 v2.0.0-20230905082151-e28c4d73a589/go.mod h1:49upX+/hUyppWIqu58cumojyIwXdkA8k6reA/mQlKuI= -github.com/kubeovn/kubevirt-client-go v0.0.0-20240430072310-d367a71d7cd7 h1:1wXNpLgiQNcxjgKYGjwaZMid/veHyWikHe43+n6t5RI= -github.com/kubeovn/kubevirt-client-go v0.0.0-20240430072310-d367a71d7cd7/go.mod h1:tZBpCFmVsbw2W/Q1kkQ7T9dllhsID5JCWuQJoqYx6iM= +github.com/kubeovn/kubevirt-client-go v0.0.0-20240719051923-4613ee8d79ec h1:oYLM++miLoT1lLRV+KVmCi3NqSzBihBKIORNT6fYyKo= +github.com/kubeovn/kubevirt-client-go v0.0.0-20240719051923-4613ee8d79ec/go.mod h1:7bSgPDhnVXzMiSrSEagZnxKdMn3YxdIU8mvlj8wICtQ= github.com/kubeovn/libovsdb v0.0.0-20240218023647-f0bc3ce57fcd h1:GhgvSBFKEkVNgDq8IslC04NVuoznreZH/Imz/cr6bhs= github.com/kubeovn/libovsdb v0.0.0-20240218023647-f0bc3ce57fcd/go.mod h1:pTnlGt1JZrncr6pJn/Fhnp3FFTMQRaTVxiSKBLVGa5s= github.com/kubeovn/ovsdb v0.0.0-20240410091831-5dd26006c475 h1:KZba2Kj9TXCUdUSqOR3eiy4VvkkIyhDVImYmYs6GQWU= github.com/kubeovn/ovsdb v0.0.0-20240410091831-5dd26006c475/go.mod h1:LAd0qoeAAm/QyZcpxN2BnpndM2/dhZt+/kokPvcxKcE= github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0 h1:nHHjmvjitIiyPlUHk/ofpgvBcNcawJLtf4PYHORLjAA= github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0/go.mod h1:YBCo4DoEeDndqvAn6eeu0vWM7QdXmHEeI9cFWplmBys= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/libopenstorage/openstorage v1.0.0 h1:GLPam7/0mpdP8ZZtKjbfcXJBTIA/T1O6CBErVEFEyIM= github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= @@ -1132,21 +1137,19 @@ github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1 github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/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.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= -github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= +github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= 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/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 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-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -1168,7 +1171,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= @@ -1192,9 +1194,10 @@ github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7 github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -1216,6 +1219,7 @@ github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3ev github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -1235,6 +1239,7 @@ github.com/openshift/client-go v0.0.1/go.mod h1:I8qTI1lgErsWc6CVukSjP1PYqpafE7fu github.com/openshift/custom-resource-status v1.1.2 h1:C3DL44LEbvlbItfd8mT5jWrqPfHnSOQoQf/sypqA6A4= github.com/openshift/custom-resource-status v1.1.2/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= github.com/osrg/gobgp/v3 v3.28.0 h1:Oy96v6TUiCxMq32b2cmfcREhPFwBoNK+JtBKwjhGQgw= github.com/osrg/gobgp/v3 v3.28.0/go.mod h1:ZGeSti9mURR/o5hf5R6T1FM5g1yiEBZbhP+TuqYJUpI= github.com/parnurzeal/gorequest v0.3.0 h1:SoFyqCDC9COr1xuS6VA8fC8RU7XyrJZN2ona1kEX7FI= @@ -1313,7 +1318,6 @@ github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE 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.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= @@ -1327,7 +1331,6 @@ 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= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -1354,9 +1357,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtse github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= 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/vishvananda/netlink v1.2.1-beta.2.0.20240524165444-4d4ba1473f21 h1:tcHUxOT8j/R+0S+A1j8D2InqguXFNxAiij+8QFOlX7Y= -github.com/vishvananda/netlink v1.2.1-beta.2.0.20240524165444-4d4ba1473f21/go.mod h1:whJevzBpTrid75eZy99s3DqCmy05NfibNaF2Ol5Ox5A= -github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netlink v1.2.1-beta.2.0.20240713210050-d13535d71ed3 h1:z77sOcayXxSukV2QIDn5pg7kYx9V5rGoYZLr4syF5kk= +github.com/vishvananda/netlink v1.2.1-beta.2.0.20240713210050-d13535d71ed3/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= @@ -1398,14 +1400,14 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 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.52.0 h1:Lg4/aNChh+6whhYldqPpYcdng/jeLyQZn8cqWT2Q+Ts= -go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.52.0/go.mod h1:IcSJTrfVeG9nWXqZdQRL1J1SdgS+PM2qf83+CQEvJkM= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= -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.27.0 h1:IjgxbomVrV9za6bRi8fWCNXENs0co37SZedQilP2hm0= -go.opentelemetry.io/contrib/propagators/b3 v1.27.0/go.mod h1:Dv9obQz25lCisDvvs4dy28UPh974CxkahRDUPsY7y9E= +go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.53.0 h1:wwtQnRJbaVShQGjKomYYjvNoAvgXftwMIPxfY0LwWKY= +go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.53.0/go.mod h1:OgGTh4n1VkuEmwUC+4jkHDakfhhDYUgH1RlAROSHx9Q= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/contrib/propagators/b3 v1.28.0 h1:XR6CFQrQ/ttAYmTBX2loUEFGdk1h17pxYI8828dk/1Y= +go.opentelemetry.io/contrib/propagators/b3 v1.28.0/go.mod h1:DWRkzJONLquRz7OJPh2rRbZ7MugQj62rk7g6HRnEqh0= 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.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= @@ -1457,10 +1459,12 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -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/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1476,8 +1480,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 h1:wDLEX9a7YQoKdKNQt88rtydkqDxeGaBUTnIYc3iG/mA= +golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1527,6 +1531,7 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1542,7 +1547,6 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR 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= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1601,10 +1605,12 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -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/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= 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= @@ -1683,7 +1689,6 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w 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= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1731,6 +1736,7 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1761,11 +1767,14 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1781,10 +1790,12 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -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/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= 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= @@ -1892,9 +1903,11 @@ golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= 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= @@ -2126,15 +2139,15 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go. google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -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/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -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/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/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= @@ -2226,7 +2239,6 @@ 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= @@ -2249,36 +2261,35 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt 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= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.30.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI= -k8s.io/api v0.30.2/go.mod h1:ULg5g9JvOev2dG0u2hig4Z7tQ2hHIuS+m8MNZ+X6EmI= -k8s.io/apiextensions-apiserver v0.30.2 h1:l7Eue2t6QiLHErfn2vwK4KgF4NeDgjQkCXtEbOocKIE= -k8s.io/apiextensions-apiserver v0.30.2/go.mod h1:lsJFLYyK40iguuinsb3nt+Sj6CmodSI4ACDLep1rgjw= -k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg= -k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/apiserver v0.30.2 h1:ACouHiYl1yFI2VFI3YGM+lvxgy6ir4yK2oLOsLI1/tw= -k8s.io/apiserver v0.30.2/go.mod h1:BOTdFBIch9Sv0ypSEcUR6ew/NUFGocRFNl72Ra7wTm8= -k8s.io/cli-runtime v0.30.2 h1:ooM40eEJusbgHNEqnHziN9ZpLN5U4WcQGsdLKVxpkKE= -k8s.io/cli-runtime v0.30.2/go.mod h1:Y4g/2XezFyTATQUbvV5WaChoUGhojv/jZAtdp5Zkm0A= -k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50= -k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs= -k8s.io/cloud-provider v0.30.2 h1:yov6r02v7sMUNNvzEz51LtL2krn2c1wsC+dy/8BxKQI= -k8s.io/cloud-provider v0.30.2/go.mod h1:w69t2dSjDtI9BYK6SEqj6HmMKIojEk08fXRoUzjFN2I= -k8s.io/cluster-bootstrap v0.30.2 h1:9PQ5phjWTxmPFKPEzTG6QJzPaUIfuW2RqcHDME5gqPg= -k8s.io/cluster-bootstrap v0.30.2/go.mod h1:dvzAgNVmwRfZ0BzHI/WTvzqlzmNH7w21mdnahEq61KY= -k8s.io/code-generator v0.30.2/go.mod h1:RQP5L67QxqgkVquk704CyvWFIq0e6RCMmLTXxjE8dVA= -k8s.io/component-base v0.30.2 h1:pqGBczYoW1sno8q9ObExUqrYSKhtE5rW3y6gX88GZII= -k8s.io/component-base v0.30.2/go.mod h1:yQLkQDrkK8J6NtP+MGJOws+/PPeEXNpwFixsUI7h/OE= -k8s.io/component-helpers v0.30.2 h1:kDMYLiWEYeWU7H6jBI+Ua1i2hqNh0DzqDHNIppFC3po= -k8s.io/component-helpers v0.30.2/go.mod h1:tI0anfS6AbRqooaICkGg7UVAQLedOauVSQW9srDBnJw= -k8s.io/controller-manager v0.30.2 h1:tC7V7IdGUW2I4de3bXx4m2fS3naP7VlCYlECCajK9fU= -k8s.io/controller-manager v0.30.2/go.mod h1:CYltIHGhCgldEkXT5vS2JHCCWM1WyBI4kA2UfP9cZvY= -k8s.io/cri-api v0.30.2 h1:4KR5W6ziqfGzKYVmFG9AEOJzxNbCPyZMoeCeIlK9jew= -k8s.io/cri-api v0.30.2/go.mod h1://4/umPJSW1ISNSNng4OwjpkvswJOQwU8rnkvO8P+xg= -k8s.io/csi-translation-lib v0.30.2 h1:ZcFVMWDHg7feW3mtdl+xClgmw1Yxv7m9ysOKt8h3K8Y= -k8s.io/csi-translation-lib v0.30.2/go.mod h1:jFT8vquP6eSDUwDHk0mKT6uKFWlZp60ecUEUhmlGsOY= -k8s.io/dynamic-resource-allocation v0.30.2 h1:wEhjNbVPymPEY5Db4UXPiQkioHV/4MHDzAkf+1TLaNM= -k8s.io/dynamic-resource-allocation v0.30.2/go.mod h1:J5gKMh7FcGcWziX6ugeNfyFM8j1mvxBgYWrLfRDZ38k= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ= +k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04= +k8s.io/apiextensions-apiserver v0.30.3 h1:oChu5li2vsZHx2IvnGP3ah8Nj3KyqG3kRSaKmijhB9U= +k8s.io/apiextensions-apiserver v0.30.3/go.mod h1:uhXxYDkMAvl6CJw4lrDN4CPbONkF3+XL9cacCT44kV4= +k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc= +k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/apiserver v0.30.3 h1:QZJndA9k2MjFqpnyYv/PH+9PE0SHhx3hBho4X0vE65g= +k8s.io/apiserver v0.30.3/go.mod h1:6Oa88y1CZqnzetd2JdepO0UXzQX4ZnOekx2/PtEjrOg= +k8s.io/cli-runtime v0.30.3 h1:aG69oRzJuP2Q4o8dm+f5WJIX4ZBEwrvdID0+MXyUY6k= +k8s.io/cli-runtime v0.30.3/go.mod h1:hwrrRdd9P84CXSKzhHxrOivAR9BRnkMt0OeP5mj7X30= +k8s.io/client-go v0.30.3 h1:bHrJu3xQZNXIi8/MoxYtZBBWQQXwy16zqJwloXXfD3k= +k8s.io/client-go v0.30.3/go.mod h1:8d4pf8vYu665/kUbsxWAQ/JDBNWqfFeZnvFiVdmx89U= +k8s.io/cloud-provider v0.30.3 h1:SNWZmllTymOTzIPJuhtZH6il/qVi75dQARRQAm9k6VY= +k8s.io/cloud-provider v0.30.3/go.mod h1:Ax0AVdHnM7tMYnJH1Ycy4SMBD98+4zA+tboUR9eYsY8= +k8s.io/cluster-bootstrap v0.30.3 h1:MgxyxMkpaC6mu0BKWJ8985XCOnKU+eH3Iy+biwtDXRk= +k8s.io/cluster-bootstrap v0.30.3/go.mod h1:h8BoLDfdD7XEEIXy7Bx9FcMzxHwz29jsYYi34bM5DKU= +k8s.io/code-generator v0.30.3/go.mod h1:PFgBiv+miFV7TZYp+RXgROkhA+sWYZ+mtpbMLofMke8= +k8s.io/component-base v0.30.3 h1:Ci0UqKWf4oiwy8hr1+E3dsnliKnkMLZMVbWzeorlk7s= +k8s.io/component-base v0.30.3/go.mod h1:C1SshT3rGPCuNtBs14RmVD2xW0EhRSeLvBh7AGk1quA= +k8s.io/component-helpers v0.30.3 h1:KPc8l0eGx9Wg2OcKc58k9ozNcVcOInAi3NGiuS2xJ/c= +k8s.io/component-helpers v0.30.3/go.mod h1:VOQ7g3q+YbKWwKeACG2BwPv4ftaN8jXYJ5U3xpzuYAE= +k8s.io/controller-manager v0.30.3 h1:QRFGkWWD5gi/KCSU0qxyUoZRbt+BKgiCUXiTD1RO95w= +k8s.io/controller-manager v0.30.3/go.mod h1:F95rjHCOH2WwV9XlVxRo71CtddKLhF3FzE+s1lc7E/0= +k8s.io/cri-api v0.30.3 h1:o7AAGb3645Ik44WkHI0eqUc7JbQVmstlINLlLAtU/rI= +k8s.io/cri-api v0.30.3/go.mod h1://4/umPJSW1ISNSNng4OwjpkvswJOQwU8rnkvO8P+xg= +k8s.io/csi-translation-lib v0.30.3 h1:wBaPWnOi14/vANRIrp8pmbdx/Pgz2QRcroH7wkodezc= +k8s.io/csi-translation-lib v0.30.3/go.mod h1:3AizNZbDttVDH1RO0x1yGEQP74e9Xbfb60IBP1oWO1o= +k8s.io/dynamic-resource-allocation v0.30.3 h1:49aLgEhknKF8gPVhsquJ3ylOnfC8ddxnqVP6y3T+hkM= +k8s.io/dynamic-resource-allocation v0.30.3/go.mod h1:Dj7OzA3pYT/OfN9PvuYt9CH5e5KcjKBRAik8XeG0nB8= k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= @@ -2288,40 +2299,35 @@ k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kms v0.30.2 h1:VSZILO/tkzrz5Tu2j+yFQZ2Dc5JerQZX2GqhFJbQrfw= -k8s.io/kms v0.30.2/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4= -k8s.io/kube-aggregator v0.30.2 h1:0+yk/ED6foCprY8VmkDPUhngjaAPKsNTXB/UrtvbIz0= -k8s.io/kube-aggregator v0.30.2/go.mod h1:EhqCfDdxysNWXk1wRL9SEHAdo1DKl6EULQagztkBcXE= -k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kms v0.30.3 h1:NLg+oN45S2Y3U0WiLRzbS61AY/XrS5JBMZp531Z+Pho= +k8s.io/kms v0.30.3/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4= +k8s.io/kube-aggregator v0.30.3 h1:hy5zfQ7p6BuJgc/XtGp3GBh2MPfOj6b1n3raKKMHOQE= +k8s.io/kube-aggregator v0.30.3/go.mod h1:2SP0IckvQoOwwZN8lmtWUnTZTgIpwOWvidWtxyqLwuk= k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f h1:0LQagt0gDpKqvIkAMPaRGcXawNMouPECM1+F9BVxEaM= k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f/go.mod h1:S9tOR0FxgyusSNR+MboCuiDpVWkAifZvaYI1Q2ubgro= -k8s.io/kube-scheduler v0.30.2 h1:2uR6qVkAV4ySzAQws5XDTWu62mRCxwm2m9oS0EIhAQI= -k8s.io/kube-scheduler v0.30.2/go.mod h1:ft17TR1cD7ZgLC5m3xkpvU4wK2X5ccbsg/b+a3HdR2Y= -k8s.io/kubectl v0.30.2 h1:cgKNIvsOiufgcs4yjvgkK0+aPCfa8pUwzXdJtkbhsH8= -k8s.io/kubectl v0.30.2/go.mod h1:rz7GHXaxwnigrqob0lJsiA07Df8RE3n1TSaC2CTeuB4= -k8s.io/kubelet v0.30.2 h1:Ck4E/pHndI20IzDXxS57dElhDGASPO5pzXF7BcKfmCY= -k8s.io/kubelet v0.30.2/go.mod h1:DSwwTbLQmdNkebAU7ypIALR4P9aXZNFwgRmedojUE94= -k8s.io/kubernetes v1.30.2 h1:11WhS78OYX/lnSy6TXxPO6Hk+E5K9ZNrEsk9JgMSX8I= -k8s.io/kubernetes v1.30.2/go.mod h1:yPbIk3MhmhGigX62FLJm+CphNtjxqCvAIFQXup6RKS0= -k8s.io/legacy-cloud-providers v0.30.2 h1:RfMtmbAPvTn7+nkHRWXpGeaif4x7VBOU2SAZ2BdFEdI= -k8s.io/legacy-cloud-providers v0.30.2/go.mod h1:Y3vTBCDw/A42HIwMBoVMpLv3hP5WewjUj8F6zYrO0Ug= -k8s.io/metrics v0.30.2 h1:zj4kIPTCfEbY0RHEogpA7QtlItU7xaO11+Gz1zVDxlc= -k8s.io/metrics v0.30.2/go.mod h1:GpoO5XTy/g8CclVLtgA5WTrr2Cy5vCsqr5Xa/0ETWIk= -k8s.io/mount-utils v0.30.2 h1:2KDVY9hXyDyRw9EO4lmox4+Nn5atVOq+4ffZ/br2aAU= -k8s.io/mount-utils v0.30.2/go.mod h1:9sCVmwGLcV1MPvbZ+rToMDnl1QcGozy+jBPd0MsQLIo= -k8s.io/pod-security-admission v0.30.2 h1:UlHnkvvOr+rgQplOqD+SHzLUF8EgKIOCpDU8kaMeTQQ= -k8s.io/pod-security-admission v0.30.2/go.mod h1:gMUJUG9zOgNBk0VIz5BS7uIYiYPEoXkBSeHh6rG2m8c= -k8s.io/sample-apiserver v0.30.2 h1:bnkF2ER7MQ6mazUmNSi5niRFKooL3uU6e1RhIgZMres= -k8s.io/sample-apiserver v0.30.2/go.mod h1:hLVmvDbhVqtS9goL3PbPfvPw+vIygKl7z9njDWbMt90= -k8s.io/sample-controller v0.30.2 h1:J8Xvli+YHS6C7sWFzn00N2CAtkvLOguXj+Iq4S3oMwA= -k8s.io/sample-controller v0.30.2/go.mod h1:Btgcc0ZQfurowzwy4e7v3wx4hE1AADwzhZ+apsJ4J8Y= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/kube-scheduler v0.30.3 h1:Fn2sX+tOvOMkRG6W2kntNAQStIZlr3/X6DfpMcy/rik= +k8s.io/kube-scheduler v0.30.3/go.mod h1:wzEWmB9+4/e+x96n1d1BHuETHHrOxb22ESAtVS/fJts= +k8s.io/kubectl v0.30.3 h1:YIBBvMdTW0xcDpmrOBzcpUVsn+zOgjMYIu7kAq+yqiI= +k8s.io/kubectl v0.30.3/go.mod h1:IcR0I9RN2+zzTRUa1BzZCm4oM0NLOawE6RzlDvd1Fpo= +k8s.io/kubelet v0.30.3 h1:KvGWDdhzD0vEyDyGTCjsDc8D+0+lwRMw3fJbfQgF7ys= +k8s.io/kubelet v0.30.3/go.mod h1:D9or45Vkzcqg55CEiqZ8dVbwP3Ksj7DruEVRS9oq3Ys= +k8s.io/kubernetes v1.30.3 h1:A0qoXI1YQNzrQZiff33y5zWxYHFT/HeZRK98/sRDJI0= +k8s.io/kubernetes v1.30.3/go.mod h1:yPbIk3MhmhGigX62FLJm+CphNtjxqCvAIFQXup6RKS0= +k8s.io/legacy-cloud-providers v0.30.3 h1:6C50kKmsdKNTsQqfy8V6MTbQKlEkR1oJoeh+WrilM4w= +k8s.io/legacy-cloud-providers v0.30.3/go.mod h1:VATC0a8MFqrTeVBCSYnMPhMP83bZA7vaMbE7eA8xSa8= +k8s.io/metrics v0.30.3 h1:gKCpte5zykrOmQhZ8qmsxyJslMdiLN+sqbBfIWNpbGM= +k8s.io/metrics v0.30.3/go.mod h1:W06L2nXRhOwPkFYDJYWdEIS3u6JcJy3ebIPYbndRs6A= +k8s.io/mount-utils v0.30.3 h1:8Z3wSW5+GSvGNtlDhtoZrBCKLMIf5z/9tf8pie+G06s= +k8s.io/mount-utils v0.30.3/go.mod h1:9sCVmwGLcV1MPvbZ+rToMDnl1QcGozy+jBPd0MsQLIo= +k8s.io/pod-security-admission v0.30.3 h1:UDGZWR3ry/XrN/Ki/w7qrp49OwgQsKyh+6xWbexvJi8= +k8s.io/pod-security-admission v0.30.3/go.mod h1:T1EQSOLl9YyDMnXNJfsq2jeci6uoymY0mrRkkKihd98= +k8s.io/sample-apiserver v0.30.3 h1:SGlc1FvY+5CGolD0Qn1iGuhbhBWMUru/kcjQ9ki2iEs= +k8s.io/sample-apiserver v0.30.3/go.mod h1:P4g1Jw2lq2wtCiibqVX3KIRAfXtHpw6pOD/dzwmVG/w= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -kubevirt.io/api v1.2.0 h1:1f8XQLPl4BuHPsc6SHTPnYSYeDxucKCQGa8CdrGJSRc= -kubevirt.io/api v1.2.0/go.mod h1:SbeR9ma4EwnaOZEUkh/lNz0kzYm5LPpEDE30vKXC5Zg= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +kubevirt.io/api v1.3.0 h1:9sGElMmnRU50pGED+MPPD2OwQl4S5lvjCUjm+t0mI90= +kubevirt.io/api v1.3.0/go.mod h1:e6LkElYZZm8NcP2gKlFVHZS9pgNhIARHIjSBSfeiP1s= kubevirt.io/containerized-data-importer-api v1.58.1 h1:Zbf0pCvxb4fBvtMR6uI2OIJZ4UfwFxripzOLMO4HPbI= kubevirt.io/containerized-data-importer-api v1.58.1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= @@ -2374,7 +2380,8 @@ sigs.k8s.io/kustomize/api v0.16.0 h1:/zAR4FOQDCkgSDmVzV2uiFbuy9bhu3jEzthrHCuvm1g sigs.k8s.io/kustomize/api v0.16.0/go.mod h1:MnFZ7IP2YqVyVwMWoRxPtgl/5hpA+eCCrQR/866cm5c= sigs.k8s.io/kustomize/kyaml v0.16.0 h1:6J33uKSoATlKZH16unr2XOhDI+otoe2sR3M8PDzW3K0= sigs.k8s.io/kustomize/kyaml v0.16.0/go.mod h1:xOK/7i+vmE14N2FdFyugIshB8eF6ALpy7jI87Q2nRh4= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +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.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= diff --git a/hack/update-codegen-docker.sh b/hack/update-codegen-docker.sh index 016239a8ca99..7f139694c557 100755 --- a/hack/update-codegen-docker.sh +++ b/hack/update-codegen-docker.sh @@ -4,14 +4,12 @@ # set GOPROXY you like GOPROXY=${GOPROXY:-"https://goproxy.cn"} -PROJECT_PACKAGE=github.com/kubeovn/kube-ovn docker run -it --rm \ - -v ${PWD}:/go/src/${PROJECT_PACKAGE}\ - -v ${PWD}/hack/boilerplate.go.txt:/tmp/fake-boilerplate.txt \ - -e PROJECT_PACKAGE=${PROJECT_PACKAGE} \ - -e CLIENT_GENERATOR_OUT=${PROJECT_PACKAGE}/pkg/client \ - -e APIS_ROOT=${PROJECT_PACKAGE}/pkg/apis \ + -v ${PWD}:/app \ -e GOPROXY=${GOPROXY} \ - ghcr.io/zhangzujian/kube-code-generator:v1.29.3 + ghcr.io/zhangzujian/kube-code-generator:v0.2.1 \ + --boilerplate-path ./hack/boilerplate.go.txt \ + --apis-in ./pkg/apis \ + --go-gen-out ./pkg/client go mod tidy diff --git a/mocks/pkg/ovs/interface.go b/mocks/pkg/ovs/interface.go index 9d07d923c122..03a4d73c9e88 100644 --- a/mocks/pkg/ovs/interface.go +++ b/mocks/pkg/ovs/interface.go @@ -20,6 +20,7 @@ import ( ovsdb "github.com/ovn-org/libovsdb/ovsdb" gomock "go.uber.org/mock/gomock" v10 "k8s.io/api/networking/v1" + v1alpha1 "sigs.k8s.io/network-policy-api/apis/v1alpha1" ) // MockNBGlobal is a mock of NBGlobal interface. @@ -1001,6 +1002,20 @@ func (mr *MockLogicalSwitchPortMockRecorder) ResetLogicalSwitchPortMigrateOption return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetLogicalSwitchPortMigrateOptions", reflect.TypeOf((*MockLogicalSwitchPort)(nil).ResetLogicalSwitchPortMigrateOptions), lspName, srcNodeName, targetNodeName, migratedFail) } +// SetLogicalSwitchPortActivationStrategy mocks base method. +func (m *MockLogicalSwitchPort) SetLogicalSwitchPortActivationStrategy(lspName, chassis string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetLogicalSwitchPortActivationStrategy", lspName, chassis) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetLogicalSwitchPortActivationStrategy indicates an expected call of SetLogicalSwitchPortActivationStrategy. +func (mr *MockLogicalSwitchPortMockRecorder) SetLogicalSwitchPortActivationStrategy(lspName, chassis any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogicalSwitchPortActivationStrategy", reflect.TypeOf((*MockLogicalSwitchPort)(nil).SetLogicalSwitchPortActivationStrategy), lspName, chassis) +} + // SetLogicalSwitchPortArpProxy mocks base method. func (m *MockLogicalSwitchPort) SetLogicalSwitchPortArpProxy(lspName string, enableArpProxy bool) error { m.ctrl.T.Helper() @@ -1755,6 +1770,21 @@ func (mr *MockACLMockRecorder) SetLogicalSwitchPrivate(lsName, cidrBlock, nodeSw return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogicalSwitchPrivate", reflect.TypeOf((*MockACL)(nil).SetLogicalSwitchPrivate), lsName, cidrBlock, nodeSwitchCIDR, allowSubnets) } +// UpdateAnpRuleACLOps mocks base method. +func (m *MockACL) UpdateAnpRuleACLOps(pgName, asName, protocol string, priority int, aclAction ovnnb.ACLAction, rulePorts []v1alpha1.AdminNetworkPolicyPort, isIngress, isBanp bool) ([]ovsdb.Operation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateAnpRuleACLOps", pgName, asName, protocol, priority, aclAction, rulePorts, isIngress, isBanp) + ret0, _ := ret[0].([]ovsdb.Operation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateAnpRuleACLOps indicates an expected call of UpdateAnpRuleACLOps. +func (mr *MockACLMockRecorder) UpdateAnpRuleACLOps(pgName, asName, protocol, priority, aclAction, rulePorts, isIngress, isBanp any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAnpRuleACLOps", reflect.TypeOf((*MockACL)(nil).UpdateAnpRuleACLOps), pgName, asName, protocol, priority, aclAction, rulePorts, isIngress, isBanp) +} + // UpdateEgressACLOps mocks base method. func (m *MockACL) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol string, npp []v10.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { m.ctrl.T.Helper() @@ -4158,6 +4188,20 @@ func (mr *MockNbClientMockRecorder) SetLoadBalancerAffinityTimeout(lbName, timeo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLoadBalancerAffinityTimeout", reflect.TypeOf((*MockNbClient)(nil).SetLoadBalancerAffinityTimeout), lbName, timeout) } +// SetLogicalSwitchPortActivationStrategy mocks base method. +func (m *MockNbClient) SetLogicalSwitchPortActivationStrategy(lspName, chassis string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetLogicalSwitchPortActivationStrategy", lspName, chassis) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetLogicalSwitchPortActivationStrategy indicates an expected call of SetLogicalSwitchPortActivationStrategy. +func (mr *MockNbClientMockRecorder) SetLogicalSwitchPortActivationStrategy(lspName, chassis any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogicalSwitchPortActivationStrategy", reflect.TypeOf((*MockNbClient)(nil).SetLogicalSwitchPortActivationStrategy), lspName, chassis) +} + // SetLogicalSwitchPortArpProxy mocks base method. func (m *MockNbClient) SetLogicalSwitchPortArpProxy(lspName string, enableArpProxy bool) error { m.ctrl.T.Helper() @@ -4359,6 +4403,21 @@ func (mr *MockNbClientMockRecorder) Transact(method, operations any) *gomock.Cal return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transact", reflect.TypeOf((*MockNbClient)(nil).Transact), method, operations) } +// UpdateAnpRuleACLOps mocks base method. +func (m *MockNbClient) UpdateAnpRuleACLOps(pgName, asName, protocol string, priority int, aclAction ovnnb.ACLAction, rulePorts []v1alpha1.AdminNetworkPolicyPort, isIngress, isBanp bool) ([]ovsdb.Operation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateAnpRuleACLOps", pgName, asName, protocol, priority, aclAction, rulePorts, isIngress, isBanp) + ret0, _ := ret[0].([]ovsdb.Operation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateAnpRuleACLOps indicates an expected call of UpdateAnpRuleACLOps. +func (mr *MockNbClientMockRecorder) UpdateAnpRuleACLOps(pgName, asName, protocol, priority, aclAction, rulePorts, isIngress, isBanp any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAnpRuleACLOps", reflect.TypeOf((*MockNbClient)(nil).UpdateAnpRuleACLOps), pgName, asName, protocol, priority, aclAction, rulePorts, isIngress, isBanp) +} + // UpdateBFD mocks base method. func (m *MockNbClient) UpdateBFD(bfd *ovnnb.BFD, fields ...any) error { m.ctrl.T.Helper() diff --git a/pkg/controller/admin_network_policy.go b/pkg/controller/admin_network_policy.go new file mode 100644 index 000000000000..f8feb9682afa --- /dev/null +++ b/pkg/controller/admin_network_policy.go @@ -0,0 +1,1072 @@ +package controller + +import ( + "errors" + "fmt" + "reflect" + "strings" + "time" + "unicode" + + "github.com/scylladb/go-set/strset" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/tools/cache" + "k8s.io/klog/v2" + v1alpha1 "sigs.k8s.io/network-policy-api/apis/v1alpha1" + + kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" + "github.com/kubeovn/kube-ovn/pkg/ovs" + "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb" + "github.com/kubeovn/kube-ovn/pkg/util" +) + +type ChangedField string + +const ( + ChangedSubject ChangedField = "Subject" + ChangedIngressRule ChangedField = "IngressRule" + ChangedEgressRule ChangedField = "EgressRule" +) + +type ChangedName struct { + // the rule name can be omitted default, add isMatch to append check for rule update + isMatch bool + oldRuleName string + curRuleName string +} + +type ChangedDelta struct { + key string + ruleNames [util.AnpMaxRules]ChangedName + field ChangedField +} + +func (c *Controller) enqueueAddAnp(obj interface{}) { + var key string + var err error + if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { + utilruntime.HandleError(err) + return + } + klog.V(3).Infof("enqueue add anp %s", key) + c.addAnpQueue.Add(key) +} + +func (c *Controller) enqueueDeleteAnp(obj interface{}) { + var key string + var err error + if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { + utilruntime.HandleError(err) + return + } + klog.V(3).Infof("enqueue delete anp %s", key) + c.deleteAnpQueue.Add(obj) +} + +func (c *Controller) enqueueUpdateAnp(oldObj, newObj interface{}) { + oldAnpObj := oldObj.(*v1alpha1.AdminNetworkPolicy) + newAnpObj := newObj.(*v1alpha1.AdminNetworkPolicy) + + // All the acls should be recreated with the following situations + if oldAnpObj.Spec.Priority != newAnpObj.Spec.Priority || len(oldAnpObj.Spec.Ingress) != len(newAnpObj.Spec.Ingress) || len(oldAnpObj.Spec.Egress) != len(newAnpObj.Spec.Egress) { + c.addAnpQueue.Add(newAnpObj.Name) + return + } + + // Acls should be updated when action or ports of ingress/egress rule has been changed + for index, rule := range newAnpObj.Spec.Ingress { + oldRule := oldAnpObj.Spec.Ingress[index] + if oldRule.Action != rule.Action || !reflect.DeepEqual(oldRule.Ports, rule.Ports) { + // It's difficult to distinguish which rule has changed and update acls for that rule, so go through the anp add process to recreate acls. + // If we want to get fine-grained changes over rule, maybe it's a better way to add a new queue to process the change + c.addAnpQueue.Add(newAnpObj.Name) + return + } + } + + for index, rule := range newAnpObj.Spec.Egress { + oldRule := oldAnpObj.Spec.Egress[index] + if oldRule.Action != rule.Action || !reflect.DeepEqual(oldRule.Ports, rule.Ports) { + c.addAnpQueue.Add(newAnpObj.Name) + return + } + } + klog.V(3).Infof("enqueue update anp %s", newAnpObj.Name) + + // The remaining changes do not affect the acls. The port-group or address-set should be updated. + // The port-group for anp should be updated + if !reflect.DeepEqual(oldAnpObj.Spec.Subject, newAnpObj.Spec.Subject) { + c.updateAnpQueue.Add(ChangedDelta{key: newAnpObj.Name, field: ChangedSubject}) + } + + // Rule name or peer selector in ingress/egress rule has changed, the corresponding address-set need be updated + ruleChanged := false + var changedIngressRuleNames, changedEgressRuleNames [util.AnpMaxRules]ChangedName + for index, rule := range newAnpObj.Spec.Ingress { + oldRule := oldAnpObj.Spec.Ingress[index] + if oldRule.Name != rule.Name { + changedIngressRuleNames[index] = ChangedName{oldRuleName: oldRule.Name, curRuleName: rule.Name} + ruleChanged = true + } + if !reflect.DeepEqual(oldRule.From, rule.From) { + changedIngressRuleNames[index] = ChangedName{curRuleName: rule.Name} + ruleChanged = true + } + } + if ruleChanged { + c.updateAnpQueue.Add(ChangedDelta{key: newAnpObj.Name, ruleNames: changedIngressRuleNames, field: ChangedIngressRule}) + } + + ruleChanged = false + for index, rule := range newAnpObj.Spec.Egress { + oldRule := oldAnpObj.Spec.Egress[index] + if oldRule.Name != rule.Name { + changedEgressRuleNames[index] = ChangedName{oldRuleName: oldRule.Name, curRuleName: rule.Name} + ruleChanged = true + } + if !reflect.DeepEqual(oldRule.To, rule.To) { + changedEgressRuleNames[index] = ChangedName{curRuleName: rule.Name} + ruleChanged = true + } + } + if ruleChanged { + c.updateAnpQueue.Add(ChangedDelta{key: newAnpObj.Name, ruleNames: changedEgressRuleNames, field: ChangedEgressRule}) + } +} + +func (c *Controller) runAddAnpWorker() { + for c.processNextAddAnpWorkItem() { + } +} + +func (c *Controller) runUpdateAnpWorker() { + for c.processNextUpdateAnpWorkItem() { + } +} + +func (c *Controller) runDeleteAnpWorker() { + for c.processNextDeleteAnpWorkItem() { + } +} + +func (c *Controller) processNextAddAnpWorkItem() bool { + obj, shutdown := c.addAnpQueue.Get() + if shutdown { + return false + } + now := time.Now() + + err := func(obj interface{}) error { + defer c.addAnpQueue.Done(obj) + var key string + var ok bool + if key, ok = obj.(string); !ok { + c.addAnpQueue.Forget(obj) + utilruntime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj)) + return nil + } + if err := c.handleAddAnp(key); err != nil { + c.addAnpQueue.AddRateLimited(key) + return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error()) + } + last := time.Since(now) + klog.Infof("take %d ms to handle add anp %s", last.Milliseconds(), key) + c.addAnpQueue.Forget(obj) + return nil + }(obj) + if err != nil { + utilruntime.HandleError(err) + return true + } + return true +} + +func (c *Controller) processNextUpdateAnpWorkItem() bool { + obj, shutdown := c.updateAnpQueue.Get() + if shutdown { + return false + } + + err := func(obj interface{}) error { + defer c.updateAnpQueue.Done(obj) + var key ChangedDelta + var ok bool + if key, ok = obj.(ChangedDelta); !ok { + c.updateAnpQueue.Forget(obj) + utilruntime.HandleError(fmt.Errorf("expected ChangedDelta in workqueue but got %#v", obj)) + return nil + } + if err := c.handleUpdateAnp(key); err != nil { + c.updateAnpQueue.AddRateLimited(key) + return fmt.Errorf("error syncing admin network policy %s: %w, requeuing", key.key, err) + } + c.updateAnpQueue.Forget(obj) + return nil + }(obj) + if err != nil { + utilruntime.HandleError(err) + return true + } + return true +} + +func (c *Controller) processNextDeleteAnpWorkItem() bool { + obj, shutdown := c.deleteAnpQueue.Get() + if shutdown { + return false + } + + err := func(obj interface{}) error { + defer c.deleteAnpQueue.Done(obj) + var anp *v1alpha1.AdminNetworkPolicy + var ok bool + if anp, ok = obj.(*v1alpha1.AdminNetworkPolicy); !ok { + c.deleteAnpQueue.Forget(obj) + utilruntime.HandleError(fmt.Errorf("expected anp object in workqueue but got %#v", obj)) + return nil + } + if err := c.handleDeleteAnp(anp); err != nil { + c.deleteAnpQueue.AddRateLimited(obj) + return fmt.Errorf("error syncing anp '%s': %s, requeuing", anp.Name, err.Error()) + } + c.deleteAnpQueue.Forget(obj) + return nil + }(obj) + if err != nil { + utilruntime.HandleError(err) + return true + } + return true +} + +func (c *Controller) handleAddAnp(key string) (err error) { + c.anpKeyMutex.LockKey(key) + defer func() { _ = c.anpKeyMutex.UnlockKey(key) }() + + cachedAnp, err := c.anpsLister.Get(key) + if err != nil { + if k8serrors.IsNotFound(err) { + return nil + } + klog.Error(err) + return err + } + klog.Infof("handle add anp %s", cachedAnp.Name) + anp := cachedAnp.DeepCopy() + + if err := c.validateAnpConfig(anp); err != nil { + klog.Errorf("failed to validate anp %s: %v", anp.Name, err) + return err + } + if priority, exist := c.anpNamePrioMap[anp.Name]; exist && priority != anp.Spec.Priority { + // anp spec's priority has been changed + delete(c.anpPrioNameMap, priority) + } + // record new created anp after validation + c.anpPrioNameMap[anp.Spec.Priority] = anp.Name + c.anpNamePrioMap[anp.Name] = anp.Spec.Priority + + anpName := getAnpName(anp.Name) + + // ovn portGroup/addressSet doesn't support name with '-', so we replace '-' by '.'. + // This may cause conflict if two anp with name test-anp and test.anp, maybe hash is a better solution, but we do not want to lost the readability now. + // Make sure all create operations are reentrant. + pgName := strings.ReplaceAll(anpName, "-", ".") + if err = c.OVNNbClient.CreatePortGroup(pgName, map[string]string{adminNetworkPolicyKey: anpName}); err != nil { + klog.Errorf("failed to create port group for anp %s: %v", key, err) + return err + } + + ports, err := c.fetchSelectedPods(&anp.Spec.Subject) + if err != nil { + klog.Errorf("failed to fetch ports belongs to anp %s: %v", key, err) + return err + } + + if err = c.OVNNbClient.PortGroupSetPorts(pgName, ports); err != nil { + klog.Errorf("failed to set ports %v to port group %s: %v", ports, pgName, err) + return err + } + + ingressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "to-lport", nil) + if err != nil { + klog.Errorf("failed to generate clear operations for anp %s ingress acls: %v", key, err) + return err + } + + curIngressAddrSet, curEgressAddrSet, err := c.getCurrentAddrSetByName(anpName, false) + if err != nil { + klog.Errorf("failed to list address sets for anp %s: %v", key, err) + return err + } + desiredIngressAddrSet := strset.NewWithSize(len(anp.Spec.Ingress) * 2) + desiredEgressAddrSet := strset.NewWithSize(len(anp.Spec.Egress) * 2) + + // create ingress acl + for index, anpr := range anp.Spec.Ingress { + // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different + ingressAsV4Name, ingressAsV6Name := getAnpAddressSetName(pgName, anpr.Name, index, true) + desiredIngressAddrSet.Add(ingressAsV4Name, ingressAsV6Name) + + var v4Addrs, v4Addr, v6Addrs, v6Addr []string + // This field must be defined and contain at least one item. + for _, anprpeer := range anpr.From { + if v4Addr, v6Addr, err = c.fetchIngressSelectedAddresses(&anprpeer); err != nil { + klog.Errorf("failed to fetch admin network policy selected addresses, %v", err) + return err + } + v4Addrs = append(v4Addrs, v4Addr...) + v6Addrs = append(v6Addrs, v6Addr...) + } + klog.Infof("anp %s, ingress rule %s, selected v4 address %v, v6 address %v", anpName, anpr.Name, v4Addrs, v6Addrs) + + if err = c.createAsForAnpRule(anpName, anpr.Name, "ingress", ingressAsV4Name, v4Addrs, false); err != nil { + klog.Error(err) + return err + } + if err = c.createAsForAnpRule(anpName, anpr.Name, "ingress", ingressAsV6Name, v6Addrs, false); err != nil { + klog.Error(err) + return err + } + + aclPriority := util.AnpACLMaxPriority - int(anp.Spec.Priority*100) - index + aclAction := convertAction(anpr.Action, "") + rulePorts := []v1alpha1.AdminNetworkPolicyPort{} + if anpr.Ports != nil { + rulePorts = *anpr.Ports + } + + if len(v4Addrs) != 0 { + ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, ingressAsV4Name, kubeovnv1.ProtocolIPv4, aclPriority, aclAction, rulePorts, true, false) + if err != nil { + klog.Errorf("failed to add v4 ingress acls for anp %s: %v", key, err) + return err + } + ingressACLOps = append(ingressACLOps, ops...) + } + + if len(v6Addrs) != 0 { + ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, ingressAsV6Name, kubeovnv1.ProtocolIPv6, aclPriority, aclAction, rulePorts, true, false) + if err != nil { + klog.Errorf("failed to add v6 ingress acls for anp %s: %v", key, err) + return err + } + ingressACLOps = append(ingressACLOps, ops...) + } + } + + if err := c.OVNNbClient.Transact("add-ingress-acls", ingressACLOps); err != nil { + return fmt.Errorf("failed to add ingress acls for anp %s: %w", key, err) + } + if err := c.deleteUnusedAddrSetForAnp(curIngressAddrSet, desiredIngressAddrSet); err != nil { + return fmt.Errorf("failed to delete unused ingress address set for anp %s: %w", key, err) + } + + egressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "from-lport", nil) + if err != nil { + klog.Errorf("failed to generate clear operations for anp %s egress acls: %v", key, err) + return err + } + // create egress acl + for index, anpr := range anp.Spec.Egress { + // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different + egressAsV4Name, egressAsV6Name := getAnpAddressSetName(pgName, anpr.Name, index, false) + desiredEgressAddrSet.Add(egressAsV4Name, egressAsV6Name) + + var v4Addrs, v4Addr, v6Addrs, v6Addr []string + // This field must be defined and contain at least one item. + for _, anprpeer := range anpr.To { + if v4Addr, v6Addr, err = c.fetchEgressSelectedAddresses(&anprpeer); err != nil { + klog.Errorf("failed to fetch admin network policy selected addresses, %v", err) + return err + } + v4Addrs = append(v4Addrs, v4Addr...) + v6Addrs = append(v6Addrs, v6Addr...) + } + klog.Infof("anp %s, egress rule %s, selected v4 address %v, v6 address %v", anpName, anpr.Name, v4Addrs, v6Addrs) + + if err = c.createAsForAnpRule(anpName, anpr.Name, "egress", egressAsV4Name, v4Addrs, false); err != nil { + klog.Error(err) + return err + } + if err = c.createAsForAnpRule(anpName, anpr.Name, "egress", egressAsV6Name, v6Addrs, false); err != nil { + klog.Error(err) + return err + } + + aclPriority := util.AnpACLMaxPriority - int(anp.Spec.Priority*100) - index + aclAction := convertAction(anpr.Action, "") + rulePorts := []v1alpha1.AdminNetworkPolicyPort{} + if anpr.Ports != nil { + rulePorts = *anpr.Ports + } + + if len(v4Addrs) != 0 { + ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, egressAsV4Name, kubeovnv1.ProtocolIPv4, aclPriority, aclAction, rulePorts, false, false) + if err != nil { + klog.Errorf("failed to add v4 egress acls for anp %s: %v", key, err) + return err + } + egressACLOps = append(egressACLOps, ops...) + } + + if len(v6Addrs) != 0 { + ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, egressAsV6Name, kubeovnv1.ProtocolIPv6, aclPriority, aclAction, rulePorts, false, false) + if err != nil { + klog.Errorf("failed to add v6 egress acls for anp %s: %v", key, err) + return err + } + egressACLOps = append(egressACLOps, ops...) + } + } + + if err := c.OVNNbClient.Transact("add-egress-acls", egressACLOps); err != nil { + return fmt.Errorf("failed to add egress acls for anp %s: %w", key, err) + } + if err := c.deleteUnusedAddrSetForAnp(curEgressAddrSet, desiredEgressAddrSet); err != nil { + return fmt.Errorf("failed to delete unused egress address set for anp %s: %w", key, err) + } + + return nil +} + +func (c *Controller) handleDeleteAnp(anp *v1alpha1.AdminNetworkPolicy) error { + c.anpKeyMutex.LockKey(anp.Name) + defer func() { _ = c.anpKeyMutex.UnlockKey(anp.Name) }() + + klog.Infof("handle delete admin network policy %s", anp.Name) + delete(c.anpPrioNameMap, anp.Spec.Priority) + delete(c.anpNamePrioMap, anp.Name) + + anpName := getAnpName(anp.Name) + + // ACLs releated to port_group will be deleted automatically when port_group is deleted + pgName := strings.ReplaceAll(anpName, "-", ".") + if err := c.OVNNbClient.DeletePortGroup(pgName); err != nil { + klog.Errorf("failed to delete port group for anp %s: %v", anpName, err) + } + + if err := c.OVNNbClient.DeleteAddressSets(map[string]string{ + adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "ingress"), + }); err != nil { + klog.Errorf("failed to delete ingress address set for anp %s: %v", anpName, err) + return err + } + + if err := c.OVNNbClient.DeleteAddressSets(map[string]string{ + adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "egress"), + }); err != nil { + klog.Errorf("failed to delete egress address set for anp %s: %v", anpName, err) + return err + } + + return nil +} + +func (c *Controller) handleUpdateAnp(changed ChangedDelta) error { + // Only handle updates that do not affect acls. + c.anpKeyMutex.LockKey(changed.key) + defer func() { _ = c.anpKeyMutex.UnlockKey(changed.key) }() + + cachedAnp, err := c.anpsLister.Get(changed.key) + if err != nil { + if k8serrors.IsNotFound(err) { + return nil + } + klog.Error(err) + return err + } + desiredAnp := cachedAnp.DeepCopy() + klog.Infof("handle update admin network policy %s", desiredAnp.Name) + + anpName := getAnpName(desiredAnp.Name) + pgName := strings.ReplaceAll(anpName, "-", ".") + + // The port-group for anp should be updated + if changed.field == ChangedSubject { + // The port-group must exist when update anp, this check should never be matched. + if ok, err := c.OVNNbClient.PortGroupExists(pgName); !ok || err != nil { + klog.Errorf("port-group for anp %s does not exist when update anp", desiredAnp.Name) + return err + } + + ports, err := c.fetchSelectedPods(&desiredAnp.Spec.Subject) + if err != nil { + klog.Errorf("failed to fetch ports belongs to anp %s: %v", desiredAnp.Name, err) + return err + } + + if err = c.OVNNbClient.PortGroupSetPorts(pgName, ports); err != nil { + klog.Errorf("failed to set ports %v to port group %s: %v", ports, pgName, err) + return err + } + } + + // Peer selector in ingress/egress rule has changed, so the corresponding address-set need be updated + if changed.field == ChangedIngressRule { + for index, rule := range desiredAnp.Spec.Ingress { + // Make sure the rule is changed and go on update + if rule.Name == changed.ruleNames[index].curRuleName || changed.ruleNames[index].isMatch { + if err := c.setAddrSetForAnpRule(anpName, pgName, rule.Name, index, rule.From, []v1alpha1.AdminNetworkPolicyEgressPeer{}, true, false); err != nil { + klog.Errorf("failed to set ingress address-set for anp rule %s/%s, %v", anpName, rule.Name, err) + return err + } + + if changed.ruleNames[index].oldRuleName != "" { + oldRuleName := changed.ruleNames[index].oldRuleName + // Normally the name can not be changed, but when the name really changes, the old address set should be deleted + // There is no description in the Name comments that it cannot be changed + oldAsV4Name, oldAsV6Name := getAnpAddressSetName(pgName, oldRuleName, index, true) + + if err := c.OVNNbClient.DeleteAddressSet(oldAsV4Name); err != nil { + klog.Errorf("failed to delete address set %s, %v", oldAsV4Name, err) + // just record error log + } + if err := c.OVNNbClient.DeleteAddressSet(oldAsV6Name); err != nil { + klog.Errorf("failed to delete address set %s, %v", oldAsV6Name, err) + } + } + } + } + } + + if changed.field == ChangedEgressRule { + for index, rule := range desiredAnp.Spec.Egress { + // Make sure the rule is changed and go on update + if rule.Name == changed.ruleNames[index].curRuleName || changed.ruleNames[index].isMatch { + if err := c.setAddrSetForAnpRule(anpName, pgName, rule.Name, index, []v1alpha1.AdminNetworkPolicyIngressPeer{}, rule.To, false, false); err != nil { + klog.Errorf("failed to set egress address-set for anp rule %s/%s, %v", anpName, rule.Name, err) + return err + } + + if changed.ruleNames[index].oldRuleName != "" { + oldRuleName := changed.ruleNames[index].oldRuleName + // Normally the name can not be changed, but when the name really changes, the old address set should be deleted + // There is no description in the Name comments that it cannot be changed + oldAsV4Name, oldAsV6Name := getAnpAddressSetName(pgName, oldRuleName, index, false) + + if err := c.OVNNbClient.DeleteAddressSet(oldAsV4Name); err != nil { + klog.Errorf("failed to delete address set %s, %v", oldAsV4Name, err) + // just record error log + } + if err := c.OVNNbClient.DeleteAddressSet(oldAsV6Name); err != nil { + klog.Errorf("failed to delete address set %s, %v", oldAsV6Name, err) + } + } + } + } + } + + return nil +} + +func (c *Controller) validateAnpConfig(anp *v1alpha1.AdminNetworkPolicy) error { + // The behavior is undefined if two ANP objects have same priority. + if anpName, exist := c.anpPrioNameMap[anp.Spec.Priority]; exist && anpName != anp.Name { + err := fmt.Errorf("can not create anp with same priority %d, exist one is %s, new created is %s", anp.Spec.Priority, anpName, anp.Name) + klog.Error(err) + return err + } + + // We have noticed redhat's discussion about ACL priority in https://bugzilla.redhat.com/show_bug.cgi?id=2175752 + // After discussion, we decided to use the same range of priorities(20000-30000). Pay tribute to the developers of redhat. + if anp.Spec.Priority > util.AnpMaxPriority { + err := fmt.Errorf("the priority of anp %s is greater than max value %d", anp.Name, util.AnpMaxPriority) + klog.Error(err) + return err + } + + if len(anp.Spec.Ingress) > util.AnpMaxRules || len(anp.Spec.Egress) > util.AnpMaxRules { + err := fmt.Errorf("at most %d rules can be create in anp ingress/egress, ingress rules num %d and egress rules num %d in anp %s", util.AnpMaxRules, len(anp.Spec.Ingress), len(anp.Spec.Egress), anp.Name) + klog.Error(err) + return err + } + + if len(anp.Spec.Ingress) == 0 && len(anp.Spec.Egress) == 0 { + err := fmt.Errorf("one of ingress/egress rules must be set, both ingress/egress are empty for anp %s", anp.Name) + klog.Error(err) + return err + } + + return nil +} + +func (c *Controller) fetchSelectedPods(anpSubject *v1alpha1.AdminNetworkPolicySubject) ([]string, error) { + var ports []string + + // Exactly one field must be set. + if anpSubject.Namespaces != nil { + nsSelector, err := metav1.LabelSelectorAsSelector(anpSubject.Namespaces) + if err != nil { + return nil, fmt.Errorf("error creating ns label selector, %w", err) + } + + ports, _, _, err = c.fetchPods(nsSelector, labels.Everything()) + if err != nil { + return nil, fmt.Errorf("failed to fetch pods, %w", err) + } + } else { + nsSelector, err := metav1.LabelSelectorAsSelector(&anpSubject.Pods.NamespaceSelector) + if err != nil { + return nil, fmt.Errorf("error creating ns label selector, %w", err) + } + podSelector, err := metav1.LabelSelectorAsSelector(&anpSubject.Pods.PodSelector) + if err != nil { + return nil, fmt.Errorf("error creating pod label selector, %w", err) + } + + ports, _, _, err = c.fetchPods(nsSelector, podSelector) + if err != nil { + return nil, fmt.Errorf("failed to fetch pods, %w", err) + } + } + klog.Infof("get selected ports for subject, %v", ports) + return ports, nil +} + +func (c *Controller) fetchPods(nsSelector, podSelector labels.Selector) ([]string, []string, []string, error) { + ports := make([]string, 0, util.AnpMaxRules) + v4Addresses := make([]string, 0, util.AnpMaxRules) + v6Addresses := make([]string, 0, util.AnpMaxRules) + + namespaces, err := c.namespacesLister.List(nsSelector) + if err != nil { + klog.Errorf("failed to list namespaces: %v", err) + return nil, nil, nil, err + } + + klog.V(3).Infof("fetch pod ports/addresses, namespace selector is %s, pod selector is %s", nsSelector.String(), podSelector.String()) + for _, namespace := range namespaces { + pods, err := c.podsLister.Pods(namespace.Name).List(podSelector) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to list pods, %w", err) + } + + for _, pod := range pods { + if pod.Spec.HostNetwork { + continue + } + podName := c.getNameByPod(pod) + + podNets, err := c.getPodKubeovnNets(pod) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to get pod networks, %w", err) + } + + for _, podNet := range podNets { + if !isOvnSubnet(podNet.Subnet) { + continue + } + + if pod.Annotations[fmt.Sprintf(util.AllocatedAnnotationTemplate, podNet.ProviderName)] == "true" { + ports = append(ports, ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName)) + + podIPAnnotation := pod.Annotations[fmt.Sprintf(util.IPAddressAnnotationTemplate, podNet.ProviderName)] + podIPs := strings.Split(podIPAnnotation, ",") + for _, podIP := range podIPs { + switch util.CheckProtocol(podIP) { + case kubeovnv1.ProtocolIPv4: + v4Addresses = append(v4Addresses, podIP) + case kubeovnv1.ProtocolIPv6: + v6Addresses = append(v6Addresses, podIP) + } + } + } + } + } + } + + return ports, v4Addresses, v6Addresses, nil +} + +func (c *Controller) fetchIngressSelectedAddresses(ingressPeer *v1alpha1.AdminNetworkPolicyIngressPeer) ([]string, []string, error) { + var v4Addresses, v6Addresses []string + + // Exactly one of the selector pointers must be set for a given peer. + if ingressPeer.Namespaces != nil { + nsSelector, err := metav1.LabelSelectorAsSelector(ingressPeer.Namespaces) + if err != nil { + return nil, nil, fmt.Errorf("error creating ns label selector, %w", err) + } + + _, v4Addresses, v6Addresses, err = c.fetchPods(nsSelector, labels.Everything()) + if err != nil { + return nil, nil, fmt.Errorf("failed to fetch ingress peer addresses, %w", err) + } + } else if ingressPeer.Pods != nil { + nsSelector, err := metav1.LabelSelectorAsSelector(&ingressPeer.Pods.NamespaceSelector) + if err != nil { + return nil, nil, fmt.Errorf("error creating ns label selector, %w", err) + } + podSelector, err := metav1.LabelSelectorAsSelector(&ingressPeer.Pods.PodSelector) + if err != nil { + return nil, nil, fmt.Errorf("error creating pod label selector, %w", err) + } + + _, v4Addresses, v6Addresses, err = c.fetchPods(nsSelector, podSelector) + if err != nil { + return nil, nil, fmt.Errorf("failed to fetch ingress peer addresses, %w", err) + } + } + + return v4Addresses, v6Addresses, nil +} + +func (c *Controller) fetchEgressSelectedAddresses(egressPeer *v1alpha1.AdminNetworkPolicyEgressPeer) ([]string, []string, error) { + var v4Addresses, v6Addresses []string + + // Exactly one of the selector pointers must be set for a given peer. + // Do not support Nodes and Networks filter now + switch { + case egressPeer.Namespaces != nil: + nsSelector, err := metav1.LabelSelectorAsSelector(egressPeer.Namespaces) + if err != nil { + return nil, nil, fmt.Errorf("error creating ns label selector, %w", err) + } + + _, v4Addresses, v6Addresses, err = c.fetchPods(nsSelector, labels.Everything()) + if err != nil { + return nil, nil, fmt.Errorf("failed to fetch egress peer addresses, %w", err) + } + case egressPeer.Pods != nil: + nsSelector, err := metav1.LabelSelectorAsSelector(&egressPeer.Pods.NamespaceSelector) + if err != nil { + return nil, nil, fmt.Errorf("error creating ns label selector, %w", err) + } + podSelector, err := metav1.LabelSelectorAsSelector(&egressPeer.Pods.PodSelector) + if err != nil { + return nil, nil, fmt.Errorf("error creating pod label selector, %w", err) + } + + _, v4Addresses, v6Addresses, err = c.fetchPods(nsSelector, podSelector) + if err != nil { + return nil, nil, fmt.Errorf("failed to fetch egress peer addresses, %w", err) + } + default: + return nil, nil, errors.New("either Namespaces or Pods must be specified in egressPeer") + } + + return v4Addresses, v6Addresses, nil +} + +func (c *Controller) createAsForAnpRule(anpName, ruleName, direction, asName string, addresses []string, isBanp bool) error { + var err error + if isBanp { + err = c.OVNNbClient.CreateAddressSet(asName, map[string]string{ + baselineAdminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, direction), + }) + } else { + err = c.OVNNbClient.CreateAddressSet(asName, map[string]string{ + adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, direction), + }) + } + if err != nil { + klog.Errorf("failed to create ovn address set %s for anp/banp rule %s/%s: %v", asName, anpName, ruleName, err) + return err + } + + if err := c.OVNNbClient.AddressSetUpdateAddress(asName, addresses...); err != nil { + klog.Errorf("failed to set addresses %q to address set %s: %v", strings.Join(addresses, ","), asName, err) + return err + } + + return nil +} + +func (c *Controller) getCurrentAddrSetByName(anpName string, isBanp bool) (*strset.Set, *strset.Set, error) { + curIngressAddrSet := strset.New() + curEgressAddrSet := strset.New() + var ass []ovnnb.AddressSet + var err error + + // anp and banp can use same name, so depends on the external_ids key field to distinguish + if isBanp { + ass, err = c.OVNNbClient.ListAddressSets(map[string]string{ + baselineAdminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "ingress"), + }) + } else { + ass, err = c.OVNNbClient.ListAddressSets(map[string]string{ + adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "ingress"), + }) + } + if err != nil { + klog.Errorf("failed to list ingress address sets for anp/banp %s: %v", anpName, err) + return curIngressAddrSet, curEgressAddrSet, err + } + for _, as := range ass { + curIngressAddrSet.Add(as.Name) + } + + if isBanp { + ass, err = c.OVNNbClient.ListAddressSets(map[string]string{ + baselineAdminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "egress"), + }) + } else { + ass, err = c.OVNNbClient.ListAddressSets(map[string]string{ + adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "egress"), + }) + } + if err != nil { + klog.Errorf("failed to list egress address sets for anp/banp %s: %v", anpName, err) + return curIngressAddrSet, curEgressAddrSet, err + } + for _, as := range ass { + curEgressAddrSet.Add(as.Name) + } + + return curIngressAddrSet, curEgressAddrSet, nil +} + +func (c *Controller) deleteUnusedAddrSetForAnp(curAddrSet, desiredAddrSet *strset.Set) error { + toDel := strset.Difference(curAddrSet, desiredAddrSet).List() + + for _, asName := range toDel { + if err := c.OVNNbClient.DeleteAddressSet(asName); err != nil { + klog.Errorf("failed to delete address set %s, %v", asName, err) + return err + } + } + + return nil +} + +func (c *Controller) setAddrSetForAnpRule(anpName, pgName, ruleName string, index int, from []v1alpha1.AdminNetworkPolicyIngressPeer, to []v1alpha1.AdminNetworkPolicyEgressPeer, isIngress, isBanp bool) error { + // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different + + var v4Addrs, v4Addr, v6Addrs, v6Addr []string + var err error + if isIngress { + for _, anprpeer := range from { + if v4Addr, v6Addr, err = c.fetchIngressSelectedAddresses(&anprpeer); err != nil { + klog.Errorf("failed to fetch anp/banp ingress selected addresses, %v", err) + return err + } + v4Addrs = append(v4Addrs, v4Addr...) + v6Addrs = append(v6Addrs, v6Addr...) + } + klog.Infof("update anp/banp ingress rule %s, selected v4 address %v, v6 address %v", ruleName, v4Addrs, v6Addrs) + + gressAsV4Name, gressAsV6Name := getAnpAddressSetName(pgName, ruleName, index, true) + if err = c.createAsForAnpRule(anpName, ruleName, "ingress", gressAsV4Name, v4Addrs, isBanp); err != nil { + klog.Error(err) + return err + } + if err = c.createAsForAnpRule(anpName, ruleName, "ingress", gressAsV6Name, v6Addrs, isBanp); err != nil { + klog.Error(err) + return err + } + } else { + for _, anprpeer := range to { + if v4Addr, v6Addr, err = c.fetchEgressSelectedAddresses(&anprpeer); err != nil { + klog.Errorf("failed to fetch anp/banp egress selected addresses, %v", err) + return err + } + v4Addrs = append(v4Addrs, v4Addr...) + v6Addrs = append(v6Addrs, v6Addr...) + } + klog.Infof("update anp/banp egress rule %s, selected v4 address %v, v6 address %v", ruleName, v4Addrs, v6Addrs) + + gressAsV4Name, gressAsV6Name := getAnpAddressSetName(pgName, ruleName, index, false) + if err = c.createAsForAnpRule(anpName, ruleName, "egress", gressAsV4Name, v4Addrs, isBanp); err != nil { + klog.Error(err) + return err + } + if err = c.createAsForAnpRule(anpName, ruleName, "egress", gressAsV6Name, v6Addrs, isBanp); err != nil { + klog.Error(err) + return err + } + } + + return nil +} + +func (c *Controller) updateAnpsByLabelsMatch(nsLabels, podLabels map[string]string) { + anps, _ := c.anpsLister.List(labels.Everything()) + for _, anp := range anps { + changed := ChangedDelta{ + key: anp.Name, + } + + if isLabelsMatch(anp.Spec.Subject.Namespaces, anp.Spec.Subject.Pods, nsLabels, podLabels) { + klog.Infof("anp %s, labels matched for anp's subject, nsLabels %s, podLabels %s", anp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String()) + changed.field = ChangedSubject + c.updateAnpQueue.Add(changed) + } + + ingressRuleNames, egressRuleNames := isLabelsMatchAnpRulePeers(anp.Spec.Ingress, anp.Spec.Egress, nsLabels, podLabels) + if !isRulesArrayEmpty(ingressRuleNames) { + klog.Infof("anp %s, labels matched for anp's ingress peer, nsLabels %s, podLabels %s", anp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String()) + changed.ruleNames = ingressRuleNames + changed.field = ChangedIngressRule + c.updateAnpQueue.Add(changed) + } + + if !isRulesArrayEmpty(egressRuleNames) { + klog.Infof("anp %s, labels matched for anp's egress peer, nsLabels %s, podLabels %s", anp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String()) + changed.ruleNames = egressRuleNames + changed.field = ChangedEgressRule + c.updateAnpQueue.Add(changed) + } + } + + banps, _ := c.banpsLister.List(labels.Everything()) + for _, banp := range banps { + changed := ChangedDelta{ + key: banp.Name, + } + + if isLabelsMatch(banp.Spec.Subject.Namespaces, banp.Spec.Subject.Pods, nsLabels, podLabels) { + klog.Infof("banp %s, labels matched for banp's subject, nsLabels %s, podLabels %s", banp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String()) + changed.field = ChangedSubject + c.updateBanpQueue.Add(changed) + } + + ingressRuleNames, egressRuleNames := isLabelsMatchBanpRulePeers(banp.Spec.Ingress, banp.Spec.Egress, nsLabels, podLabels) + if !isRulesArrayEmpty(ingressRuleNames) { + klog.Infof("banp %s, labels matched for banp's ingress peer, nsLabels %s, podLabels %s", banp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String()) + changed.ruleNames = ingressRuleNames + changed.field = ChangedIngressRule + c.updateBanpQueue.Add(changed) + } + + if !isRulesArrayEmpty(egressRuleNames) { + klog.Infof("banp %s, labels matched for banp's egress peer, nsLabels %s, podLabels %s", banp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String()) + changed.ruleNames = egressRuleNames + changed.field = ChangedEgressRule + c.updateBanpQueue.Add(changed) + } + } +} + +func isLabelsMatch(namespaces *metav1.LabelSelector, pods *v1alpha1.NamespacedPod, nsLabels, podLabels map[string]string) bool { + // Exactly one field of namespaces/pods must be set. + if namespaces != nil { + nsSelector, _ := metav1.LabelSelectorAsSelector(namespaces) + klog.V(3).Infof("namespaces is not nil, nsSelector %s", nsSelector.String()) + if nsSelector.Matches(labels.Set(nsLabels)) { + return true + } + } else { + nsSelector, _ := metav1.LabelSelectorAsSelector(&pods.NamespaceSelector) + podSelector, _ := metav1.LabelSelectorAsSelector(&pods.PodSelector) + klog.V(3).Infof("pods is not nil, nsSelector %s, podSelector %s", nsSelector.String(), podSelector.String()) + if nsSelector.Matches(labels.Set(nsLabels)) && podSelector.Matches(labels.Set(podLabels)) { + return true + } + } + + return false +} + +func isLabelsMatchRulePeers(from []v1alpha1.AdminNetworkPolicyIngressPeer, to []v1alpha1.AdminNetworkPolicyEgressPeer, nsLabels, podLabels map[string]string) bool { + for _, ingressPeer := range from { + if isLabelsMatch(ingressPeer.Namespaces, ingressPeer.Pods, nsLabels, podLabels) { + return true + } + } + + for _, egressPeer := range to { + if isLabelsMatch(egressPeer.Namespaces, egressPeer.Pods, nsLabels, podLabels) { + return true + } + } + + return false +} + +func isLabelsMatchAnpRulePeers(ingress []v1alpha1.AdminNetworkPolicyIngressRule, egress []v1alpha1.AdminNetworkPolicyEgressRule, nsLabels, podLabels map[string]string) ([util.AnpMaxRules]ChangedName, [util.AnpMaxRules]ChangedName) { + var changedIngressRuleNames, changedEgressRuleNames [util.AnpMaxRules]ChangedName + + for index, anpr := range ingress { + if isLabelsMatchRulePeers(anpr.From, []v1alpha1.AdminNetworkPolicyEgressPeer{}, nsLabels, podLabels) { + changedIngressRuleNames[index].isMatch = true + changedIngressRuleNames[index].curRuleName = anpr.Name + } + } + + for index, anpr := range egress { + if isLabelsMatchRulePeers([]v1alpha1.AdminNetworkPolicyIngressPeer{}, anpr.To, nsLabels, podLabels) { + changedEgressRuleNames[index].isMatch = true + changedEgressRuleNames[index].curRuleName = anpr.Name + } + } + + return changedIngressRuleNames, changedEgressRuleNames +} + +func isLabelsMatchBanpRulePeers(ingress []v1alpha1.BaselineAdminNetworkPolicyIngressRule, egress []v1alpha1.BaselineAdminNetworkPolicyEgressRule, nsLabels, podLabels map[string]string) ([util.AnpMaxRules]ChangedName, [util.AnpMaxRules]ChangedName) { + var changedIngressRuleNames, changedEgressRuleNames [util.AnpMaxRules]ChangedName + + for index, banpr := range ingress { + if isLabelsMatchRulePeers(banpr.From, []v1alpha1.AdminNetworkPolicyEgressPeer{}, nsLabels, podLabels) { + changedIngressRuleNames[index].isMatch = true + changedIngressRuleNames[index].curRuleName = banpr.Name + } + } + + for index, banpr := range egress { + if isLabelsMatchRulePeers([]v1alpha1.AdminNetworkPolicyIngressPeer{}, banpr.To, nsLabels, podLabels) { + changedEgressRuleNames[index].isMatch = true + changedEgressRuleNames[index].curRuleName = banpr.Name + } + } + + return changedIngressRuleNames, changedEgressRuleNames +} + +func getAnpName(name string) string { + anpName := name + nameArray := []rune(name) + if !unicode.IsLetter(nameArray[0]) { + anpName = "anp" + name + } + return anpName +} + +func getAnpAddressSetName(pgName, ruleName string, index int, isIngress bool) (string, string) { + var asV4Name, asV6Name string + if isIngress { + // In case ruleName is omitted, add direction and index to distinguish address-set + asV4Name = strings.ReplaceAll(fmt.Sprintf("%s.ingress.%d.%s.%s", pgName, index, ruleName, kubeovnv1.ProtocolIPv4), "-", ".") + asV6Name = strings.ReplaceAll(fmt.Sprintf("%s.ingress.%d.%s.%s", pgName, index, ruleName, kubeovnv1.ProtocolIPv6), "-", ".") + } else { + asV4Name = strings.ReplaceAll(fmt.Sprintf("%s.egress.%d.%s.%s", pgName, index, ruleName, kubeovnv1.ProtocolIPv4), "-", ".") + asV6Name = strings.ReplaceAll(fmt.Sprintf("%s.egress.%d.%s.%s", pgName, index, ruleName, kubeovnv1.ProtocolIPv6), "-", ".") + } + + return asV4Name, asV6Name +} + +func convertAction(anpRuleAction v1alpha1.AdminNetworkPolicyRuleAction, banpRuleAction v1alpha1.BaselineAdminNetworkPolicyRuleAction) (aclAction ovnnb.ACLAction) { + switch anpRuleAction { + case v1alpha1.AdminNetworkPolicyRuleActionAllow: + aclAction = ovnnb.ACLActionAllow + case v1alpha1.AdminNetworkPolicyRuleActionDeny: + aclAction = ovnnb.ACLActionDrop + case v1alpha1.AdminNetworkPolicyRuleActionPass: + aclAction = ovnnb.ACLActionPass + } + + switch banpRuleAction { + case v1alpha1.BaselineAdminNetworkPolicyRuleActionAllow: + aclAction = ovnnb.ACLActionAllow + case v1alpha1.BaselineAdminNetworkPolicyRuleActionDeny: + aclAction = ovnnb.ACLActionDrop + } + return +} + +func isRulesArrayEmpty(ruleNames [util.AnpMaxRules]ChangedName) bool { + isEmpty := true + for _, ruleName := range ruleNames { + // The ruleName can be omitted default + if ruleName.curRuleName != "" || ruleName.isMatch { + isEmpty = false + break + } + } + return isEmpty +} diff --git a/pkg/controller/baseline_admin_network_policy.go b/pkg/controller/baseline_admin_network_policy.go new file mode 100644 index 000000000000..6dc630bac68c --- /dev/null +++ b/pkg/controller/baseline_admin_network_policy.go @@ -0,0 +1,516 @@ +package controller + +import ( + "fmt" + "reflect" + "strings" + "time" + + "github.com/scylladb/go-set/strset" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/tools/cache" + "k8s.io/klog/v2" + v1alpha1 "sigs.k8s.io/network-policy-api/apis/v1alpha1" + + kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" + "github.com/kubeovn/kube-ovn/pkg/util" +) + +func (c *Controller) enqueueAddBanp(obj interface{}) { + var key string + var err error + if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { + utilruntime.HandleError(err) + return + } + klog.V(3).Infof("enqueue add banp %s", key) + c.addBanpQueue.Add(key) +} + +func (c *Controller) enqueueDeleteBanp(obj interface{}) { + var key string + var err error + if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { + utilruntime.HandleError(err) + return + } + klog.V(3).Infof("enqueue delete banp %s", key) + c.deleteBanpQueue.Add(obj) +} + +func (c *Controller) enqueueUpdateBanp(oldObj, newObj interface{}) { + oldBanp := oldObj.(*v1alpha1.BaselineAdminNetworkPolicy) + newBanp := newObj.(*v1alpha1.BaselineAdminNetworkPolicy) + + // All the acls should be recreated with the following situations + if len(oldBanp.Spec.Ingress) != len(newBanp.Spec.Ingress) || len(oldBanp.Spec.Egress) != len(newBanp.Spec.Egress) { + c.addBanpQueue.Add(newBanp.Name) + return + } + + // Acls should be updated when action or ports of ingress/egress rule has been changed + for index, rule := range newBanp.Spec.Ingress { + oldRule := oldBanp.Spec.Ingress[index] + if oldRule.Action != rule.Action || !reflect.DeepEqual(oldRule.Ports, rule.Ports) { + c.addBanpQueue.Add(newBanp.Name) + return + } + } + + for index, rule := range newBanp.Spec.Egress { + oldRule := oldBanp.Spec.Egress[index] + if oldRule.Action != rule.Action || !reflect.DeepEqual(oldRule.Ports, rule.Ports) { + c.addBanpQueue.Add(newBanp.Name) + return + } + } + klog.V(3).Infof("enqueue update banp %s", newBanp.Name) + + // The remaining changes do not affect the acls. The port-group or address-set should be updated. + // The port-group for anp should be updated + if !reflect.DeepEqual(oldBanp.Spec.Subject, newBanp.Spec.Subject) { + c.updateBanpQueue.Add(ChangedDelta{key: newBanp.Name, field: ChangedSubject}) + } + + // Rule name or peer selector in ingress/egress rule has changed, the corresponding address-set need be updated + ruleChanged := false + var changedIngressRuleNames, changedEgressRuleNames [util.AnpMaxRules]ChangedName + + for index, rule := range newBanp.Spec.Ingress { + oldRule := oldBanp.Spec.Ingress[index] + if oldRule.Name != rule.Name { + changedIngressRuleNames[index] = ChangedName{oldRuleName: oldRule.Name, curRuleName: rule.Name} + ruleChanged = true + } + if !reflect.DeepEqual(oldRule.From, rule.From) { + changedIngressRuleNames[index] = ChangedName{curRuleName: rule.Name} + ruleChanged = true + } + } + if ruleChanged { + c.updateBanpQueue.Add(ChangedDelta{key: newBanp.Name, ruleNames: changedIngressRuleNames, field: ChangedIngressRule}) + } + + ruleChanged = false + for index, rule := range newBanp.Spec.Egress { + oldRule := oldBanp.Spec.Egress[index] + if oldRule.Name != rule.Name { + changedEgressRuleNames[index] = ChangedName{oldRuleName: oldRule.Name, curRuleName: rule.Name} + ruleChanged = true + } + if !reflect.DeepEqual(oldRule.To, rule.To) { + changedEgressRuleNames[index] = ChangedName{curRuleName: rule.Name} + ruleChanged = true + } + } + if ruleChanged { + c.updateBanpQueue.Add(ChangedDelta{key: newBanp.Name, ruleNames: changedEgressRuleNames, field: ChangedEgressRule}) + } +} + +func (c *Controller) runAddBanpWorker() { + for c.processNextAddBanpWorkItem() { + } +} + +func (c *Controller) runUpdateBanpWorker() { + for c.processNextUpdateBanpWorkItem() { + } +} + +func (c *Controller) runDeleteBanpWorker() { + for c.processNextDeleteBanpWorkItem() { + } +} + +func (c *Controller) processNextAddBanpWorkItem() bool { + obj, shutdown := c.addBanpQueue.Get() + if shutdown { + return false + } + now := time.Now() + + err := func(obj interface{}) error { + defer c.addBanpQueue.Done(obj) + var key string + var ok bool + if key, ok = obj.(string); !ok { + c.addBanpQueue.Forget(obj) + utilruntime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj)) + return nil + } + if err := c.handleAddBanp(key); err != nil { + c.addBanpQueue.AddRateLimited(key) + return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error()) + } + last := time.Since(now) + klog.Infof("take %d ms to handle add banp %s", last.Milliseconds(), key) + c.addBanpQueue.Forget(obj) + return nil + }(obj) + if err != nil { + utilruntime.HandleError(err) + return true + } + return true +} + +func (c *Controller) processNextUpdateBanpWorkItem() bool { + obj, shutdown := c.updateBanpQueue.Get() + if shutdown { + return false + } + + err := func(obj interface{}) error { + defer c.updateBanpQueue.Done(obj) + var key ChangedDelta + var ok bool + if key, ok = obj.(ChangedDelta); !ok { + c.updateBanpQueue.Forget(obj) + utilruntime.HandleError(fmt.Errorf("expected ChangedDelta in workqueue but got %#v", obj)) + return nil + } + if err := c.handleUpdateBanp(key); err != nil { + c.updateBanpQueue.AddRateLimited(key) + return fmt.Errorf("error syncing banp %s: %w, requeuing", key.key, err) + } + c.updateBanpQueue.Forget(obj) + return nil + }(obj) + if err != nil { + utilruntime.HandleError(err) + return true + } + return true +} + +func (c *Controller) processNextDeleteBanpWorkItem() bool { + obj, shutdown := c.deleteBanpQueue.Get() + if shutdown { + return false + } + + err := func(obj interface{}) error { + defer c.deleteBanpQueue.Done(obj) + var banp *v1alpha1.BaselineAdminNetworkPolicy + var ok bool + if banp, ok = obj.(*v1alpha1.BaselineAdminNetworkPolicy); !ok { + c.deleteBanpQueue.Forget(obj) + utilruntime.HandleError(fmt.Errorf("expected banp object in workqueue but got %#v", obj)) + return nil + } + if err := c.handleDeleteBanp(banp); err != nil { + c.deleteBanpQueue.AddRateLimited(obj) + return fmt.Errorf("error syncing banp '%s': %s, requeuing", banp.Name, err.Error()) + } + c.deleteBanpQueue.Forget(obj) + return nil + }(obj) + if err != nil { + utilruntime.HandleError(err) + return true + } + return true +} + +func (c *Controller) handleAddBanp(key string) (err error) { + // Only one banp with default name can be created in cluster, no need to check + c.banpKeyMutex.LockKey(key) + defer func() { _ = c.banpKeyMutex.UnlockKey(key) }() + + cachedBanp, err := c.banpsLister.Get(key) + if err != nil { + if k8serrors.IsNotFound(err) { + return nil + } + klog.Error(err) + return err + } + klog.Infof("handle add banp %s", cachedBanp.Name) + banp := cachedBanp.DeepCopy() + + banpName := getAnpName(banp.Name) + + // ovn portGroup/addressSet doesn't support name with '-', so we replace '-' by '.'. + pgName := strings.ReplaceAll(banpName, "-", ".") + if err = c.OVNNbClient.CreatePortGroup(pgName, map[string]string{baselineAdminNetworkPolicyKey: banpName}); err != nil { + klog.Errorf("failed to create port group for banp %s: %v", key, err) + return err + } + + ports, err := c.fetchSelectedPods(&banp.Spec.Subject) + if err != nil { + klog.Errorf("failed to fetch ports belongs to banp %s: %v", key, err) + return err + } + + if err = c.OVNNbClient.PortGroupSetPorts(pgName, ports); err != nil { + klog.Errorf("failed to set ports %v to port group %s: %v", ports, pgName, err) + return err + } + + ingressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "to-lport", nil) + if err != nil { + klog.Errorf("failed to generate clear operations for banp %s ingress acls: %v", key, err) + return err + } + + curIngressAddrSet, curEgressAddrSet, err := c.getCurrentAddrSetByName(banpName, true) + if err != nil { + klog.Errorf("failed to list address sets for banp %s: %v", key, err) + return err + } + desiredIngressAddrSet := strset.NewWithSize(len(banp.Spec.Ingress) * 2) + desiredEgressAddrSet := strset.NewWithSize(len(banp.Spec.Egress) * 2) + + // create ingress acl + for index, banpr := range banp.Spec.Ingress { + // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different + ingressAsV4Name, ingressAsV6Name := getAnpAddressSetName(pgName, banpr.Name, index, true) + desiredIngressAddrSet.Add(ingressAsV4Name, ingressAsV6Name) + + var v4Addrs, v4Addr, v6Addrs, v6Addr []string + // This field must be defined and contain at least one item. + for _, anprpeer := range banpr.From { + if v4Addr, v6Addr, err = c.fetchIngressSelectedAddresses(&anprpeer); err != nil { + klog.Errorf("failed to fetch admin network policy selected addresses, %v", err) + return err + } + v4Addrs = append(v4Addrs, v4Addr...) + v6Addrs = append(v6Addrs, v6Addr...) + } + klog.Infof("Banp Ingress Rule %s, selected v4 address %v, v6 address %v", banpr.Name, v4Addrs, v6Addrs) + + if err = c.createAsForAnpRule(banpName, banpr.Name, "ingress", ingressAsV4Name, v4Addrs, true); err != nil { + klog.Error(err) + return err + } + if err = c.createAsForAnpRule(banpName, banpr.Name, "ingress", ingressAsV6Name, v6Addrs, true); err != nil { + klog.Error(err) + return err + } + + // use 1700-1800 for banp acl priority + aclPriority := util.BanpACLMaxPriority - index + aclAction := convertAction("", banpr.Action) + rulePorts := []v1alpha1.AdminNetworkPolicyPort{} + if banpr.Ports != nil { + rulePorts = *banpr.Ports + } + + if len(v4Addrs) != 0 { + ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, ingressAsV4Name, kubeovnv1.ProtocolIPv4, aclPriority, aclAction, rulePorts, true, true) + if err != nil { + klog.Errorf("failed to add v4 ingress acls for banp %s: %v", key, err) + return err + } + ingressACLOps = append(ingressACLOps, ops...) + } + + if len(v6Addrs) != 0 { + ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, ingressAsV6Name, kubeovnv1.ProtocolIPv6, aclPriority, aclAction, rulePorts, true, true) + if err != nil { + klog.Errorf("failed to add v6 ingress acls for banp %s: %v", key, err) + return err + } + ingressACLOps = append(ingressACLOps, ops...) + } + } + + if err := c.OVNNbClient.Transact("add-ingress-acls", ingressACLOps); err != nil { + return fmt.Errorf("failed to add ingress acls for banp %s: %w", key, err) + } + if err := c.deleteUnusedAddrSetForAnp(curIngressAddrSet, desiredIngressAddrSet); err != nil { + return fmt.Errorf("failed to delete unused ingress address set for banp %s: %w", key, err) + } + + egressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "from-lport", nil) + if err != nil { + klog.Errorf("failed to generate clear operations for banp %s egress acls: %v", key, err) + return err + } + // create egress acl + for index, banpr := range banp.Spec.Egress { + // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different + egressAsV4Name, egressAsV6Name := getAnpAddressSetName(pgName, banpr.Name, index, false) + desiredEgressAddrSet.Add(egressAsV4Name, egressAsV6Name) + + var v4Addrs, v4Addr, v6Addrs, v6Addr []string + // This field must be defined and contain at least one item. + for _, anprpeer := range banpr.To { + if v4Addr, v6Addr, err = c.fetchEgressSelectedAddresses(&anprpeer); err != nil { + klog.Errorf("failed to fetch admin network policy selected addresses, %v", err) + return err + } + v4Addrs = append(v4Addrs, v4Addr...) + v6Addrs = append(v6Addrs, v6Addr...) + } + klog.Infof("Banp Egress Rule %s, selected v4 address %v, v6 address %v", banpr.Name, v4Addrs, v6Addrs) + + if err = c.createAsForAnpRule(banpName, banpr.Name, "egress", egressAsV4Name, v4Addrs, true); err != nil { + klog.Error(err) + return err + } + if err = c.createAsForAnpRule(banpName, banpr.Name, "egress", egressAsV6Name, v6Addrs, true); err != nil { + klog.Error(err) + return err + } + + aclPriority := util.BanpACLMaxPriority - index + aclAction := convertAction("", banpr.Action) + rulePorts := []v1alpha1.AdminNetworkPolicyPort{} + if banpr.Ports != nil { + rulePorts = *banpr.Ports + } + + if len(v4Addrs) != 0 { + ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, egressAsV4Name, kubeovnv1.ProtocolIPv4, aclPriority, aclAction, rulePorts, false, true) + if err != nil { + klog.Errorf("failed to add v4 egress acls for banp %s: %v", key, err) + return err + } + egressACLOps = append(egressACLOps, ops...) + } + + if len(v6Addrs) != 0 { + ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, egressAsV6Name, kubeovnv1.ProtocolIPv6, aclPriority, aclAction, rulePorts, false, true) + if err != nil { + klog.Errorf("failed to add v6 egress acls for banp %s: %v", key, err) + return err + } + egressACLOps = append(egressACLOps, ops...) + } + } + + if err := c.OVNNbClient.Transact("add-egress-acls", egressACLOps); err != nil { + return fmt.Errorf("failed to add egress acls for banp %s: %w", key, err) + } + if err := c.deleteUnusedAddrSetForAnp(curEgressAddrSet, desiredEgressAddrSet); err != nil { + return fmt.Errorf("failed to delete unused egress address set for banp %s: %w", key, err) + } + + return nil +} + +func (c *Controller) handleDeleteBanp(banp *v1alpha1.BaselineAdminNetworkPolicy) error { + c.banpKeyMutex.LockKey(banp.Name) + defer func() { _ = c.banpKeyMutex.UnlockKey(banp.Name) }() + + klog.Infof("handle delete banp %s", banp.Name) + banpName := getAnpName(banp.Name) + + // ACLs releated to port_group will be deleted automatically when port_group is deleted + pgName := strings.ReplaceAll(banpName, "-", ".") + if err := c.OVNNbClient.DeletePortGroup(pgName); err != nil { + klog.Errorf("failed to delete port group for banp %s: %v", banpName, err) + } + + if err := c.OVNNbClient.DeleteAddressSets(map[string]string{ + baselineAdminNetworkPolicyKey: fmt.Sprintf("%s/%s", banpName, "ingress"), + }); err != nil { + klog.Errorf("failed to delete ingress address set for banp %s: %v", banpName, err) + return err + } + + if err := c.OVNNbClient.DeleteAddressSets(map[string]string{ + baselineAdminNetworkPolicyKey: fmt.Sprintf("%s/%s", banpName, "egress"), + }); err != nil { + klog.Errorf("failed to delete egress address set for banp %s: %v", banpName, err) + return err + } + + return nil +} + +func (c *Controller) handleUpdateBanp(changed ChangedDelta) error { + // Only handle updates that do not affect acls. + c.banpKeyMutex.LockKey(changed.key) + defer func() { _ = c.banpKeyMutex.UnlockKey(changed.key) }() + + cachedBanp, err := c.banpsLister.Get(changed.key) + if err != nil { + if k8serrors.IsNotFound(err) { + return nil + } + klog.Error(err) + return err + } + desiredBanp := cachedBanp.DeepCopy() + klog.Infof("handle update banp %s", desiredBanp.Name) + + banpName := getAnpName(desiredBanp.Name) + pgName := strings.ReplaceAll(banpName, "-", ".") + + // The port-group for anp should be updated + if changed.field == ChangedSubject { + // The port-group must exist when update anp, this check should never be matched. + if ok, err := c.OVNNbClient.PortGroupExists(pgName); !ok || err != nil { + klog.Errorf("port-group for banp %s does not exist when update banp", desiredBanp.Name) + return err + } + + ports, err := c.fetchSelectedPods(&desiredBanp.Spec.Subject) + if err != nil { + klog.Errorf("failed to fetch ports belongs to banp %s: %v", desiredBanp.Name, err) + return err + } + + if err = c.OVNNbClient.PortGroupSetPorts(pgName, ports); err != nil { + klog.Errorf("failed to set ports %v to port group %s: %v", ports, pgName, err) + return err + } + } + + // Peer selector in ingress/egress rule has changed, so the corresponding address-set need be updated + if changed.field == ChangedIngressRule { + for index, rule := range desiredBanp.Spec.Ingress { + // Make sure the rule is changed and go on update + if rule.Name == changed.ruleNames[index].curRuleName { + if err := c.setAddrSetForAnpRule(banpName, pgName, rule.Name, index, rule.From, []v1alpha1.AdminNetworkPolicyEgressPeer{}, true, true); err != nil { + klog.Errorf("failed to set ingress address-set for anp rule %s/%s, %v", banpName, rule.Name, err) + return err + } + + if changed.ruleNames[index].oldRuleName != "" { + oldRuleName := changed.ruleNames[index].oldRuleName + oldAsV4Name, oldAsV6Name := getAnpAddressSetName(pgName, oldRuleName, index, true) + + if err := c.OVNNbClient.DeleteAddressSet(oldAsV4Name); err != nil { + klog.Errorf("failed to delete address set %s, %v", oldAsV4Name, err) + // just record error log + } + if err := c.OVNNbClient.DeleteAddressSet(oldAsV6Name); err != nil { + klog.Errorf("failed to delete address set %s, %v", oldAsV6Name, err) + } + } + } + } + } + + if changed.field == ChangedEgressRule { + for index, rule := range desiredBanp.Spec.Egress { + // Make sure the rule is changed and go on update + if rule.Name == changed.ruleNames[index].curRuleName { + if err := c.setAddrSetForAnpRule(banpName, pgName, rule.Name, index, []v1alpha1.AdminNetworkPolicyIngressPeer{}, rule.To, false, true); err != nil { + klog.Errorf("failed to set egress address-set for banp rule %s/%s, %v", banpName, rule.Name, err) + return err + } + + if changed.ruleNames[index].oldRuleName != "" { + oldRuleName := changed.ruleNames[index].oldRuleName + oldAsV4Name, oldAsV6Name := getAnpAddressSetName(pgName, oldRuleName, index, false) + + if err := c.OVNNbClient.DeleteAddressSet(oldAsV4Name); err != nil { + klog.Errorf("failed to delete address set %s, %v", oldAsV4Name, err) + // just record error log + } + if err := c.OVNNbClient.DeleteAddressSet(oldAsV6Name); err != nil { + klog.Errorf("failed to delete address set %s, %v", oldAsV6Name, err) + } + } + } + } + } + return nil +} diff --git a/pkg/controller/client_go_adapter.go b/pkg/controller/client_go_adapter.go deleted file mode 100644 index 7211db793a87..000000000000 --- a/pkg/controller/client_go_adapter.go +++ /dev/null @@ -1,210 +0,0 @@ -/* -Copyright 2018 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. -*/ - -// This file comes from sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go - -package controller - -import ( - "context" - "net/url" - "strings" - "time" - - "github.com/prometheus/client_golang/prometheus" - reflectormetrics "k8s.io/client-go/tools/cache" - clientmetrics "k8s.io/client-go/tools/metrics" -) - -// this file contains setup logic to initialize the myriad of places -// that client-go registers metrics. we copy the names and formats -// from Kubernetes so that we match the core controllers. - -var ( - // client metrics - - requestLatency = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Name: "rest_client_request_latency_seconds", - Help: "Request latency in seconds. Broken down by verb and URL.", - Buckets: prometheus.ExponentialBuckets(0.001, 2, 10), - }, - []string{"verb", "url"}, - ) - - requestResult = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "rest_client_requests_total", - Help: "Number of HTTP requests, partitioned by status code, method, and host.", - }, - []string{"code", "method", "host"}, - ) - - // reflector metrics - - // TODO(directxman12): update these to be histograms once the metrics overhaul KEP - // PRs start landing. - - reflectorSubsystem = "reflector" - - listsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: reflectorSubsystem, - Name: "lists_total", - Help: "Total number of API lists done by the reflectors", - }, []string{"name"}) - - listsDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: reflectorSubsystem, - Name: "list_duration_seconds", - Help: "How long an API list takes to return and decode for the reflectors", - }, []string{"name"}) - - itemsPerList = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: reflectorSubsystem, - Name: "items_per_list", - Help: "How many items an API list returns to the reflectors", - }, []string{"name"}) - - watchesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: reflectorSubsystem, - Name: "watches_total", - Help: "Total number of API watches done by the reflectors", - }, []string{"name"}) - - shortWatchesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: reflectorSubsystem, - Name: "short_watches_total", - Help: "Total number of short API watches done by the reflectors", - }, []string{"name"}) - - watchDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: reflectorSubsystem, - Name: "watch_duration_seconds", - Help: "How long an API watch takes to return and decode for the reflectors", - }, []string{"name"}) - - itemsPerWatch = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: reflectorSubsystem, - Name: "items_per_watch", - Help: "How many items an API watch returns to the reflectors", - }, []string{"name"}) - - lastResourceVersion = prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Subsystem: reflectorSubsystem, - Name: "last_resource_version", - Help: "Last resource version seen for the reflectors", - }, []string{"name"}) -) - -func InitClientGoMetrics() { - registerClientMetrics() - registerReflectorMetrics() -} - -// registerClientMetrics sets up the client latency metrics from client-go -func registerClientMetrics() { - // register the metrics with our registry - prometheus.MustRegister(requestLatency) - prometheus.MustRegister(requestResult) - - // register the metrics with client-go - opts := clientmetrics.RegisterOpts{ - RequestLatency: clientmetrics.LatencyMetric(&latencyAdapter{metric: requestLatency}), - RequestResult: clientmetrics.ResultMetric(&resultAdapter{metric: requestResult}), - } - clientmetrics.Register(opts) -} - -// registerReflectorMetrics sets up reflector (reconcile) loop metrics -func registerReflectorMetrics() { - prometheus.MustRegister(listsTotal) - prometheus.MustRegister(listsDuration) - prometheus.MustRegister(itemsPerList) - prometheus.MustRegister(watchesTotal) - prometheus.MustRegister(shortWatchesTotal) - prometheus.MustRegister(watchDuration) - prometheus.MustRegister(itemsPerWatch) - prometheus.MustRegister(lastResourceVersion) - - reflectormetrics.SetReflectorMetricsProvider(reflectorMetricsProvider{}) -} - -// this section contains adapters, implementations, and other sundry organic, artisanally -// hand-crafted syntax trees required to convince client-go that it actually wants to let -// someone use its metrics. - -// Client metrics adapters (method #1 for client-go metrics), -// copied (more-or-less directly) from k8s.io/kubernetes setup code -// (which isn't anywhere in an easily-importable place). - -type latencyAdapter struct { - metric *prometheus.HistogramVec -} - -func (l *latencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) { - url := u.String() - last := strings.LastIndex(url, "/") - if last != -1 { - url = url[:last] - } - l.metric.WithLabelValues(verb, url).Observe(latency.Seconds()) -} - -type resultAdapter struct { - metric *prometheus.CounterVec -} - -func (r *resultAdapter) Increment(_ context.Context, code, method, host string) { - r.metric.WithLabelValues(code, method, host).Inc() -} - -// Reflector metrics provider (method #2 for client-go metrics), -// copied (more-or-less directly) from k8s.io/kubernetes setup code -// (which isn't anywhere in an easily-importable place). - -type reflectorMetricsProvider struct{} - -func (reflectorMetricsProvider) NewListsMetric(name string) reflectormetrics.CounterMetric { - return listsTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewListDurationMetric(name string) reflectormetrics.SummaryMetric { - return listsDuration.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewItemsInListMetric(name string) reflectormetrics.SummaryMetric { - return itemsPerList.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewWatchesMetric(name string) reflectormetrics.CounterMetric { - return watchesTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewShortWatchesMetric(name string) reflectormetrics.CounterMetric { - return shortWatchesTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewWatchDurationMetric(name string) reflectormetrics.SummaryMetric { - return watchDuration.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewItemsInWatchMetric(name string) reflectormetrics.SummaryMetric { - return itemsPerWatch.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewLastResourceVersionMetric(name string) reflectormetrics.GaugeMetric { - return lastResourceVersion.WithLabelValues(name) -} diff --git a/pkg/controller/config.go b/pkg/controller/config.go index 7dec031a5b82..1c625d55b24e 100644 --- a/pkg/controller/config.go +++ b/pkg/controller/config.go @@ -1,6 +1,7 @@ package controller import ( + "errors" "flag" "fmt" "os" @@ -14,6 +15,7 @@ import ( "k8s.io/client-go/tools/clientcmd" "k8s.io/klog/v2" "kubevirt.io/client-go/kubecli" + anpclientset "sigs.k8s.io/network-policy-api/pkg/client/clientset/versioned" clientset "github.com/kubeovn/kube-ovn/pkg/client/clientset/versioned" "github.com/kubeovn/kube-ovn/pkg/util" @@ -21,7 +23,6 @@ import ( // Configuration is the controller conf type Configuration struct { - BindAddress string OvnNbAddr string OvnSbAddr string OvnTimeout int @@ -34,6 +35,7 @@ type Configuration struct { KubeClient kubernetes.Interface KubeOvnClient clientset.Interface + AnpClient anpclientset.Interface AttachNetClient attachnetclientset.Interface KubevirtClient kubecli.KubevirtClient @@ -68,8 +70,9 @@ type Configuration struct { PodNicType string WorkerNum int - PprofPort int + PprofPort int32 EnablePprof bool + SecureServing bool NodePgProbeTime int NetworkType string @@ -89,6 +92,7 @@ type Configuration struct { EnableKeepVMIP bool EnableLbSvc bool EnableMetrics bool + EnableANP bool ExternalGatewaySwitch string ExternalGatewayConfigNS string @@ -143,7 +147,8 @@ func ParseFlags() (*Configuration, error) { argWorkerNum = pflag.Int("worker-num", 3, "The parallelism of each worker") argEnablePprof = pflag.Bool("enable-pprof", false, "Enable pprof") - argPprofPort = pflag.Int("pprof-port", 10660, "The port to get profiling data") + argPprofPort = pflag.Int32("pprof-port", 10660, "The port to get profiling data") + argSecureServing = pflag.Bool("secure-serving", false, "Enable secure serving") argNodePgProbeTime = pflag.Int("nodepg-probe-time", 1, "The probe interval for node port-group, the unit is minute") argNetworkType = pflag.String("network-type", util.NetworkTypeGeneve, "The ovn network type") @@ -163,6 +168,7 @@ func ParseFlags() (*Configuration, error) { argKeepVMIP = pflag.Bool("keep-vm-ip", true, "Whether to keep ip for kubevirt pod when pod is rebuild") argEnableLbSvc = pflag.Bool("enable-lb-svc", false, "Whether to support loadbalancer service") argEnableMetrics = pflag.Bool("enable-metrics", true, "Whether to support metrics query") + argEnableANP = pflag.Bool("enable-anp", false, "Enable support for admin network policy and baseline admin network policy") argExternalGatewayConfigNS = pflag.String("external-gateway-config-ns", "kube-system", "The namespace of configmap external-gateway-config, default: kube-system") argExternalGatewaySwitch = pflag.String("external-gateway-switch", "external", "The name of the external gateway switch which is a ovs bridge to provide external network, default: external") @@ -226,6 +232,7 @@ func ParseFlags() (*Configuration, error) { WorkerNum: *argWorkerNum, EnablePprof: *argEnablePprof, PprofPort: *argPprofPort, + SecureServing: *argSecureServing, NetworkType: *argNetworkType, DefaultVlanID: *argDefaultVlanID, LsDnatModDlDst: *argLsDnatModDlDst, @@ -255,10 +262,11 @@ func ParseFlags() (*Configuration, error) { BfdMinTx: *argBfdMinTx, BfdMinRx: *argBfdMinRx, BfdDetectMult: *argBfdDetectMult, + EnableANP: *argEnableANP, } if config.NetworkType == util.NetworkTypeVlan && config.DefaultHostInterface == "" { - return nil, fmt.Errorf("no host nic for vlan") + return nil, errors.New("no host nic for vlan") } if config.DefaultGateway == "" { @@ -295,7 +303,7 @@ func ParseFlags() (*Configuration, error) { if err := util.CheckSystemCIDR([]string{config.NodeSwitchCIDR, config.DefaultCIDR, config.ServiceClusterIPRange}); err != nil { klog.Error(err) - return nil, fmt.Errorf("check system cidr failed, %v", err) + return nil, fmt.Errorf("check system cidr failed, %w", err) } for _, ip := range strings.Split(*argNodeLocalDNSIP, ",") { @@ -350,6 +358,13 @@ func (config *Configuration) initKubeClient() error { } config.KubevirtClient = virtClient + AnpClient, err := anpclientset.NewForConfig(cfg) + if err != nil { + klog.Errorf("init admin network policy client failed %v", err) + return err + } + config.AnpClient = AnpClient + kubeOvnClient, err := clientset.NewForConfig(cfg) if err != nil { klog.Errorf("init kubeovn client failed %v", err) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index e3bafdef480f..ab81820b6170 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -25,7 +25,9 @@ import ( "k8s.io/klog/v2" "k8s.io/utils/keymutex" - kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" + anpinformer "sigs.k8s.io/network-policy-api/pkg/client/informers/externalversions" + anplister "sigs.k8s.io/network-policy-api/pkg/client/listers/apis/v1alpha1" + kubeovninformer "github.com/kubeovn/kube-ovn/pkg/client/informers/externalversions" kubeovnlister "github.com/kubeovn/kube-ovn/pkg/client/listers/kubeovn/v1" ovnipam "github.com/kubeovn/kube-ovn/pkg/ipam" @@ -36,14 +38,16 @@ import ( const controllerAgentName = "kube-ovn-controller" const ( - logicalSwitchKey = "ls" - logicalRouterKey = "lr" - portGroupKey = "pg" - networkPolicyKey = "np" - sgKey = "sg" - associatedSgKeyPrefix = "associated_sg_" - sgsKey = "security_groups" - u2oKey = "u2o" + logicalSwitchKey = "ls" + logicalRouterKey = "lr" + portGroupKey = "pg" + networkPolicyKey = "np" + sgKey = "sg" + associatedSgKeyPrefix = "associated_sg_" + sgsKey = "security_groups" + u2oKey = "u2o" + adminNetworkPolicyKey = "anp" + baselineAdminNetworkPolicyKey = "banp" ) // Controller is kube-ovn main controller that watch ns/pod/node/svc/ep and operate ovn @@ -52,9 +56,11 @@ type Controller struct { vpcs *sync.Map // subnetVpcMap *sync.Map - podSubnetMap *sync.Map - ipam *ovnipam.IPAM - namedPort *NamedPort + podSubnetMap *sync.Map + ipam *ovnipam.IPAM + namedPort *NamedPort + anpPrioNameMap map[int32]string + anpNamePrioMap map[string]int32 OVNNbClient ovs.NbClient OVNSbClient ovs.SbClient @@ -235,15 +241,29 @@ type Controller struct { configMapsLister v1.ConfigMapLister configMapsSynced cache.InformerSynced + anpsLister anplister.AdminNetworkPolicyLister + anpsSynced cache.InformerSynced + addAnpQueue workqueue.RateLimitingInterface + updateAnpQueue workqueue.RateLimitingInterface + deleteAnpQueue workqueue.RateLimitingInterface + anpKeyMutex keymutex.KeyMutex + + banpsLister anplister.BaselineAdminNetworkPolicyLister + banpsSynced cache.InformerSynced + addBanpQueue workqueue.RateLimitingInterface + updateBanpQueue workqueue.RateLimitingInterface + deleteBanpQueue workqueue.RateLimitingInterface + banpKeyMutex keymutex.KeyMutex + recorder record.EventRecorder informerFactory kubeinformers.SharedInformerFactory cmInformerFactory kubeinformers.SharedInformerFactory kubeovnInformerFactory kubeovninformer.SharedInformerFactory + anpInformerFactory anpinformer.SharedInformerFactory } // Run creates and runs a new ovn controller func Run(ctx context.Context, config *Configuration) { - utilruntime.Must(kubeovnv1.AddToScheme(scheme.Scheme)) klog.V(4).Info("Creating event broadcaster") eventBroadcaster := record.NewBroadcasterWithCorrelatorOptions(record.CorrelatorOptions{BurstSize: 100}) eventBroadcaster.StartLogging(klog.Infof) @@ -266,6 +286,10 @@ func Run(ctx context.Context, config *Configuration) { kubeovninformer.WithTweakListOptions(func(listOption *metav1.ListOptions) { listOption.AllowWatchBookmarks = true })) + anpInformerFactory := anpinformer.NewSharedInformerFactoryWithOptions(config.AnpClient, 0, + anpinformer.WithTweakListOptions(func(listOption *metav1.ListOptions) { + listOption.AllowWatchBookmarks = true + })) vpcInformer := kubeovnInformerFactory.Kubeovn().V1().Vpcs() vpcNatGatewayInformer := kubeovnInformerFactory.Kubeovn().V1().VpcNatGateways() @@ -294,6 +318,8 @@ func Run(ctx context.Context, config *Configuration) { ovnFipInformer := kubeovnInformerFactory.Kubeovn().V1().OvnFips() ovnSnatRuleInformer := kubeovnInformerFactory.Kubeovn().V1().OvnSnatRules() ovnDnatRuleInformer := kubeovnInformerFactory.Kubeovn().V1().OvnDnatRules() + anpInformer := anpInformerFactory.Policy().V1alpha1().AdminNetworkPolicies() + banpInformer := anpInformerFactory.Policy().V1alpha1().BaselineAdminNetworkPolicies() numKeyLocks := runtime.NumCPU() * 2 if numKeyLocks < config.WorkerNum*2 { @@ -469,6 +495,7 @@ func Run(ctx context.Context, config *Configuration) { informerFactory: informerFactory, cmInformerFactory: cmInformerFactory, kubeovnInformerFactory: kubeovnInformerFactory, + anpInformerFactory: anpInformerFactory, } var err error @@ -508,6 +535,22 @@ func Run(ctx context.Context, config *Configuration) { controller.npKeyMutex = keymutex.NewHashed(numKeyLocks) } + if config.EnableANP { + controller.anpsLister = anpInformer.Lister() + controller.anpsSynced = anpInformer.Informer().HasSynced + controller.addAnpQueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "AddAnp") + controller.updateAnpQueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "UpdateAnp") + controller.deleteAnpQueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "DeleteAnp") + controller.anpKeyMutex = keymutex.NewHashed(numKeyLocks) + + controller.banpsLister = banpInformer.Lister() + controller.banpsSynced = banpInformer.Informer().HasSynced + controller.addBanpQueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "AddBanp") + controller.updateBanpQueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "UpdateBanp") + controller.deleteBanpQueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "DeleteBanp") + controller.banpKeyMutex = keymutex.NewHashed(numKeyLocks) + } + defer controller.shutdown() klog.Info("Starting OVN controller") @@ -515,6 +558,7 @@ func Run(ctx context.Context, config *Configuration) { controller.informerFactory.Start(ctx.Done()) controller.cmInformerFactory.Start(ctx.Done()) controller.kubeovnInformerFactory.Start(ctx.Done()) + controller.anpInformerFactory.Start(ctx.Done()) klog.Info("Waiting for informer caches to sync") cacheSyncs := []cache.InformerSynced{ @@ -532,6 +576,9 @@ func Run(ctx context.Context, config *Configuration) { if controller.config.EnableNP { cacheSyncs = append(cacheSyncs, controller.npsSynced) } + if controller.config.EnableANP { + cacheSyncs = append(cacheSyncs, controller.anpsSynced, controller.banpsSynced) + } if !cache.WaitForCacheSync(ctx.Done(), cacheSyncs...) { util.LogFatalAndExit(nil, "failed to wait for caches to sync") } @@ -739,6 +786,29 @@ func Run(ctx context.Context, config *Configuration) { } } + if config.EnableANP { + if _, err = anpInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: controller.enqueueAddAnp, + UpdateFunc: controller.enqueueUpdateAnp, + DeleteFunc: controller.enqueueDeleteAnp, + }); err != nil { + util.LogFatalAndExit(err, "failed to add admin network policy event handler") + } + + if _, err = banpInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: controller.enqueueAddBanp, + UpdateFunc: controller.enqueueUpdateBanp, + DeleteFunc: controller.enqueueDeleteBanp, + }); err != nil { + util.LogFatalAndExit(err, "failed to add baseline admin network policy event handler") + } + + if controller.anpPrioNameMap == nil { + controller.anpPrioNameMap = make(map[int32]string, 100) + controller.anpNamePrioMap = make(map[string]int32, 100) + } + } + controller.Run(ctx) } @@ -910,6 +980,16 @@ func (c *Controller) shutdown() { c.updateNpQueue.ShutDown() c.deleteNpQueue.ShutDown() } + if c.config.EnableANP { + c.addAnpQueue.ShutDown() + c.updateAnpQueue.ShutDown() + c.deleteAnpQueue.ShutDown() + + c.addBanpQueue.ShutDown() + c.updateBanpQueue.ShutDown() + c.deleteBanpQueue.ShutDown() + } + c.addOrUpdateSgQueue.ShutDown() c.delSgQueue.ShutDown() c.syncSgPortsQueue.ShutDown() @@ -1107,6 +1187,16 @@ func (c *Controller) startWorkers(ctx context.Context) { go wait.Until(c.runAddQoSPolicyWorker, time.Second, ctx.Done()) go wait.Until(c.runUpdateQoSPolicyWorker, time.Second, ctx.Done()) go wait.Until(c.runDelQoSPolicyWorker, time.Second, ctx.Done()) + + if c.config.EnableANP { + go wait.Until(c.runAddAnpWorker, time.Second, ctx.Done()) + go wait.Until(c.runUpdateAnpWorker, time.Second, ctx.Done()) + go wait.Until(c.runDeleteAnpWorker, time.Second, ctx.Done()) + + go wait.Until(c.runAddBanpWorker, time.Second, ctx.Done()) + go wait.Until(c.runUpdateBanpWorker, time.Second, ctx.Done()) + go wait.Until(c.runDeleteBanpWorker, time.Second, ctx.Done()) + } } func (c *Controller) allSubnetReady(subnets ...string) (bool, error) { @@ -1114,7 +1204,7 @@ func (c *Controller) allSubnetReady(subnets ...string) (bool, error) { exist, err := c.OVNNbClient.LogicalSwitchExists(lsName) if err != nil { klog.Error(err) - return false, fmt.Errorf("check logical switch %s exist: %v", lsName, err) + return false, fmt.Errorf("check logical switch %s exist: %w", lsName, err) } if !exist { diff --git a/pkg/controller/external_gw.go b/pkg/controller/external_gw.go index 32667597d6f1..e09d9cdd2bd2 100644 --- a/pkg/controller/external_gw.go +++ b/pkg/controller/external_gw.go @@ -2,6 +2,7 @@ package controller import ( "context" + "errors" "fmt" "reflect" "slices" @@ -254,7 +255,7 @@ func (c *Controller) getGatewayChassis(config map[string]string) ([]string, erro chassises = append(chassises, chassis.Name) } if len(chassises) == 0 { - err := fmt.Errorf("no available external gw chassis") + err := errors.New("no available external gw chassis") klog.Error(err) return nil, err } @@ -271,7 +272,7 @@ func (c *Controller) updateDefaultVpcExternal(enableExternal bool) error { if vpc.Spec.EnableExternal != enableExternal { vpc.Spec.EnableExternal = enableExternal if _, err := c.config.KubeOvnClient.KubeovnV1().Vpcs().Update(context.Background(), vpc, metav1.UpdateOptions{}); err != nil { - err := fmt.Errorf("failed to update vpc enable external %s, %v", vpc.Name, err) + err := fmt.Errorf("failed to update vpc enable external %s, %w", vpc.Name, err) klog.Error(err) return err } diff --git a/pkg/controller/gc.go b/pkg/controller/gc.go index 48a7fef99e22..c80e74d79b6e 100644 --- a/pkg/controller/gc.go +++ b/pkg/controller/gc.go @@ -33,6 +33,7 @@ func (c *Controller) gc() error { // The lsp gc is processed periodically by markAndCleanLSP, will not gc lsp when init c.gcLoadBalancer, c.gcPortGroup, + c.gcRoutePolicy, c.gcStaticRoute, c.gcVpcNatGateway, c.gcLogicalRouterPort, @@ -686,6 +687,45 @@ func (c *Controller) gcPortGroup() error { return nil } +func (c *Controller) gcRoutePolicy() error { + klog.Infof("start to gc route policy") + + policies, err := c.OVNNbClient.ListLogicalRouterPolicies(c.config.ClusterRouter, util.NorthGatewayRoutePolicyPriority, nil, true) + if err != nil { + klog.Errorf("failed to list route policy, %v", err) + return err + } + + podIPs := []string{} + pods, err := c.podsLister.List(labels.Everything()) + if err != nil { + klog.Errorf("failed to list pods, %v", err) + return err + } + for _, pod := range pods { + if pod.Annotations != nil && pod.Annotations[util.NorthGatewayAnnotation] != "" { + podIPs = append(podIPs, strings.Split(pod.Annotations[util.IPAddressAnnotation], ",")...) + } + } + + for _, policy := range policies { + parts := strings.Split(policy.Match, "==") + if len(parts) != 2 { + continue + } + srcIP := strings.TrimSpace(parts[1]) + if !slices.Contains(podIPs, srcIP) { + klog.Infof("gc route policy %s", policy.Match) + if err := c.OVNNbClient.DeleteLogicalRouterPolicy(c.config.ClusterRouter, policy.Priority, policy.Match); err != nil { + klog.Errorf("failed to delete route policy %s: %v", policy.Match, err) + return err + } + } + } + + return nil +} + func (c *Controller) gcStaticRoute() error { klog.Infof("start to gc static routes") routes, err := c.OVNNbClient.ListLogicalRouterStaticRoutes(c.config.ClusterRouter, nil, nil, "", nil) @@ -810,7 +850,7 @@ func (c *Controller) getVMLsps() []string { } for _, ns := range nss { - vms, err := c.config.KubevirtClient.VirtualMachine(ns.Name).List(context.Background(), &metav1.ListOptions{}) + vms, err := c.config.KubevirtClient.VirtualMachine(ns.Name).List(context.Background(), metav1.ListOptions{}) if err != nil { if !k8serrors.IsNotFound(err) { klog.Errorf("failed to list vm in namespace %s, %v", ns, err) diff --git a/pkg/controller/init.go b/pkg/controller/init.go index 3142471a20bf..4a85e6b22b25 100644 --- a/pkg/controller/init.go +++ b/pkg/controller/init.go @@ -141,7 +141,7 @@ func (c *Controller) initDefaultLogicalSwitch() error { if c.config.NetworkType == util.NetworkTypeVlan { defaultSubnet.Spec.Vlan = c.config.DefaultVlanName if c.config.DefaultLogicalGateway && c.config.DefaultU2OInterconnection { - err = fmt.Errorf("logicalGateway and u2oInterconnection can't be opened at the same time") + err = errors.New("logicalGateway and u2oInterconnection can't be opened at the same time") klog.Error(err) return err } @@ -571,7 +571,7 @@ func (c *Controller) initDefaultVlan() error { } if c.config.DefaultVlanID < 0 || c.config.DefaultVlanID > 4095 { - return fmt.Errorf("the default vlan id is not between 1-4095") + return errors.New("the default vlan id is not between 1-4095") } defaultVlan := kubeovnv1.Vlan{ diff --git a/pkg/controller/ip.go b/pkg/controller/ip.go index e689823cca36..d55171c7eb88 100644 --- a/pkg/controller/ip.go +++ b/pkg/controller/ip.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" "net" "reflect" @@ -217,7 +218,7 @@ func (c *Controller) handleAddReservedIP(key string) error { } klog.V(3).Infof("handle add reserved ip %s", ip.Name) if ip.Spec.Subnet == "" { - err := fmt.Errorf("subnet parameter cannot be empty") + err := errors.New("subnet parameter cannot be empty") klog.Error(err) return err } @@ -229,7 +230,7 @@ func (c *Controller) handleAddReservedIP(key string) error { subnet, err := c.subnetsLister.Get(ip.Spec.Subnet) if err != nil { - err = fmt.Errorf("failed to get subnet %s: %v", ip.Spec.Subnet, err) + err = fmt.Errorf("failed to get subnet %s: %w", ip.Spec.Subnet, err) klog.Error(err) return err } @@ -255,13 +256,13 @@ func (c *Controller) handleAddReservedIP(key string) error { v4IP, v6IP, mac, err := c.ipAcquireAddress(ip, subnet) if err != nil { - err = fmt.Errorf("failed to acquire ip address %v", err) + err = fmt.Errorf("failed to acquire ip address %w", err) klog.Error(err) return err } ipStr := util.GetStringIP(v4IP, v6IP) if err := c.createOrUpdateIPCR(ip.Name, ip.Spec.PodName, ipStr, mac, subnet.Name, ip.Spec.Namespace, ip.Spec.NodeName, ip.Spec.PodType); err != nil { - err = fmt.Errorf("failed to create ips CR %s.%s: %v", ip.Spec.PodName, ip.Spec.Namespace, err) + err = fmt.Errorf("failed to create ips CR %s.%s: %w", ip.Spec.PodName, ip.Spec.Namespace, err) klog.Error(err) return err } @@ -485,7 +486,7 @@ func (c *Controller) createOrUpdateIPCR(ipCRName, podName, ip, mac, subnetName, ipCR, err = c.ipsLister.Get(ipName) if err != nil { if !k8serrors.IsNotFound(err) { - err := fmt.Errorf("failed to get ip CR %s: %v", ipName, err) + err := fmt.Errorf("failed to get ip CR %s: %w", ipName, err) klog.Error(err) return err } @@ -521,7 +522,7 @@ func (c *Controller) createOrUpdateIPCR(ipCRName, podName, ip, mac, subnetName, }, }, metav1.CreateOptions{}) if err != nil { - errMsg := fmt.Errorf("failed to create ip CR %s: %v", ipName, err) + errMsg := fmt.Errorf("failed to create ip CR %s: %w", ipName, err) klog.Error(errMsg) return errMsg } @@ -555,11 +556,10 @@ func (c *Controller) createOrUpdateIPCR(ipCRName, podName, ip, mac, subnetName, ipCR, err = c.config.KubeOvnClient.KubeovnV1().IPs().Update(context.Background(), newIPCR, metav1.UpdateOptions{}) if err != nil { - err := fmt.Errorf("failed to update ip CR %s: %v", ipCRName, err) + err := fmt.Errorf("failed to update ip CR %s: %w", ipCRName, err) klog.Error(err) return err } - } if err := c.handleAddIPFinalizer(ipCR); err != nil { klog.Errorf("failed to handle add ip finalizer %v", err) @@ -590,14 +590,14 @@ func (c *Controller) ipAcquireAddress(ip *kubeovnv1.IP, subnet *kubeovnv1.Subnet if err == nil { return v4IP, v6IP, mac, err } - err = fmt.Errorf("failed to get random address for ip %s, %v", ip.Name, err) + err = fmt.Errorf("failed to get random address for ip %s, %w", ip.Name, err) } else { // static address v4IP, v6IP, mac, err = c.acquireStaticAddress(key, portName, ipStr, macPtr, subnet.Name, true) if err == nil { return v4IP, v6IP, mac, nil } - err = fmt.Errorf("failed to get static address for ip %s, %v", ip.Name, err) + err = fmt.Errorf("failed to get static address for ip %s, %w", ip.Name, err) } klog.Error(err) return "", "", "", err diff --git a/pkg/controller/namespace.go b/pkg/controller/namespace.go index 6127d395ca9b..ff02e6222bd7 100644 --- a/pkg/controller/namespace.go +++ b/pkg/controller/namespace.go @@ -40,6 +40,9 @@ func (c *Controller) enqueueDeleteNamespace(obj interface{}) { c.updateNpQueue.Add(np) } } + if c.config.EnableANP { + c.updateAnpsByLabelsMatch(obj.(*v1.Namespace).Labels, nil) + } } func (c *Controller) enqueueUpdateNamespace(oldObj, newObj interface{}) { @@ -49,11 +52,17 @@ func (c *Controller) enqueueUpdateNamespace(oldObj, newObj interface{}) { return } - if c.config.EnableNP && !reflect.DeepEqual(oldNs.Labels, newNs.Labels) { - oldNp := c.namespaceMatchNetworkPolicies(oldNs) - newNp := c.namespaceMatchNetworkPolicies(newNs) - for _, np := range util.DiffStringSlice(oldNp, newNp) { - c.updateNpQueue.Add(np) + if !reflect.DeepEqual(oldNs.Labels, newNs.Labels) { + if c.config.EnableNP { + oldNp := c.namespaceMatchNetworkPolicies(oldNs) + newNp := c.namespaceMatchNetworkPolicies(newNs) + for _, np := range util.DiffStringSlice(oldNp, newNp) { + c.updateNpQueue.Add(np) + } + } + + if c.config.EnableANP { + c.updateAnpsByLabelsMatch(newObj.(*v1.Namespace).Labels, nil) } } diff --git a/pkg/controller/net_metrics.go b/pkg/controller/net_metrics.go index f0c242389091..fb9f7479211e 100644 --- a/pkg/controller/net_metrics.go +++ b/pkg/controller/net_metrics.go @@ -1,6 +1,9 @@ package controller -import "github.com/prometheus/client_golang/prometheus" +import ( + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) var ( metricSubnetAvailableIPs = prometheus.NewGaugeVec( @@ -66,9 +69,9 @@ var ( ) func registerMetrics() { - prometheus.MustRegister(metricSubnetAvailableIPs) - prometheus.MustRegister(metricSubnetUsedIPs) - prometheus.MustRegister(metricCentralSubnetInfo) - prometheus.MustRegister(metricSubnetIPAMInfo) - prometheus.MustRegister(metricSubnetIPAssignedInfo) + metrics.Registry.MustRegister(metricSubnetAvailableIPs) + metrics.Registry.MustRegister(metricSubnetUsedIPs) + metrics.Registry.MustRegister(metricCentralSubnetInfo) + metrics.Registry.MustRegister(metricSubnetIPAMInfo) + metrics.Registry.MustRegister(metricSubnetIPAssignedInfo) } diff --git a/pkg/controller/network_policy.go b/pkg/controller/network_policy.go index e1c53c8662b0..b1e6628e6229 100644 --- a/pkg/controller/network_policy.go +++ b/pkg/controller/network_policy.go @@ -88,7 +88,7 @@ func (c *Controller) processNextUpdateNpWorkItem() bool { } if err := c.handleUpdateNp(key); err != nil { c.updateNpQueue.AddRateLimited(key) - return fmt.Errorf("error syncing network policy %s: %v, requeuing", key, err) + return fmt.Errorf("error syncing network policy %s: %w, requeuing", key, err) } c.updateNpQueue.Forget(obj) return nil @@ -301,7 +301,7 @@ func (c *Controller) handleUpdateNp(key string) error { } } if err := c.OVNNbClient.Transact("add-ingress-acls", ingressACLOps); err != nil { - return fmt.Errorf("add ingress acls to %s: %v", pgName, err) + return fmt.Errorf("add ingress acls to %s: %w", pgName, err) } if err := c.OVNNbClient.SetACLLog(pgName, logEnable, true); err != nil { @@ -425,11 +425,10 @@ func (c *Controller) handleUpdateNp(key string) error { egressACLOps = append(egressACLOps, ops...) } - } } if err := c.OVNNbClient.Transact("add-egress-acls", egressACLOps); err != nil { - return fmt.Errorf("add egress acls to %s: %v", pgName, err) + return fmt.Errorf("add egress acls to %s: %w", pgName, err) } if err := c.OVNNbClient.SetACLLog(pgName, logEnable, false); err != nil { @@ -537,11 +536,11 @@ func (c *Controller) fetchSelectedPorts(namespace string, selector *metav1.Label var subnets []string sel, err := metav1.LabelSelectorAsSelector(selector) if err != nil { - return nil, nil, fmt.Errorf("error creating label selector, %v", err) + return nil, nil, fmt.Errorf("error creating label selector, %w", err) } pods, err := c.podsLister.Pods(namespace).List(sel) if err != nil { - return nil, nil, fmt.Errorf("failed to list pods, %v", err) + return nil, nil, fmt.Errorf("failed to list pods, %w", err) } ports := make([]string, 0, len(pods)) @@ -552,7 +551,7 @@ func (c *Controller) fetchSelectedPorts(namespace string, selector *metav1.Label podName := c.getNameByPod(pod) podNets, err := c.getPodKubeovnNets(pod) if err != nil { - return nil, nil, fmt.Errorf("failed to get pod networks, %v", err) + return nil, nil, fmt.Errorf("failed to get pod networks, %w", err) } for _, podNet := range podNets { @@ -610,11 +609,11 @@ func (c *Controller) fetchPolicySelectedAddresses(namespace, protocol string, np } else { sel, err := metav1.LabelSelectorAsSelector(npp.NamespaceSelector) if err != nil { - return nil, nil, fmt.Errorf("error creating label selector, %v", err) + return nil, nil, fmt.Errorf("error creating label selector, %w", err) } nss, err := c.namespacesLister.List(sel) if err != nil { - return nil, nil, fmt.Errorf("failed to list ns, %v", err) + return nil, nil, fmt.Errorf("failed to list ns, %w", err) } for _, ns := range nss { selectedNs = append(selectedNs, ns.Name) @@ -631,12 +630,12 @@ func (c *Controller) fetchPolicySelectedAddresses(namespace, protocol string, np for _, ns := range selectedNs { pods, err := c.podsLister.Pods(ns).List(sel) if err != nil { - return nil, nil, fmt.Errorf("failed to list pod, %v", err) + return nil, nil, fmt.Errorf("failed to list pod, %w", err) } svcs, err := c.servicesLister.Services(ns).List(labels.Everything()) if err != nil { klog.Errorf("failed to list svc, %v", err) - return nil, nil, fmt.Errorf("failed to list svc, %v", err) + return nil, nil, fmt.Errorf("failed to list svc, %w", err) } for _, pod := range pods { @@ -701,7 +700,7 @@ func isSvcMatchPod(svc *corev1.Service, pod *corev1.Pod) (bool, error) { ss := metav1.SetAsLabelSelector(svc.Spec.Selector) sel, err := metav1.LabelSelectorAsSelector(ss) if err != nil { - return false, fmt.Errorf("error fetch label selector, %v", err) + return false, fmt.Errorf("error fetch label selector, %w", err) } if pod.Labels == nil { return false, nil @@ -740,13 +739,13 @@ func (c *Controller) svcMatchNetworkPolicies(svc *corev1.Service) ([]string, err // find all match pod pods, err := c.podsLister.Pods(svc.Namespace).List(labels.Everything()) if err != nil { - return nil, fmt.Errorf("failed to list pods, %v", err) + return nil, fmt.Errorf("failed to list pods, %w", err) } // find all match netpol nps, err := c.npsLister.NetworkPolicies(corev1.NamespaceAll).List(labels.Everything()) if err != nil { - return nil, fmt.Errorf("failed to list netpols, %v", err) + return nil, fmt.Errorf("failed to list netpols, %w", err) } match := []string{} for _, pod := range pods { diff --git a/pkg/controller/node.go b/pkg/controller/node.go index 450a17254b6b..c65731783d9b 100644 --- a/pkg/controller/node.go +++ b/pkg/controller/node.go @@ -2,6 +2,7 @@ package controller import ( "context" + "errors" "fmt" "reflect" "slices" @@ -695,7 +696,7 @@ func (c *Controller) checkGatewayReady() error { if util.GatewayContains(subnet.Spec.GatewayNode, node.Name) { pinger, err := goping.NewPinger(ip) if err != nil { - return fmt.Errorf("failed to init pinger, %v", err) + return fmt.Errorf("failed to init pinger, %w", err) } pinger.SetPrivileged(true) @@ -793,7 +794,7 @@ func (c *Controller) retryDelDupChassis(attempts, sleep int, f func(node *v1.Nod time.Sleep(time.Duration(sleep) * time.Second) } if i >= (attempts - 1) { - errMsg := fmt.Errorf("exhausting all attempts") + errMsg := errors.New("exhausting all attempts") klog.Error(errMsg) return errMsg } @@ -917,7 +918,7 @@ func (c *Controller) UpdateChassisTag(node *v1.Node) error { if chassis.ExternalIDs == nil || chassis.ExternalIDs["vendor"] != util.CniTypeName { klog.Infof("init tag %s for node %s chassis %s", util.CniTypeName, node.Name, chassis.Name) if err = c.OVNSbClient.UpdateChassisTag(chassis.Name, node.Name); err != nil { - return fmt.Errorf("failed to init chassis tag, %v", err) + return fmt.Errorf("failed to init chassis tag, %w", err) } } return nil diff --git a/pkg/controller/ovn_eip.go b/pkg/controller/ovn_eip.go index 20f88dabdead..3767eb35d3e0 100644 --- a/pkg/controller/ovn_eip.go +++ b/pkg/controller/ovn_eip.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" "strings" "time" @@ -391,7 +392,7 @@ func (c *Controller) createOrUpdateOvnEipCR(key, subnet, v4ip, v6ip, mac, usageT }, }, metav1.CreateOptions{}) if err != nil { - err := fmt.Errorf("failed to create crd ovn eip '%s', %v", key, err) + err := fmt.Errorf("failed to create crd ovn eip '%s', %w", key, err) klog.Error(err) return err } @@ -423,7 +424,7 @@ func (c *Controller) createOrUpdateOvnEipCR(key, subnet, v4ip, v6ip, mac, usageT } if needUpdate { if _, err := c.config.KubeOvnClient.KubeovnV1().OvnEips().Update(context.Background(), ovnEip, metav1.UpdateOptions{}); err != nil { - errMsg := fmt.Errorf("failed to update ovn eip '%s', %v", key, err) + errMsg := fmt.Errorf("failed to update ovn eip '%s', %w", key, err) klog.Error(errMsg) return errMsg } @@ -520,7 +521,7 @@ func (c *Controller) patchOvnEipStatus(key string, ready bool) error { } nat, err := c.getOvnEipNat(ovnEip.Spec.V4Ip) if err != nil { - err := fmt.Errorf("failed to get ovn eip nat") + err := errors.New("failed to get ovn eip nat") klog.Error(err) return err } @@ -646,7 +647,7 @@ func (c *Controller) handleDelOvnEipFinalizer(cachedEip *kubeovnv1.OvnEip) error var err error nat, err := c.getOvnEipNat(cachedEip.Spec.V4Ip) if err != nil { - err := fmt.Errorf("failed to get ovn eip nat") + err := errors.New("failed to get ovn eip nat") klog.Error(err) return err } diff --git a/pkg/controller/ovn_fip.go b/pkg/controller/ovn_fip.go index 1ef9e40ce6a4..04c816ab3fdc 100644 --- a/pkg/controller/ovn_fip.go +++ b/pkg/controller/ovn_fip.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" "strconv" @@ -209,7 +210,7 @@ func (c *Controller) handleAddOvnFip(key string) error { // check eip eipName := cachedFip.Spec.OvnEip if eipName == "" { - err := fmt.Errorf("failed to create fip rule, should set eip") + err := errors.New("failed to create fip rule, should set eip") klog.Error(err) return err } @@ -228,7 +229,7 @@ func (c *Controller) handleAddOvnFip(key string) error { v4Eip = cachedEip.Status.V4Ip v6Eip = cachedEip.Status.V6Ip if err = c.isOvnFipDuplicated(key, cachedEip.Spec.V4Ip); err != nil { - err = fmt.Errorf("failed to add fip %s, %v", key, err) + err = fmt.Errorf("failed to add fip %s, %w", key, err) klog.Error(err) return err } @@ -271,7 +272,7 @@ func (c *Controller) handleAddOvnFip(key string) error { } vpcName = subnet.Spec.Vpc if err = c.isOvnFipDuplicated(key, cachedEip.Spec.V4Ip); err != nil { - err = fmt.Errorf("failed to update fip %s, %v", key, err) + err = fmt.Errorf("failed to update fip %s, %w", key, err) klog.Error(err) return err } @@ -349,7 +350,7 @@ func (c *Controller) handleUpdateOvnFip(key string) error { // check eip eipName := cachedFip.Spec.OvnEip if eipName == "" { - err := fmt.Errorf("failed to create fip rule, should set eip") + err := errors.New("failed to create fip rule, should set eip") klog.Error(err) return err } @@ -368,7 +369,7 @@ func (c *Controller) handleUpdateOvnFip(key string) error { v4Eip = cachedEip.Status.V4Ip v6Eip = cachedEip.Status.V6Ip if err = c.isOvnFipDuplicated(key, cachedEip.Spec.V4Ip); err != nil { - err = fmt.Errorf("failed to add fip %s, %v", key, err) + err = fmt.Errorf("failed to add fip %s, %w", key, err) klog.Error(err) return err } @@ -408,7 +409,7 @@ func (c *Controller) handleUpdateOvnFip(key string) error { } vpcName = subnet.Spec.Vpc if err = c.isOvnFipDuplicated(key, cachedEip.Spec.V4Ip); err != nil { - err = fmt.Errorf("failed to update fip %s, %v", key, err) + err = fmt.Errorf("failed to update fip %s, %w", key, err) klog.Error(err) return err } diff --git a/pkg/controller/ovn_snat.go b/pkg/controller/ovn_snat.go index 4d7b13832351..db3c01cf0df1 100644 --- a/pkg/controller/ovn_snat.go +++ b/pkg/controller/ovn_snat.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -190,7 +191,7 @@ func (c *Controller) handleAddOvnSnatRule(key string) error { // check eip eipName := cachedSnat.Spec.OvnEip if eipName == "" { - err := fmt.Errorf("failed to create ovn snat rule, should set eip") + err := errors.New("failed to create ovn snat rule, should set eip") klog.Error(err) return err } @@ -305,7 +306,7 @@ func (c *Controller) handleUpdateOvnSnatRule(key string) error { // check eip eipName := cachedSnat.Spec.OvnEip if eipName == "" { - err := fmt.Errorf("failed to create ovn snat rule, should set eip") + err := errors.New("failed to create ovn snat rule, should set eip") klog.Error(err) return err } diff --git a/pkg/controller/pod.go b/pkg/controller/pod.go index 4132c0544b67..568200097a21 100644 --- a/pkg/controller/pod.go +++ b/pkg/controller/pod.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" "net" "reflect" @@ -181,6 +182,10 @@ func (c *Controller) enqueueAddPod(obj interface{}) { } p := obj.(*v1.Pod) + if p.Spec.HostNetwork { + return + } + // TODO: we need to find a way to reduce duplicated np added to the queue if c.config.EnableNP { c.namedPort.AddNamedPortByPod(p) @@ -191,10 +196,6 @@ func (c *Controller) enqueueAddPod(obj interface{}) { } } - if p.Spec.HostNetwork { - return - } - if !isPodAlive(p) { isStateful, statefulSetName, statefulSetUID := isStatefulSetPod(p) isVMPod, vmName := isVMPod(p) @@ -237,6 +238,10 @@ func (c *Controller) enqueueDeletePod(obj interface{}) { } p := obj.(*v1.Pod) + if p.Spec.HostNetwork { + return + } + if c.config.EnableNP { c.namedPort.DeleteNamedPortByPod(p) for _, np := range c.podMatchNetworkPolicies(p) { @@ -244,8 +249,9 @@ func (c *Controller) enqueueDeletePod(obj interface{}) { } } - if p.Spec.HostNetwork { - return + if c.config.EnableANP { + podNs, _ := c.namespacesLister.Get(obj.(*v1.Pod).Namespace) + c.updateAnpsByLabelsMatch(podNs.Labels, obj.(*v1.Pod).Labels) } klog.Infof("enqueue delete pod %s", key) @@ -284,6 +290,9 @@ func (c *Controller) enqueueUpdatePod(oldObj, newObj interface{}) { if oldPod.ResourceVersion == newPod.ResourceVersion { return } + if newPod.Spec.HostNetwork { + return + } key, err := cache.MetaNamespaceKeyFunc(newObj) if err != nil { @@ -320,8 +329,20 @@ func (c *Controller) enqueueUpdatePod(oldObj, newObj interface{}) { } } - if newPod.Spec.HostNetwork { - return + if c.config.EnableANP { + podNs, _ := c.namespacesLister.Get(newPod.Namespace) + if !reflect.DeepEqual(oldPod.Labels, newPod.Labels) { + c.updateAnpsByLabelsMatch(podNs.Labels, newPod.Labels) + } + + for _, podNet := range podNets { + oldAllocated := oldPod.Annotations[fmt.Sprintf(util.AllocatedAnnotationTemplate, podNet.ProviderName)] + newAllocated := newPod.Annotations[fmt.Sprintf(util.AllocatedAnnotationTemplate, podNet.ProviderName)] + if oldAllocated != newAllocated { + c.updateAnpsByLabelsMatch(podNs.Labels, newPod.Labels) + break + } + } } isStateful, statefulSetName, statefulSetUID := isStatefulSetPod(newPod) @@ -706,14 +727,14 @@ func (c *Controller) reconcileAllocateSubnets(cachedPod, pod *v1.Pod, needAlloca if migrated { klog.Infof("migrate end reset options for lsp %s from %s to %s, migrated fail: %t", portName, srcNodeName, targetNodeName, migratedFail) if err := c.OVNNbClient.ResetLogicalSwitchPortMigrateOptions(portName, srcNodeName, targetNodeName, migratedFail); err != nil { - err = fmt.Errorf("failed to clean migrate options for lsp %s, %v", portName, err) + err = fmt.Errorf("failed to clean migrate options for lsp %s, %w", portName, err) klog.Error(err) return nil, err } } else { klog.Infof("migrate start set options for lsp %s from %s to %s", portName, srcNodeName, targetNodeName) if err := c.OVNNbClient.SetLogicalSwitchPortMigrateOptions(portName, srcNodeName, targetNodeName); err != nil { - err = fmt.Errorf("failed to set migrate options for lsp %s, %v", portName, err) + err = fmt.Errorf("failed to set migrate options for lsp %s, %w", portName, err) klog.Error(err) return nil, err } @@ -744,7 +765,7 @@ func (c *Controller) reconcileAllocateSubnets(cachedPod, pod *v1.Pod, needAlloca // CreatePort may fail, so put ip CR creation after CreatePort ipCRName := ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName) if err := c.createOrUpdateIPCR(ipCRName, podName, ipStr, mac, subnet.Name, pod.Namespace, pod.Spec.NodeName, podType); err != nil { - err = fmt.Errorf("failed to create ips CR %s.%s: %v", podName, pod.Namespace, err) + err = fmt.Errorf("failed to create ips CR %s.%s: %w", podName, pod.Namespace, err) klog.Error(err) return nil, err } @@ -809,13 +830,13 @@ func (c *Controller) reconcileRouteSubnets(cachedPod, pod *v1.Pod, needRoutePodN return fmt.Errorf("NodeSwitch subnet %s is unavailable for pod", subnet.Name) } + portName := ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName) if (!c.config.EnableLb || !(subnet.Spec.EnableLb != nil && *subnet.Spec.EnableLb)) && subnet.Spec.Vpc == c.config.ClusterRouter && subnet.Spec.U2OInterconnection && subnet.Spec.Vlan != "" && !subnet.Spec.LogicalGateway { pgName := getOverlaySubnetsPortGroupName(subnet.Name, pod.Spec.NodeName) - portName := ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName) if err := c.OVNNbClient.PortGroupAddPorts(pgName, portName); err != nil { klog.Errorf("failed to add port to u2o port group %s: %v", pgName, err) return err @@ -846,7 +867,7 @@ func (c *Controller) reconcileRouteSubnets(cachedPod, pod *v1.Pod, needRoutePodN nextHop = externalSubnet.Spec.Gateway if nextHop == "" { klog.Errorf("no available gateway address") - return fmt.Errorf("no available gateway address") + return errors.New("no available gateway address") } } if strings.Contains(nextHop, "/") { @@ -867,12 +888,10 @@ func (c *Controller) reconcileRouteSubnets(cachedPod, pod *v1.Pod, needRoutePodN } // remove lsp from port group to make EIP/SNAT work - portName := ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName) if err = c.OVNNbClient.PortGroupRemovePorts(pgName, portName); err != nil { klog.Error(err) return err } - } else { if subnet.Spec.GatewayType == kubeovnv1.GWDistributedType && pod.Annotations[util.NorthGatewayAnnotation] == "" { nodeTunlIPAddr, err := getNodeTunlIP(node) @@ -888,7 +907,6 @@ func (c *Controller) reconcileRouteSubnets(cachedPod, pod *v1.Pod, needRoutePodN continue } - portName := ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName) if err := c.OVNNbClient.PortGroupAddPorts(pgName, portName); err != nil { klog.Errorf("add port to port group %s: %v", pgName, err) return err @@ -903,18 +921,32 @@ func (c *Controller) reconcileRouteSubnets(cachedPod, pod *v1.Pod, needRoutePodN } } - if pod.Annotations[util.NorthGatewayAnnotation] != "" { - if err := c.addStaticRouteToVpc( - subnet.Spec.Vpc, - &kubeovnv1.StaticRoute{ - Policy: kubeovnv1.PolicySrc, - CIDR: podIP, - NextHopIP: pod.Annotations[util.NorthGatewayAnnotation], - RouteTable: subnet.Spec.RouteTable, - }, - ); err != nil { - klog.Errorf("failed to add static route, %v", err) - return err + if pod.Annotations[util.NorthGatewayAnnotation] != "" && pod.Annotations[util.IPAddressAnnotation] != "" { + for _, podAddr := range strings.Split(pod.Annotations[util.IPAddressAnnotation], ",") { + if util.CheckProtocol(podAddr) != util.CheckProtocol(pod.Annotations[util.NorthGatewayAnnotation]) { + continue + } + ipSuffix := "ip4" + if util.CheckProtocol(podAddr) == kubeovnv1.ProtocolIPv6 { + ipSuffix = "ip6" + } + + if err := c.addPolicyRouteToVpc( + subnet.Spec.Vpc, + &kubeovnv1.PolicyRoute{ + Priority: util.NorthGatewayRoutePolicyPriority, + Match: fmt.Sprintf("%s.src == %s", ipSuffix, podAddr), + Action: kubeovnv1.PolicyRouteActionReroute, + NextHopIP: pod.Annotations[util.NorthGatewayAnnotation], + }, + map[string]string{ + "vendor": util.CniTypeName, + "subnet": subnet.Name, + }, + ); err != nil { + klog.Errorf("failed to add policy route, %v", err) + return err + } } } else if c.config.EnableEipSnat { if err = c.deleteStaticRouteFromVpc( @@ -956,6 +988,13 @@ func (c *Controller) reconcileRouteSubnets(cachedPod, pod *v1.Pod, needRoutePodN } } + if pod.Annotations[fmt.Sprintf(util.ActivationStrategyTemplate, podNet.ProviderName)] != "" { + if err := c.OVNNbClient.SetLogicalSwitchPortActivationStrategy(portName, pod.Spec.NodeName); err != nil { + klog.Errorf("failed to set activation strategy for lsp %s: %v", portName, err) + return err + } + } + pod.Annotations[fmt.Sprintf(util.RoutedAnnotationTemplate, podNet.ProviderName)] = "true" } patch, err := util.GenerateMergePatchPayload(cachedPod, pod) @@ -1041,7 +1080,7 @@ func (c *Controller) handleDeletePod(key string) error { } for _, port := range ports { if err := c.OVNNbClient.CleanLogicalSwitchPortMigrateOptions(port.Name); err != nil { - err = fmt.Errorf("failed to clean migrate options for vm lsp %s, %v", port.Name, err) + err = fmt.Errorf("failed to clean migrate options for vm lsp %s, %w", port.Name, err) klog.Error(err) return err } @@ -1098,19 +1137,20 @@ func (c *Controller) handleDeletePod(key string) error { klog.Error(err) return err } - // If pod has snat or eip, also need delete staticRoute when delete pod - if vpc.Name == c.config.ClusterRouter { - if err = c.deleteStaticRouteFromVpc( - vpc.Name, - subnet.Spec.RouteTable, - address.IP, - "", - kubeovnv1.PolicyDst, - ); err != nil { - klog.Errorf("failed to delete static route, %v", err) - return err - } + + ipSuffix := "ip4" + if util.CheckProtocol(address.IP) == kubeovnv1.ProtocolIPv6 { + ipSuffix = "ip6" } + if err = c.deletePolicyRouteFromVpc( + vpc.Name, + util.NorthGatewayRoutePolicyPriority, + fmt.Sprintf("%s.src == %s", ipSuffix, address.IP), + ); err != nil { + klog.Errorf("failed to delete static route, %v", err) + return err + } + if c.config.EnableEipSnat { if pod.Annotations[util.EipAnnotation] != "" { if err = c.OVNNbClient.DeleteNat(c.config.ClusterRouter, ovnnb.NATTypeDNATAndSNAT, pod.Annotations[util.EipAnnotation], address.IP); err != nil { @@ -1127,7 +1167,7 @@ func (c *Controller) handleDeletePod(key string) error { } for _, port := range ports { // when lsp is deleted, the port of pod is deleted from any port-group automatically. - klog.Infof("gc logical switch port %s", port.Name) + klog.Infof("delete logical switch port %s", port.Name) if err := c.OVNNbClient.DeleteLogicalSwitchPort(port.Name); err != nil { klog.Errorf("failed to delete lsp %s, %v", port.Name, err) return err @@ -1368,7 +1408,7 @@ func getNodeTunlIP(node *v1.Node) ([]net.IP, error) { var nodeTunlIPAddr []net.IP nodeTunlIP := node.Annotations[util.IPAddressAnnotation] if nodeTunlIP == "" { - return nil, fmt.Errorf("node has no tunnel ip annotation") + return nil, errors.New("node has no tunnel ip annotation") } for _, ip := range strings.Split(nodeTunlIP, ",") { @@ -1434,7 +1474,7 @@ func (c *Controller) podNeedSync(pod *v1.Pod) (bool, error) { } ipName := ovs.PodNameToPortName(pod.Name, pod.Namespace, n.ProviderName) if _, err = c.ipsLister.Get(ipName); err != nil { - err = fmt.Errorf("pod has no ip %s: %v", ipName, err) + err = fmt.Errorf("pod has no ip %s: %w", ipName, err) // need to sync to create ip klog.Error(err) return true, nil @@ -1908,7 +1948,7 @@ func appendCheckPodToDel(c *Controller, pod *v1.Pod, ownerRefName, ownerRefKind } case util.VMInstance: - vm, err := c.config.KubevirtClient.VirtualMachine(pod.Namespace).Get(context.Background(), ownerRefName, &metav1.GetOptions{}) + vm, err := c.config.KubevirtClient.VirtualMachine(pod.Namespace).Get(context.Background(), ownerRefName, metav1.GetOptions{}) if err != nil { if k8serrors.IsNotFound(err) { klog.Infof("VirtualMachine %s is not found", ownerRefName) @@ -1978,7 +2018,7 @@ func (c *Controller) isVMToDel(pod *v1.Pod, vmiName string) bool { vmName string ) // The vmi is also deleted when pod is deleted, only left vm exists. - vmi, err := c.config.KubevirtClient.VirtualMachineInstance(pod.Namespace).Get(context.Background(), vmiName, &metav1.GetOptions{}) + vmi, err := c.config.KubevirtClient.VirtualMachineInstance(pod.Namespace).Get(context.Background(), vmiName, metav1.GetOptions{}) if err != nil { if k8serrors.IsNotFound(err) { vmiAlive = false @@ -2003,7 +2043,7 @@ func (c *Controller) isVMToDel(pod *v1.Pod, vmiName string) bool { return false } - vm, err := c.config.KubevirtClient.VirtualMachine(pod.Namespace).Get(context.Background(), vmName, &metav1.GetOptions{}) + vm, err := c.config.KubevirtClient.VirtualMachine(pod.Namespace).Get(context.Background(), vmName, metav1.GetOptions{}) if err != nil { // the vm has gone if k8serrors.IsNotFound(err) { @@ -2206,7 +2246,7 @@ func setPodRoutesAnnotation(annotations map[string]string, provider string, rout buf, err := json.Marshal(routes) if err != nil { - err = fmt.Errorf("failed to marshal routes %+v: %v", routes, err) + err = fmt.Errorf("failed to marshal routes %+v: %w", routes, err) klog.Error(err) return err } diff --git a/pkg/controller/qos_policy.go b/pkg/controller/qos_policy.go index cfe640c7c019..7a2e31d7539d 100644 --- a/pkg/controller/qos_policy.go +++ b/pkg/controller/qos_policy.go @@ -340,13 +340,13 @@ func (c *Controller) reconcileEIPBandtithLimitRules( } } if len(added) > 0 { - if err = c.addOrUpdateEIPBandtithLimitRules(eip, eip.Status.IP, added); err != nil { + if err = c.addOrUpdateEIPBandwidthLimitRules(eip, eip.Status.IP, added); err != nil { klog.Errorf("failed to add eip %s bandwidth limit rules, %v", eip.Name, err) return err } } if len(updated) > 0 { - if err = c.addOrUpdateEIPBandtithLimitRules(eip, eip.Status.IP, updated); err != nil { + if err = c.addOrUpdateEIPBandwidthLimitRules(eip, eip.Status.IP, updated); err != nil { klog.Errorf("failed to update eip %s bandwidth limit rules, %v", eip.Name, err) return err } diff --git a/pkg/controller/security_group.go b/pkg/controller/security_group.go index 9330368f206d..5713bed27ee4 100644 --- a/pkg/controller/security_group.go +++ b/pkg/controller/security_group.go @@ -2,6 +2,8 @@ package controller import ( "context" + "encoding/hex" + "errors" "fmt" "net" "reflect" @@ -192,7 +194,7 @@ func (c *Controller) syncSecurityGroup() error { for _, sg := range sgs { lost, err := c.OVNNbClient.SGLostACL(sg) if err != nil { - err = fmt.Errorf("failed to check if security group %s lost acl: %v", sg.Name, err) + err = fmt.Errorf("failed to check if security group %s lost acl: %w", sg.Name, err) klog.Error(err) return err } @@ -303,12 +305,12 @@ func (c *Controller) handleAddOrUpdateSg(key string, force bool) error { egressNeedUpdate = true } else { // check md5 - newIngressMd5 = fmt.Sprintf("%x", structhash.Md5(sg.Spec.IngressRules, 1)) + newIngressMd5 = hex.EncodeToString(structhash.Md5(sg.Spec.IngressRules, 1)) if !sg.Status.IngressLastSyncSuccess || newIngressMd5 != sg.Status.IngressMd5 { klog.Infof("ingress need update, sg:%s", sg.Name) ingressNeedUpdate = true } - newEgressMd5 = fmt.Sprintf("%x", structhash.Md5(sg.Spec.EgressRules, 1)) + newEgressMd5 = hex.EncodeToString(structhash.Md5(sg.Spec.EgressRules, 1)) if !sg.Status.EgressLastSyncSuccess || newEgressMd5 != sg.Status.EgressMd5 { klog.Infof("egress need update, sg:%s", sg.Name) egressNeedUpdate = true @@ -370,7 +372,7 @@ func (c *Controller) validateSgRule(sg *kubeovnv1.SecurityGroup) error { allRules := append(sg.Spec.IngressRules, sg.Spec.EgressRules...) for _, rule := range allRules { if rule.IPVersion != "ipv4" && rule.IPVersion != "ipv6" { - return fmt.Errorf("IPVersion should be 'ipv4' or 'ipv6'") + return errors.New("IPVersion should be 'ipv4' or 'ipv6'") } if rule.Priority < 1 || rule.Priority > 200 { @@ -391,7 +393,7 @@ func (c *Controller) validateSgRule(sg *kubeovnv1.SecurityGroup) error { case kubeovnv1.SgRemoteTypeSg: _, err := c.sgsLister.Get(rule.RemoteSecurityGroup) if err != nil { - return fmt.Errorf("failed to get remote sg '%s', %v", rule.RemoteSecurityGroup, err) + return fmt.Errorf("failed to get remote sg '%s', %w", rule.RemoteSecurityGroup, err) } default: return fmt.Errorf("not support sgRemoteType '%s'", rule.RemoteType) @@ -399,10 +401,10 @@ func (c *Controller) validateSgRule(sg *kubeovnv1.SecurityGroup) error { if rule.Protocol == kubeovnv1.ProtocolTCP || rule.Protocol == kubeovnv1.ProtocolUDP { if rule.PortRangeMin < 1 || rule.PortRangeMin > 65535 || rule.PortRangeMax < 1 || rule.PortRangeMax > 65535 { - return fmt.Errorf("portRange is out of range") + return errors.New("portRange is out of range") } if rule.PortRangeMin > rule.PortRangeMax { - return fmt.Errorf("portRange err, range Minimum value greater than maximum value") + return errors.New("portRange err, range Minimum value greater than maximum value") } } } diff --git a/pkg/controller/service.go b/pkg/controller/service.go index 180eac4e7726..262f7e881a49 100644 --- a/pkg/controller/service.go +++ b/pkg/controller/service.go @@ -60,7 +60,6 @@ func (c *Controller) enqueueDeleteService(obj interface{}) { vip, ok := svc.Annotations[util.SwitchLBRuleVipsAnnotation] if ok || svc.Spec.ClusterIP != v1.ClusterIPNone && svc.Spec.ClusterIP != "" { - if c.config.EnableNP { var netpols []string var err error @@ -234,7 +233,7 @@ func (c *Controller) handleDeleteService(service *vpcService) error { key, err := cache.MetaNamespaceKeyFunc(service.Svc) if err != nil { klog.Error(err) - utilruntime.HandleError(fmt.Errorf("failed to get meta namespace key of %#v: %v", service.Svc, err)) + utilruntime.HandleError(fmt.Errorf("failed to get meta namespace key of %#v: %w", service.Svc, err)) return nil } diff --git a/pkg/controller/service_lb.go b/pkg/controller/service_lb.go index 9b3a276118da..cd3bc756bb54 100644 --- a/pkg/controller/service_lb.go +++ b/pkg/controller/service_lb.go @@ -57,7 +57,7 @@ func parseAttachNetworkProvider(svc *corev1.Service) (string, string) { func (c *Controller) checkAttachNetwork(svc *corev1.Service) error { attachmentName, attachmentNs := parseAttachNetworkProvider(svc) if attachmentName == "" && attachmentNs == "" { - return fmt.Errorf("the provider name should be consisted of name and namespace") + return errors.New("the provider name should be consisted of name and namespace") } _, err := c.config.AttachNetClient.K8sCniCncfIoV1().NetworkAttachmentDefinitions(attachmentNs).Get(context.Background(), attachmentName, metav1.GetOptions{}) @@ -197,7 +197,7 @@ func (c *Controller) getLbSvcPod(svcName, svcNamespace string) (*corev1.Pod, err return nil, fmt.Errorf("pod of deployment %s/%s not found", svcNamespace, genLbSvcDpName(svcName)) case len(pods) != 1: time.Sleep(2 * time.Second) - return nil, fmt.Errorf("too many pods") + return nil, errors.New("too many pods") case pods[0].Status.Phase != corev1.PodRunning: time.Sleep(2 * time.Second) return nil, fmt.Errorf("pod %s/%s is not running", pods[0].Namespace, pods[0].Name) @@ -240,7 +240,7 @@ func (c *Controller) getPodAttachIP(pod *corev1.Pod, svc *corev1.Service) (strin if pod.Annotations[attachIPAnnotation] != "" { loadBalancerIP = pod.Annotations[attachIPAnnotation] } else { - err = fmt.Errorf("failed to get attachment ip from pod's annotation") + err = errors.New("failed to get attachment ip from pod's annotation") } return loadBalancerIP, err diff --git a/pkg/controller/subnet.go b/pkg/controller/subnet.go index 6219709a87a0..e68c9dbb06c1 100644 --- a/pkg/controller/subnet.go +++ b/pkg/controller/subnet.go @@ -3,11 +3,13 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" "net" "reflect" "slices" "sort" + "strconv" "strings" "time" @@ -87,7 +89,6 @@ func (c *Controller) enqueueUpdateSubnet(oldObj, newObj interface{}) { if oldSubnet.Spec.Vpc != newSubnet.Spec.Vpc && !(oldSubnet.Spec.Vpc == "" && newSubnet.Spec.Vpc == c.config.ClusterRouter || oldSubnet.Spec.Vpc == c.config.ClusterRouter && newSubnet.Spec.Vpc == "") { - if newSubnet.Annotations == nil { newSubnet.Annotations = make(map[string]string) } @@ -130,7 +131,6 @@ func (c *Controller) enqueueUpdateSubnet(oldObj, newObj interface{}) { oldSubnet.Spec.EnableMulticastSnoop != newSubnet.Spec.EnableMulticastSnoop || !reflect.DeepEqual(oldSubnet.Spec.NatOutgoingPolicyRules, newSubnet.Spec.NatOutgoingPolicyRules) || (newSubnet.Spec.U2OInterconnection && newSubnet.Spec.U2OInterconnectionIP != "" && oldSubnet.Spec.U2OInterconnectionIP != newSubnet.Spec.U2OInterconnectionIP) { - klog.V(3).Infof("enqueue update subnet %s", key) if oldSubnet.Spec.GatewayType != newSubnet.Spec.GatewayType { @@ -317,7 +317,7 @@ func (c *Controller) formatSubnet(subnet *kubeovnv1.Subnet) (*kubeovnv1.Subnet, if subnet.Spec.Vlan != "" { if _, err := c.vlansLister.Get(subnet.Spec.Vlan); err != nil { - err = fmt.Errorf("failed to get vlan %s: %s", subnet.Spec.Vlan, err) + err = fmt.Errorf("failed to get vlan %s: %w", subnet.Spec.Vlan, err) klog.Error(err) return nil, err } @@ -359,7 +359,7 @@ func (c *Controller) updateNatOutgoingPolicyRulesStatus(subnet *kubeovnv1.Subnet klog.Error(err) return err } - priority := fmt.Sprintf("%d", index) + priority := strconv.Itoa(index) // hash code generate by subnetName, rule and priority var retBytes []byte retBytes = append(retBytes, []byte(subnet.Name)...) @@ -1369,7 +1369,7 @@ func (c *Controller) reconcileCustomVpcBfdStaticRoute(vpcName, subnetName string lrpEipName = fmt.Sprintf("%s-%s", vpcName, c.config.ExternalGatewaySwitch) lrpEip, err := c.ovnEipsLister.Get(lrpEipName) if err != nil { - err := fmt.Errorf("failed to get lrp eip %s, %v", lrpEipName, err) + err := fmt.Errorf("failed to get lrp eip %s, %w", lrpEipName, err) klog.Error(err) return err } @@ -1550,28 +1550,9 @@ func (c *Controller) reconcileDistributedSubnetRouteInDefaultVpc(subnet *kubeovn continue } - if pod.Annotations[util.NorthGatewayAnnotation] != "" { - if err := c.addStaticRouteToVpc( - subnet.Spec.Vpc, - &kubeovnv1.StaticRoute{ - Policy: kubeovnv1.PolicySrc, - CIDR: pod.Annotations[fmt.Sprintf(util.IPAddressAnnotationTemplate, podNet.ProviderName)], - NextHopIP: pod.Annotations[util.NorthGatewayAnnotation], - RouteTable: util.MainRouteTable, - }, - ); err != nil { - klog.Errorf("add static route failed, %v", err) - return err - } - } else { - podName := c.getNameByPod(pod) - portName := ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName) - podPorts = append(podPorts, portName) - } - } - - if pod.Annotations[util.NorthGatewayAnnotation] != "" { - continue + podName := c.getNameByPod(pod) + portName := ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName) + podPorts = append(podPorts, portName) } pgName := getOverlaySubnetsPortGroupName(subnet.Name, pod.Spec.NodeName) @@ -1811,7 +1792,6 @@ func (c *Controller) reconcileOvnDefaultVpcRoute(subnet *kubeovnv1.Subnet) error return err } } - } else { // It's difficult to update policy route when subnet cidr is changed, add check for cidr changed situation if err := c.reconcilePolicyRouteForCidrChangedSubnet(subnet, true); err != nil { @@ -1846,7 +1826,7 @@ func (c *Controller) reconcileOvnDefaultVpcRoute(subnet *kubeovnv1.Subnet) error gwNodeExists := c.checkGwNodeExists(subnet.Spec.GatewayNode) if !gwNodeExists { klog.Errorf("failed to init centralized gateway for subnet %s, no gateway node exists", subnet.Name) - return fmt.Errorf("failed to add ecmp policy route, no gateway node exists") + return errors.New("failed to add ecmp policy route, no gateway node exists") } if err := c.reconcilePolicyRouteForCidrChangedSubnet(subnet, false); err != nil { @@ -2753,13 +2733,13 @@ func (c *Controller) addPolicyRouteForU2OInterconn(subnet *kubeovnv1.Subnet) err /* policy1: - prio 29400 match: "ip4.dst == underlay subnet cidr" action: allow + priority 29400 match: "ip4.dst == underlay subnet cidr" action: allow policy2: - prio 31000 match: "ip4.dst == node ips && ip4.src == underlay subnet cidr" action: reroute physical gw + priority 31000 match: "ip4.dst == node ips && ip4.src == underlay subnet cidr" action: reroute physical gw policy3: - prio 29000 match: "ip4.src == underlay subnet cidr" action: reroute physical gw + priority 29000 match: "ip4.src == underlay subnet cidr" action: reroute physical gw comment: policy1 and policy2 allow overlay pod access underlay but when overlay pod access node ip, it should go join subnet, @@ -3261,15 +3241,15 @@ func (c *Controller) findSubnetByNetworkAttachmentDefinition(ns, name string, su return nil, err } - var provder string + var provider string if netCfg.Conf.Type == util.CniTypeName { - provder = fmt.Sprintf("%s.%s.%s", name, ns, util.OvnProvider) + provider = fmt.Sprintf("%s.%s.%s", name, ns, util.OvnProvider) } else { - provder = fmt.Sprintf("%s.%s", name, ns) + provider = fmt.Sprintf("%s.%s", name, ns) } var subnet *kubeovnv1.Subnet for _, s := range subnets { - if s.Spec.Provider == provder { + if s.Spec.Provider == provider { subnet = s.DeepCopy() break } diff --git a/pkg/controller/switch_lb_rule.go b/pkg/controller/switch_lb_rule.go index 61fc3af69343..d9d9ded8b705 100644 --- a/pkg/controller/switch_lb_rule.go +++ b/pkg/controller/switch_lb_rule.go @@ -131,7 +131,7 @@ func (c *Controller) processSwitchLBRuleWorkItem(processName string, queue workq queue.Forget(obj) return nil }(obj); err != nil { - utilruntime.HandleError(fmt.Errorf("process: %s. err: %v", processName, err)) + utilruntime.HandleError(fmt.Errorf("process: %s. err: %w", processName, err)) queue.AddRateLimited(obj) return true } @@ -203,13 +203,13 @@ func (c *Controller) handleAddOrUpdateSwitchLBRule(key string) error { eps = generateEndpoints(slr, oldEps) if needToCreateEps { if _, err = c.config.KubeClient.CoreV1().Endpoints(slr.Spec.Namespace).Create(context.Background(), eps, metav1.CreateOptions{}); err != nil { - err = fmt.Errorf("failed to create endpoints '%s', err: %v", eps, err) + err = fmt.Errorf("failed to create endpoints '%s', err: %w", eps, err) klog.Error(err) return err } } else { if _, err = c.config.KubeClient.CoreV1().Endpoints(slr.Spec.Namespace).Update(context.Background(), eps, metav1.UpdateOptions{}); err != nil { - err = fmt.Errorf("failed to update endpoints '%s', err: %v", eps, err) + err = fmt.Errorf("failed to update endpoints '%s', err: %w", eps, err) klog.Error(err) return err } @@ -221,13 +221,13 @@ func (c *Controller) handleAddOrUpdateSwitchLBRule(key string) error { svc = generateHeadlessService(slr, oldSvc) if needToCreateSvc { if _, err = c.config.KubeClient.CoreV1().Services(slr.Spec.Namespace).Create(context.Background(), svc, metav1.CreateOptions{}); err != nil { - err = fmt.Errorf("failed to create service '%s', err: %v", svc, err) + err = fmt.Errorf("failed to create service '%s', err: %w", svc, err) klog.Error(err) return err } } else { if _, err = c.config.KubeClient.CoreV1().Services(slr.Spec.Namespace).Update(context.Background(), svc, metav1.UpdateOptions{}); err != nil { - err = fmt.Errorf("failed to update service '%s', err: %v", svc, err) + err = fmt.Errorf("failed to update service '%s', err: %w", svc, err) klog.Error(err) return err } @@ -249,7 +249,7 @@ func (c *Controller) handleAddOrUpdateSwitchLBRule(key string) error { newSlr.Status.Ports = strings.TrimPrefix(formatPorts, ",") if _, err = c.config.KubeOvnClient.KubeovnV1().SwitchLBRules().UpdateStatus(context.Background(), newSlr, metav1.UpdateOptions{}); err != nil { - err = fmt.Errorf("failed to update switch lb rule status, %v", err) + err = fmt.Errorf("failed to update switch lb rule status, %w", err) klog.Error(err) return err } diff --git a/pkg/controller/vip.go b/pkg/controller/vip.go index ca4cbe94a129..1e3a9fb7b566 100644 --- a/pkg/controller/vip.go +++ b/pkg/controller/vip.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" "reflect" "slices" @@ -261,19 +262,19 @@ func (c *Controller) handleAddVirtualIP(key string) error { mac = lrp.MAC ipStr := util.GetStringIP(v4ip, v6ip) if err := c.OVNNbClient.CreateLogicalSwitchPort(subnet.Name, portName, ipStr, mac, vip.Name, vip.Spec.Namespace, false, "", "", false, nil, subnet.Spec.Vpc); err != nil { - err = fmt.Errorf("failed to create lsp %s: %v", portName, err) + err = fmt.Errorf("failed to create lsp %s: %w", portName, err) klog.Error(err) return err } if err := c.OVNNbClient.SetLogicalSwitchPortArpProxy(portName, true); err != nil { - err = fmt.Errorf("failed to enable lsp arp proxy for vip %s: %v", portName, err) + err = fmt.Errorf("failed to enable lsp arp proxy for vip %s: %w", portName, err) klog.Error(err) return err } } if vip.Spec.ParentMac != "" { if vip.Spec.Type == util.SwitchLBRuleVip { - err = fmt.Errorf("invalid usage of vip") + err = errors.New("invalid usage of vip") klog.Error(err) return err } @@ -314,17 +315,17 @@ func (c *Controller) handleUpdateVirtualIP(key string) error { } // not support change if vip.Status.Mac != "" && vip.Status.Mac != vip.Spec.MacAddress { - err = fmt.Errorf("not support change mac of vip") + err = errors.New("not support change mac of vip") klog.Errorf("%v", err) return err } if vip.Status.V4ip != "" && vip.Status.V4ip != vip.Spec.V4ip { - err = fmt.Errorf("not support change v4 ip of vip") + err = errors.New("not support change v4 ip of vip") klog.Errorf("%v", err) return err } if vip.Status.V6ip != "" && vip.Status.V6ip != vip.Spec.V6ip { - err = fmt.Errorf("not support change v6 ip of vip") + err = errors.New("not support change v6 ip of vip") klog.Errorf("%v", err) return err } @@ -362,7 +363,7 @@ func (c *Controller) handleDelVirtualIP(vip *kubeovnv1.Vip) error { portName := ovs.PodNameToPortName(vip.Name, vip.Spec.Namespace, subnet.Spec.Provider) klog.Infof("delete vip arp proxy lsp %s", portName) if err := c.OVNNbClient.DeleteLogicalSwitchPort(portName); err != nil { - err = fmt.Errorf("failed to delete lsp %s: %v", vip.Name, err) + err = fmt.Errorf("failed to delete lsp %s: %w", vip.Name, err) klog.Error(err) return err } @@ -478,12 +479,12 @@ func (c *Controller) createOrUpdateVipCR(key, ns, subnet, v4ip, v6ip, mac, pV4ip ParentMac: pmac, }, }, metav1.CreateOptions{}); err != nil { - err := fmt.Errorf("failed to create crd vip '%s', %v", key, err) + err := fmt.Errorf("failed to create crd vip '%s', %w", key, err) klog.Error(err) return err } } else { - err := fmt.Errorf("failed to get crd vip '%s', %v", key, err) + err := fmt.Errorf("failed to get crd vip '%s', %w", key, err) klog.Error(err) return err } @@ -508,7 +509,7 @@ func (c *Controller) createOrUpdateVipCR(key, ns, subnet, v4ip, v6ip, mac, pV4ip vip.Status.Pmac = pmac vip.Status.Type = vip.Spec.Type if _, err := c.config.KubeOvnClient.KubeovnV1().Vips().Update(context.Background(), vip, metav1.UpdateOptions{}); err != nil { - err := fmt.Errorf("failed to update vip '%s', %v", key, err) + err := fmt.Errorf("failed to update vip '%s', %w", key, err) klog.Error(err) return err } diff --git a/pkg/controller/vpc.go b/pkg/controller/vpc.go index 3edf4c21afc6..493a45d1a210 100644 --- a/pkg/controller/vpc.go +++ b/pkg/controller/vpc.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" "net" "reflect" @@ -348,27 +349,27 @@ func (c *Controller) handleAddOrUpdateVpc(key string) error { } gatewayV4, gatewayV6 := util.SplitStringIP(joinSubnet.Spec.Gateway) if gatewayV4 != "" { - for tabele := range staticRouteMapping { + for table := range staticRouteMapping { staticTargetRoutes = append( staticTargetRoutes, &kubeovnv1.StaticRoute{ Policy: kubeovnv1.PolicyDst, CIDR: "0.0.0.0/0", NextHopIP: gatewayV4, - RouteTable: tabele, + RouteTable: table, }, ) } } if gatewayV6 != "" { - for tabele := range staticRouteMapping { + for table := range staticRouteMapping { staticTargetRoutes = append( staticTargetRoutes, &kubeovnv1.StaticRoute{ Policy: kubeovnv1.PolicyDst, CIDR: "::/0", NextHopIP: gatewayV6, - RouteTable: tabele, + RouteTable: table, }, ) } @@ -386,7 +387,7 @@ func (c *Controller) handleAddOrUpdateVpc(key string) error { nextHop = externalSubnet.Spec.Gateway if nextHop == "" { klog.Errorf("no available gateway address") - return fmt.Errorf("no available gateway address") + return errors.New("no available gateway address") } } if strings.Contains(nextHop, "/") { @@ -563,7 +564,7 @@ func (c *Controller) handleAddOrUpdateVpc(key string) error { return err } if externalSubnet.Spec.LogicalGateway { - klog.Infof("no need to hanlde external connection for logical gw external subnet %s", c.config.ExternalGatewaySwitch) + klog.Infof("no need to handle external connection for logical gw external subnet %s", c.config.ExternalGatewaySwitch) return nil } if !cachedVpc.Status.EnableExternal { @@ -664,7 +665,7 @@ func (c *Controller) handleAddOrUpdateVpc(key string) error { return nil } -func (c *Controller) addPolicyRouteToVpc(name string, policy *kubeovnv1.PolicyRoute, externalIDs map[string]string) error { +func (c *Controller) addPolicyRouteToVpc(vpcName string, policy *kubeovnv1.PolicyRoute, externalIDs map[string]string) error { var ( nextHops []string err error @@ -674,25 +675,25 @@ func (c *Controller) addPolicyRouteToVpc(name string, policy *kubeovnv1.PolicyRo nextHops = strings.Split(policy.NextHopIP, ",") } - if err = c.OVNNbClient.AddLogicalRouterPolicy(name, policy.Priority, policy.Match, string(policy.Action), nextHops, externalIDs); err != nil { - klog.Errorf("add policy route to vpc %s failed, %v", name, err) + if err = c.OVNNbClient.AddLogicalRouterPolicy(vpcName, policy.Priority, policy.Match, string(policy.Action), nextHops, externalIDs); err != nil { + klog.Errorf("add policy route to vpc %s failed, %v", vpcName, err) return err } return nil } -func (c *Controller) deletePolicyRouteFromVpc(name string, priority int, match string) error { +func (c *Controller) deletePolicyRouteFromVpc(vpcName string, priority int, match string) error { var ( vpc, cachedVpc *kubeovnv1.Vpc err error ) - if err = c.OVNNbClient.DeleteLogicalRouterPolicy(name, priority, match); err != nil { + if err = c.OVNNbClient.DeleteLogicalRouterPolicy(vpcName, priority, match); err != nil { klog.Error(err) return err } - cachedVpc, err = c.vpcsLister.Get(name) + cachedVpc, err = c.vpcsLister.Get(vpcName) if err != nil { if k8serrors.IsNotFound(err) { return nil @@ -1137,7 +1138,7 @@ func (c *Controller) handleAddVpcExternalSubnet(key, subnet string) error { } if len(chassises) == 0 { - err := fmt.Errorf("no external gw nodes") + err := errors.New("no external gw nodes") klog.Error(err) return err } @@ -1173,13 +1174,13 @@ func (c *Controller) handleAddVpcExternalSubnet(key, subnet string) error { } if _, err = c.config.KubeOvnClient.KubeovnV1().Vpcs().Patch(context.Background(), vpc.Name, types.MergePatchType, bytes, metav1.PatchOptions{}, "status"); err != nil { - err := fmt.Errorf("failed to patch vpc %s status, %v", vpc.Name, err) + err := fmt.Errorf("failed to patch vpc %s status, %w", vpc.Name, err) klog.Error(err) return err } } if _, err = c.ovnEipsLister.Get(lrpEipName); err != nil { - err := fmt.Errorf("failed to get ovn eip %s, %v", lrpEipName, err) + err := fmt.Errorf("failed to get ovn eip %s, %w", lrpEipName, err) klog.Error(err) return err } diff --git a/pkg/controller/vpc_dns.go b/pkg/controller/vpc_dns.go index 2541326f89c1..0925a6755b93 100644 --- a/pkg/controller/vpc_dns.go +++ b/pkg/controller/vpc_dns.go @@ -142,7 +142,7 @@ func (c *Controller) handleAddOrUpdateVPCDNS(key string) error { if !enableCoredns { time.Sleep(10 * time.Second) if !enableCoredns { - return fmt.Errorf("failed to add or update vpc-dns, not enabled") + return errors.New("failed to add or update vpc-dns, not enabled") } } @@ -163,55 +163,55 @@ func (c *Controller) handleAddOrUpdateVPCDNS(key string) error { if _, err = c.config.KubeOvnClient.KubeovnV1().VpcDnses().UpdateStatus(context.Background(), newVPCDNS, metav1.UpdateOptions{}); err != nil { - err := fmt.Errorf("failed to update vpc dns status, %v", err) + err := fmt.Errorf("failed to update vpc dns status, %w", err) klog.Error(err) } }() if len(corednsImage) == 0 { - err := fmt.Errorf("vpc-dns coredns image should be set") + err := errors.New("vpc-dns coredns image should be set") klog.Error(err) return err } if len(corednsVip) == 0 { - err := fmt.Errorf("vpc-dns corednsVip should be set") + err := errors.New("vpc-dns corednsVip should be set") klog.Error(err) return err } if _, err := c.vpcsLister.Get(vpcDNS.Spec.Vpc); err != nil { - err := fmt.Errorf("failed to get vpc '%s', err: %v", vpcDNS.Spec.Vpc, err) + err := fmt.Errorf("failed to get vpc '%s', err: %w", vpcDNS.Spec.Vpc, err) klog.Error(err) return err } if _, err := c.subnetsLister.Get(vpcDNS.Spec.Subnet); err != nil { - err := fmt.Errorf("failed to get subnet '%s', err: %v", vpcDNS.Spec.Subnet, err) + err := fmt.Errorf("failed to get subnet '%s', err: %w", vpcDNS.Spec.Subnet, err) klog.Error(err) return err } if err := c.checkOvnNad(); err != nil { - err := fmt.Errorf("failed to check nad, %v", err) + err := fmt.Errorf("failed to check nad, %w", err) klog.Error(err) return err } if err := c.checkVpcDNSDuplicated(vpcDNS); err != nil { - err = fmt.Errorf("failed to deploy %s, %v", vpcDNS.Name, err) + err = fmt.Errorf("failed to deploy %s, %w", vpcDNS.Name, err) klog.Error(err) return err } if err := c.createOrUpdateVpcDNSDep(vpcDNS); err != nil { - err = fmt.Errorf("failed to create or update vpc dns %s, %v", vpcDNS.Name, err) + err = fmt.Errorf("failed to create or update vpc dns %s, %w", vpcDNS.Name, err) klog.Error(err) return err } if err := c.createOrUpdateVpcDNSSlr(vpcDNS); err != nil { - err = fmt.Errorf("failed to create or update slr for vpc dns %s, %v", vpcDNS.Name, err) + err = fmt.Errorf("failed to create or update slr for vpc dns %s, %w", vpcDNS.Name, err) klog.Error(err) return err } @@ -224,14 +224,14 @@ func (c *Controller) handleDelVpcDNS(key string) error { name := genVpcDNSDpName(key) err := c.config.KubeClient.AppsV1().Deployments(c.config.PodNamespace).Delete(context.Background(), name, metav1.DeleteOptions{}) if err != nil && !k8serrors.IsNotFound(err) { - err := fmt.Errorf("failed to delete vpc dns deployment: %v", err) + err := fmt.Errorf("failed to delete vpc dns deployment: %w", err) klog.Error(err) return err } err = c.config.KubeOvnClient.KubeovnV1().SwitchLBRules().Delete(context.Background(), name, metav1.DeleteOptions{}) if err != nil && !k8serrors.IsNotFound(err) { - err := fmt.Errorf("failed to delete switch lb rule: %v", err) + err := fmt.Errorf("failed to delete switch lb rule: %w", err) klog.Error(err) return err } @@ -251,7 +251,7 @@ func (c *Controller) checkVpcDNSDuplicated(vpcDNS *kubeovnv1.VpcDns) error { if item.Status.Active && item.Name != vpcDNS.Name && item.Spec.Vpc == vpcDNS.Spec.Vpc { - err = fmt.Errorf("only one vpc-dns can be deployed in a vpc") + err = errors.New("only one vpc-dns can be deployed in a vpc") return err } } @@ -582,7 +582,7 @@ func (c *Controller) getDefaultCoreDNSImage() (string, error) { } } - return "", fmt.Errorf("coredns container no found") + return "", errors.New("coredns container no found") } func (c *Controller) initVpcDNSConfig() error { diff --git a/pkg/controller/vpc_nat.go b/pkg/controller/vpc_nat.go index 1213524cc66e..57b0eee160d2 100644 --- a/pkg/controller/vpc_nat.go +++ b/pkg/controller/vpc_nat.go @@ -13,7 +13,7 @@ var vpcNatImage = "" func (c *Controller) resyncVpcNatImage() { cm, err := c.configMapsLister.ConfigMaps(c.config.PodNamespace).Get(util.VpcNatConfig) if err != nil { - err = fmt.Errorf("failed to get ovn-vpc-nat-config, %v", err) + err = fmt.Errorf("failed to get ovn-vpc-nat-config, %w", err) klog.Error(err) return } diff --git a/pkg/controller/vpc_nat_gateway.go b/pkg/controller/vpc_nat_gateway.go index d24118da2b79..fb13f8f3f614 100644 --- a/pkg/controller/vpc_nat_gateway.go +++ b/pkg/controller/vpc_nat_gateway.go @@ -189,7 +189,7 @@ func (c *Controller) processNextWorkItem(processName string, queue workqueue.Rat return nil }(obj) if err != nil { - utilruntime.HandleError(fmt.Errorf("process: %s. err: %v", processName, err)) + utilruntime.HandleError(fmt.Errorf("process: %s. err: %w", processName, err)) queue.AddRateLimited(obj) return true } @@ -249,16 +249,16 @@ func (c *Controller) handleAddOrUpdateVpcNatGw(key string) error { klog.Infof("handle add/update vpc nat gateway %s", key) if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } if _, err := c.vpcsLister.Get(gw.Spec.Vpc); err != nil { - err = fmt.Errorf("failed to get vpc '%s', err: %v", gw.Spec.Vpc, err) + err = fmt.Errorf("failed to get vpc '%s', err: %w", gw.Spec.Vpc, err) klog.Error(err) return err } if _, err := c.subnetsLister.Get(gw.Spec.Subnet); err != nil { - err = fmt.Errorf("failed to get subnet '%s', err: %v", gw.Spec.Subnet, err) + err = fmt.Errorf("failed to get subnet '%s', err: %w", gw.Spec.Subnet, err) klog.Error(err) return err } @@ -289,7 +289,7 @@ func (c *Controller) handleAddOrUpdateVpcNatGw(key string) error { // if pod create successfully, will add initVpcNatGatewayQueue if _, err := c.config.KubeClient.AppsV1().StatefulSets(c.config.PodNamespace). Create(context.Background(), newSts, metav1.CreateOptions{}); err != nil { - err := fmt.Errorf("failed to create statefulset '%s', err: %v", newSts.Name, err) + err := fmt.Errorf("failed to create statefulset '%s', err: %w", newSts.Name, err) klog.Error(err) return err } @@ -301,7 +301,7 @@ func (c *Controller) handleAddOrUpdateVpcNatGw(key string) error { case needToUpdate: if _, err := c.config.KubeClient.AppsV1().StatefulSets(c.config.PodNamespace). Update(context.Background(), newSts, metav1.UpdateOptions{}); err != nil { - err := fmt.Errorf("failed to update statefulset '%s', err: %v", newSts.Name, err) + err := fmt.Errorf("failed to update statefulset '%s', err: %w", newSts.Name, err) klog.Error(err) return err } @@ -325,7 +325,7 @@ func (c *Controller) handleAddOrUpdateVpcNatGw(key string) error { } } if err := c.updateCrdNatGwLabels(key, gw.Spec.QoSPolicy); err != nil { - err := fmt.Errorf("failed to update nat gw %s: %v", gw.Name, err) + err := fmt.Errorf("failed to update nat gw %s: %w", gw.Name, err) klog.Error(err) return err } @@ -351,7 +351,7 @@ func (c *Controller) handleInitVpcNatGw(key string) error { } if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(key) @@ -362,7 +362,7 @@ func (c *Controller) handleInitVpcNatGw(key string) error { oriPod, err := c.getNatGwPod(key) if err != nil { - err := fmt.Errorf("failed to get nat gw %s pod: %v", gw.Name, err) + err := fmt.Errorf("failed to get nat gw %s pod: %w", gw.Name, err) klog.Error(err) return err } @@ -381,7 +381,7 @@ func (c *Controller) handleInitVpcNatGw(key string) error { natGwCreatedAT = pod.CreationTimestamp.Format("2006-01-02T15:04:05") klog.V(3).Infof("nat gw pod '%s' inited at %s", key, natGwCreatedAT) if err = c.execNatGwRules(pod, natGwInit, nil); err != nil { - err = fmt.Errorf("failed to init vpc nat gateway, %v", err) + err = fmt.Errorf("failed to init vpc nat gateway, %w", err) klog.Error(err) return err } @@ -401,7 +401,7 @@ func (c *Controller) handleInitVpcNatGw(key string) error { } if err := c.updateCrdNatGwLabels(gw.Name, gw.Spec.QoSPolicy); err != nil { - err := fmt.Errorf("failed to update nat gw %s: %v", gw.Name, err) + err := fmt.Errorf("failed to update nat gw %s: %w", gw.Name, err) klog.Error(err) return err } @@ -419,7 +419,7 @@ func (c *Controller) handleInitVpcNatGw(key string) error { } if _, err := c.config.KubeClient.CoreV1().Pods(pod.Namespace).Patch(context.Background(), pod.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{}, ""); err != nil { - err := fmt.Errorf("patch pod %s/%s failed %v", pod.Name, pod.Namespace, err) + err := fmt.Errorf("patch pod %s/%s failed %w", pod.Name, pod.Namespace, err) klog.Error(err) return err } @@ -428,7 +428,7 @@ func (c *Controller) handleInitVpcNatGw(key string) error { func (c *Controller) handleUpdateVpcFloatingIP(natGwKey string) error { if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(natGwKey) @@ -437,14 +437,14 @@ func (c *Controller) handleUpdateVpcFloatingIP(natGwKey string) error { // refresh exist fips if err := c.initCreateAt(natGwKey); err != nil { - err = fmt.Errorf("failed to init nat gw pod '%s' create at, %v", natGwKey, err) + err = fmt.Errorf("failed to init nat gw pod '%s' create at, %w", natGwKey, err) klog.Error(err) return err } fips, err := c.iptablesFipsLister.List(labels.SelectorFromSet(labels.Set{util.VpcNatGatewayNameLabel: natGwKey})) if err != nil { - err := fmt.Errorf("failed to get all fips, %v", err) + err := fmt.Errorf("failed to get all fips, %w", err) klog.Error(err) return err } @@ -463,7 +463,7 @@ func (c *Controller) handleUpdateVpcFloatingIP(natGwKey string) error { func (c *Controller) handleUpdateVpcEip(natGwKey string) error { if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(natGwKey) @@ -472,13 +472,13 @@ func (c *Controller) handleUpdateVpcEip(natGwKey string) error { // refresh exist fips if err := c.initCreateAt(natGwKey); err != nil { - err = fmt.Errorf("failed to init nat gw pod '%s' create at, %v", natGwKey, err) + err = fmt.Errorf("failed to init nat gw pod '%s' create at, %w", natGwKey, err) klog.Error(err) return err } eips, err := c.iptablesEipsLister.List(labels.Everything()) if err != nil { - err = fmt.Errorf("failed to get eip list, %v", err) + err = fmt.Errorf("failed to get eip list, %w", err) klog.Error(err) return err } @@ -496,7 +496,7 @@ func (c *Controller) handleUpdateVpcEip(natGwKey string) error { func (c *Controller) handleUpdateVpcSnat(natGwKey string) error { if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(natGwKey) @@ -505,13 +505,13 @@ func (c *Controller) handleUpdateVpcSnat(natGwKey string) error { // refresh exist snats if err := c.initCreateAt(natGwKey); err != nil { - err = fmt.Errorf("failed to init nat gw pod '%s' create at, %v", natGwKey, err) + err = fmt.Errorf("failed to init nat gw pod '%s' create at, %w", natGwKey, err) klog.Error(err) return err } snats, err := c.iptablesSnatRulesLister.List(labels.SelectorFromSet(labels.Set{util.VpcNatGatewayNameLabel: natGwKey})) if err != nil { - err = fmt.Errorf("failed to get all snats, %v", err) + err = fmt.Errorf("failed to get all snats, %w", err) klog.Error(err) return err } @@ -519,7 +519,7 @@ func (c *Controller) handleUpdateVpcSnat(natGwKey string) error { if snat.Status.Redo != natGwCreatedAT { klog.V(3).Infof("redo snat %s", snat.Name) if err = c.redoSnat(snat.Name, natGwCreatedAT, false); err != nil { - err = fmt.Errorf("failed to update eip '%s' to re-apply, %v", snat.Spec.EIP, err) + err = fmt.Errorf("failed to update eip '%s' to re-apply, %w", snat.Spec.EIP, err) klog.Error(err) return err } @@ -530,7 +530,7 @@ func (c *Controller) handleUpdateVpcSnat(natGwKey string) error { func (c *Controller) handleUpdateVpcDnat(natGwKey string) error { if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(natGwKey) @@ -539,14 +539,14 @@ func (c *Controller) handleUpdateVpcDnat(natGwKey string) error { // refresh exist dnats if err := c.initCreateAt(natGwKey); err != nil { - err = fmt.Errorf("failed to init nat gw pod '%s' create at, %v", natGwKey, err) + err = fmt.Errorf("failed to init nat gw pod '%s' create at, %w", natGwKey, err) klog.Error(err) return err } dnats, err := c.iptablesDnatRulesLister.List(labels.SelectorFromSet(labels.Set{util.VpcNatGatewayNameLabel: natGwKey})) if err != nil { - err = fmt.Errorf("failed to get all dnats, %v", err) + err = fmt.Errorf("failed to get all dnats, %w", err) klog.Error(err) return err } @@ -554,7 +554,7 @@ func (c *Controller) handleUpdateVpcDnat(natGwKey string) error { if dnat.Status.Redo != natGwCreatedAT { klog.V(3).Infof("redo dnat %s", dnat.Name) if err = c.redoDnat(dnat.Name, natGwCreatedAT, false); err != nil { - err := fmt.Errorf("failed to update dnat '%s' to redo, %v", dnat.Name, err) + err := fmt.Errorf("failed to update dnat '%s' to redo, %w", dnat.Name, err) klog.Error(err) return err } @@ -607,7 +607,7 @@ func (c *Controller) handleUpdateNatGwSubnetRoute(natGwKey string) error { } if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(natGwKey) @@ -616,7 +616,7 @@ func (c *Controller) handleUpdateNatGwSubnetRoute(natGwKey string) error { cachedPod, err := c.getNatGwPod(natGwKey) if err != nil { - err = fmt.Errorf("failed to get nat gw '%s' pod, %v", natGwKey, err) + err = fmt.Errorf("failed to get nat gw '%s' pod, %w", natGwKey, err) klog.Error(err) return err } @@ -624,13 +624,13 @@ func (c *Controller) handleUpdateNatGwSubnetRoute(natGwKey string) error { v4InternalGw, _, err := c.GetGwBySubnet(gw.Spec.Subnet) if err != nil { - err = fmt.Errorf("failed to get gw, err: %v", err) + err = fmt.Errorf("failed to get gw, err: %w", err) klog.Error(err) return err } vpc, err := c.vpcsLister.Get(gw.Spec.Vpc) if err != nil { - err = fmt.Errorf("failed to get vpc, err: %v", err) + err = fmt.Errorf("failed to get vpc, err: %w", err) klog.Error(err) return err } @@ -641,7 +641,7 @@ func (c *Controller) handleUpdateNatGwSubnetRoute(natGwKey string) error { for _, s := range vpc.Status.Subnets { subnet, err := c.subnetsLister.Get(s) if err != nil { - err = fmt.Errorf("failed to get subnet, err: %v", err) + err = fmt.Errorf("failed to get subnet, err: %w", err) klog.Error(err) return err } @@ -671,7 +671,7 @@ func (c *Controller) handleUpdateNatGwSubnetRoute(natGwKey string) error { } if len(rules) > 0 { if err = c.execNatGwRules(pod, natGwSubnetRouteAdd, rules); err != nil { - err = fmt.Errorf("failed to exec nat gateway rule, err: %v", err) + err = fmt.Errorf("failed to exec nat gateway rule, err: %w", err) klog.Error(err) return err } @@ -681,7 +681,7 @@ func (c *Controller) handleUpdateNatGwSubnetRoute(natGwKey string) error { if len(toBeDelCIDRs) > 0 { for _, cidr := range toBeDelCIDRs { if err = c.execNatGwRules(pod, natGwSubnetRouteDel, []string{cidr}); err != nil { - err = fmt.Errorf("failed to exec nat gateway rule, err: %v", err) + err = fmt.Errorf("failed to exec nat gateway rule, err: %w", err) klog.Error(err) return err } @@ -701,7 +701,7 @@ func (c *Controller) handleUpdateNatGwSubnetRoute(natGwKey string) error { } if _, err := c.config.KubeClient.CoreV1().Pods(pod.Namespace).Patch(context.Background(), pod.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{}, ""); err != nil { - err = fmt.Errorf("patch pod %s/%s failed %v", pod.Name, pod.Namespace, err) + err = fmt.Errorf("patch pod %s/%s failed %w", pod.Name, pod.Namespace, err) klog.Error(err) return err } @@ -889,10 +889,10 @@ func (c *Controller) getNatGwPod(name string) (*corev1.Pod, error) { return nil, k8serrors.NewNotFound(v1.Resource("pod"), name) case len(pods) != 1: time.Sleep(5 * time.Second) - return nil, fmt.Errorf("too many pod") + return nil, errors.New("too many pod") case pods[0].Status.Phase != corev1.PodRunning: time.Sleep(5 * time.Second) - return nil, fmt.Errorf("pod is not active now") + return nil, errors.New("pod is not active now") } return pods[0], nil @@ -914,7 +914,7 @@ func (c *Controller) initCreateAt(key string) (err error) { func (c *Controller) updateCrdNatGwLabels(key, qos string) error { gw, err := c.vpcNatGatewayLister.Get(key) if err != nil { - errMsg := fmt.Errorf("failed to get vpc nat gw '%s', %v", key, err) + errMsg := fmt.Errorf("failed to get vpc nat gw '%s', %w", key, err) klog.Error(errMsg) return errMsg } @@ -1109,7 +1109,7 @@ func (c *Controller) execNatGwQoSInPod( addRules = append(addRules, rule) if err = c.execNatGwRules(gwPod, operation, addRules); err != nil { - err = fmt.Errorf("failed to exec nat gateway rule, err: %v", err) + err = fmt.Errorf("failed to exec nat gateway rule, err: %w", err) klog.Error(err) return err } @@ -1120,7 +1120,7 @@ func (c *Controller) initVpcNatGw() error { klog.Infof("init all vpc nat gateways") gws, err := c.vpcNatGatewayLister.List(labels.Everything()) if err != nil { - err = fmt.Errorf("failed to get vpc nat gw list, %v", err) + err = fmt.Errorf("failed to get vpc nat gw list, %w", err) klog.Error(err) return err } @@ -1129,7 +1129,7 @@ func (c *Controller) initVpcNatGw() error { } if vpcNatEnabled != "true" { - err := fmt.Errorf("iptables nat gw not enable") + err := errors.New("iptables nat gw not enable") klog.Warning(err) return nil } @@ -1138,7 +1138,7 @@ func (c *Controller) initVpcNatGw() error { pod, err := c.getNatGwPod(gw.Name) if err != nil { // the nat gw maybe deleted - err := fmt.Errorf("failed to get nat gw %s pod: %v", gw.Name, err) + err := fmt.Errorf("failed to get nat gw %s pod: %w", gw.Name, err) klog.Error(err) continue } diff --git a/pkg/controller/vpc_nat_gw_eip.go b/pkg/controller/vpc_nat_gw_eip.go index 9e406239f437..ef0661d7d963 100644 --- a/pkg/controller/vpc_nat_gw_eip.go +++ b/pkg/controller/vpc_nat_gw_eip.go @@ -2,6 +2,7 @@ package controller import ( "context" + "errors" "fmt" "net" "strings" @@ -211,7 +212,7 @@ func (c *Controller) handleAddIptablesEip(key string) error { } if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(key) @@ -258,7 +259,7 @@ func (c *Controller) handleAddIptablesEip(key string) error { } addrV4, err := util.GetIPAddrWithMask(v4ip, eipV4Cidr) if err != nil { - err = fmt.Errorf("failed to get eip %s with mask by cidr %s: %v", v4ip, eipV4Cidr, err) + err = fmt.Errorf("failed to get eip %s with mask by cidr %s: %w", v4ip, eipV4Cidr, err) klog.Error(err) return err } @@ -364,7 +365,7 @@ func (c *Controller) handleUpdateIptablesEip(key string) error { } // make sure vpc nat enabled if vpcNatEnabled != "true" { - err := fmt.Errorf("iptables nat gw not enable") + err := errors.New("iptables nat gw not enable") klog.Error(err) return err } @@ -414,7 +415,7 @@ func (c *Controller) handleUpdateIptablesEip(key string) error { } addrV4, err := util.GetIPAddrWithMask(cachedEip.Status.IP, v4Cidr) if err != nil { - err = fmt.Errorf("failed to get eip %s with mask by cidr %s: %v", cachedEip.Status.IP, v4Cidr, err) + err = fmt.Errorf("failed to get eip %s with mask by cidr %s: %w", cachedEip.Status.IP, v4Cidr, err) klog.Error(err) return err } @@ -488,7 +489,7 @@ func (c *Controller) deleteEipInPod(dp, v4Cidr string) error { return nil } -func (c *Controller) addOrUpdateEIPBandtithLimitRules(eip *kubeovnv1.IptablesEIP, v4ip string, rules kubeovnv1.QoSPolicyBandwidthLimitRules) error { +func (c *Controller) addOrUpdateEIPBandwidthLimitRules(eip *kubeovnv1.IptablesEIP, v4ip string, rules kubeovnv1.QoSPolicyBandwidthLimitRules) error { var err error for _, rule := range rules { if err = c.addEipQoSInPod(eip.Spec.NatGwDp, v4ip, rule.Direction, rule.Priority, rule.RateMax, rule.BurstMax); err != nil { @@ -525,7 +526,7 @@ func (c *Controller) addEipQoS(eip *kubeovnv1.IptablesEIP, v4ip string) error { } } } - return c.addOrUpdateEIPBandtithLimitRules(eip, v4ip, qosPolicy.Status.BandwidthLimitRules) + return c.addOrUpdateEIPBandwidthLimitRules(eip, v4ip, qosPolicy.Status.BandwidthLimitRules) } func (c *Controller) delEIPBandtithLimitRules(eip *kubeovnv1.IptablesEIP, v4ip string, rules kubeovnv1.QoSPolicyBandwidthLimitRules) error { @@ -656,7 +657,7 @@ func (c *Controller) eipChangeIP(eip *kubeovnv1.IptablesEIP) bool { func (c *Controller) GetGwBySubnet(name string) (string, string, error) { subnet, err := c.subnetsLister.Get(name) if err != nil { - err = fmt.Errorf("faile to get subnet %q: %v", name, err) + err = fmt.Errorf("faile to get subnet %q: %w", name, err) klog.Error(err) return "", "", err } @@ -695,7 +696,7 @@ func (c *Controller) createOrUpdateEipCR(key, v4ip, v6ip, mac, natGwDp, qos, ext }, }, metav1.CreateOptions{}) if err != nil { - errMsg := fmt.Errorf("failed to create eip crd %s, %v", key, err) + errMsg := fmt.Errorf("failed to create eip crd %s, %w", key, err) klog.Error(errMsg) return errMsg } @@ -708,7 +709,7 @@ func (c *Controller) createOrUpdateEipCR(key, v4ip, v6ip, mac, natGwDp, qos, ext eip.Spec.NatGwDp = natGwDp eip.Spec.MacAddress = mac if _, err := c.config.KubeOvnClient.KubeovnV1().IptablesEIPs().Update(context.Background(), eip, metav1.UpdateOptions{}); err != nil { - errMsg := fmt.Errorf("failed to update eip crd %s, %v", key, err) + errMsg := fmt.Errorf("failed to update eip crd %s, %w", key, err) klog.Error(errMsg) return errMsg } @@ -934,7 +935,7 @@ func (c *Controller) patchEipStatus(key, v4ip, redo, qos string, ready bool) err nat, err := c.getIptablesEipNat(oriEip.Spec.V4ip) if err != nil { - err := fmt.Errorf("failed to get eip nat") + err := errors.New("failed to get eip nat") klog.Error(err) return err } diff --git a/pkg/controller/vpc_nat_gw_nat.go b/pkg/controller/vpc_nat_gw_nat.go index 5d3d468c9012..7adb1e1b894d 100644 --- a/pkg/controller/vpc_nat_gw_nat.go +++ b/pkg/controller/vpc_nat_gw_nat.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" "time" @@ -488,7 +489,7 @@ func (c *Controller) handleAddIptablesFip(key string) error { } if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(key) @@ -503,7 +504,7 @@ func (c *Controller) handleAddIptablesFip(key string) error { // get eip eipName := fip.Spec.EIP if eipName == "" { - return fmt.Errorf("failed to create fip rule, should set eip") + return errors.New("failed to create fip rule, should set eip") } eip, err := c.GetEip(eipName) if err != nil { @@ -512,7 +513,7 @@ func (c *Controller) handleAddIptablesFip(key string) error { } if err = c.fipTryUseEip(key, eip.Spec.V4ip); err != nil { - err = fmt.Errorf("failed to create fip %s, %v", key, err) + err = fmt.Errorf("failed to create fip %s, %w", key, err) klog.Error(err) return err } @@ -595,11 +596,11 @@ func (c *Controller) handleUpdateIptablesFip(key string) error { klog.V(3).Infof("handle update fip %s", key) // add or update should make sure vpc nat enabled if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } eipName := cachedFip.Spec.EIP if eipName == "" { - return fmt.Errorf("failed to update fip rule, should set eip") + return errors.New("failed to update fip rule, should set eip") } eip, err := c.GetEip(eipName) if err != nil { @@ -608,7 +609,7 @@ func (c *Controller) handleUpdateIptablesFip(key string) error { } if err = c.fipTryUseEip(key, eip.Spec.V4ip); err != nil { - err = fmt.Errorf("failed to update fip %s, %v", key, err) + err = fmt.Errorf("failed to update fip %s, %w", key, err) klog.Error(err) return err } @@ -690,7 +691,7 @@ func (c *Controller) handleAddIptablesDnatRule(key string) error { } if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(key) @@ -704,7 +705,7 @@ func (c *Controller) handleAddIptablesDnatRule(key string) error { klog.V(3).Infof("handle add iptables dnat %s", key) eipName := dnat.Spec.EIP if eipName == "" { - return fmt.Errorf("failed to create dnat rule, should set eip") + return errors.New("failed to create dnat rule, should set eip") } eip, err := c.GetEip(eipName) @@ -780,7 +781,7 @@ func (c *Controller) handleUpdateIptablesDnatRule(key string) error { klog.V(3).Infof("handle update dnat %s", key) eipName := cachedDnat.Spec.EIP if eipName == "" { - return fmt.Errorf("failed to update fip rule, should set eip") + return errors.New("failed to update fip rule, should set eip") } eip, err := c.GetEip(eipName) if err != nil { @@ -793,7 +794,7 @@ func (c *Controller) handleUpdateIptablesDnatRule(key string) error { } // add or update should make sure vpc nat enabled if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } if err = c.deleteDnatInPod(cachedDnat.Status.NatGwDp, cachedDnat.Status.Protocol, @@ -878,7 +879,7 @@ func (c *Controller) handleAddIptablesSnatRule(key string) error { } if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } c.vpcNatGwKeyMutex.LockKey(key) @@ -892,7 +893,7 @@ func (c *Controller) handleAddIptablesSnatRule(key string) error { klog.V(3).Infof("handle add iptables snat %s", key) eipName := snat.Spec.EIP if eipName == "" { - return fmt.Errorf("failed to create snat rule, should set eip") + return errors.New("failed to create snat rule, should set eip") } eip, err := c.GetEip(eipName) @@ -975,7 +976,7 @@ func (c *Controller) handleUpdateIptablesSnatRule(key string) error { klog.V(3).Infof("handle update snat %s", key) eipName := cachedSnat.Spec.EIP if eipName == "" { - return fmt.Errorf("failed to update fip rule, should set eip") + return errors.New("failed to update fip rule, should set eip") } eip, err := c.GetEip(eipName) if err != nil { @@ -985,7 +986,7 @@ func (c *Controller) handleUpdateIptablesSnatRule(key string) error { // add or update should make sure vpc nat enabled if vpcNatEnabled != "true" { - return fmt.Errorf("iptables nat gw not enable") + return errors.New("iptables nat gw not enable") } klog.V(3).Infof("snat change ip, old ip %s, new ip %s", cachedSnat.Status.V4ip, eip.Status.IP) @@ -1381,18 +1382,18 @@ func (c *Controller) redoFip(key, redo string, eipReady bool) error { if redo != "" && redo != fip.Status.Redo { if !eipReady { if err = c.patchEipLabel(fip.Spec.EIP); err != nil { - err = fmt.Errorf("failed to patch eip %s, %v", fip.Spec.EIP, err) + err = fmt.Errorf("failed to patch eip %s, %w", fip.Spec.EIP, err) klog.Error(err) return err } if err = c.patchEipStatus(fip.Spec.EIP, "", redo, "", false); err != nil { - err = fmt.Errorf("failed to patch eip %s, %v", fip.Spec.EIP, err) + err = fmt.Errorf("failed to patch eip %s, %w", fip.Spec.EIP, err) klog.Error(err) return err } } if err = c.patchFipStatus(key, "", "", "", redo, false); err != nil { - err = fmt.Errorf("failed to patch fip %s, %v", fip.Name, err) + err = fmt.Errorf("failed to patch fip %s, %w", fip.Name, err) klog.Error(err) return err } @@ -1527,13 +1528,13 @@ func (c *Controller) redoDnat(key, redo string, eipReady bool) error { if redo != "" && redo != dnat.Status.Redo { if !eipReady { if err = c.patchEipStatus(dnat.Spec.EIP, "", redo, "", false); err != nil { - err = fmt.Errorf("failed to patch eip %s, %v", dnat.Spec.EIP, err) + err = fmt.Errorf("failed to patch eip %s, %w", dnat.Spec.EIP, err) klog.Error(err) return err } } if err = c.patchDnatStatus(key, "", "", "", redo, false); err != nil { - err = fmt.Errorf("failed to patch dnat %s, %v", key, err) + err = fmt.Errorf("failed to patch dnat %s, %w", key, err) klog.Error(err) return err } @@ -1660,13 +1661,13 @@ func (c *Controller) redoSnat(key, redo string, eipReady bool) error { if redo != "" && redo != snat.Status.Redo { if !eipReady { if err = c.patchEipStatus(snat.Spec.EIP, "", redo, "", false); err != nil { - err = fmt.Errorf("failed to patch eip %s, %v", snat.Spec.EIP, err) + err = fmt.Errorf("failed to patch eip %s, %w", snat.Spec.EIP, err) klog.Error(err) return err } } if err = c.patchSnatStatus(key, "", "", "", redo, false); err != nil { - err = fmt.Errorf("failed to patch snat %s, %v", key, err) + err = fmt.Errorf("failed to patch snat %s, %w", key, err) klog.Error(err) return err } diff --git a/pkg/controller/workqueue_metrics.go b/pkg/controller/workqueue_metrics.go deleted file mode 100644 index eebb6217074e..000000000000 --- a/pkg/controller/workqueue_metrics.go +++ /dev/null @@ -1,170 +0,0 @@ -/* -Copyright 2018 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. -*/ - -// This file comes from sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go - -package controller - -import ( - "github.com/prometheus/client_golang/prometheus" - "k8s.io/client-go/util/workqueue" -) - -// This file is copied and adapted from k8s.io/kubernetes/pkg/util/workqueue/prometheus -// which registers metrics to the default prometheus Registry. We require very -// similar functionality, but must register metrics to a different Registry. - -func InitWorkQueueMetrics() { - workqueue.SetProvider(workqueueMetricsProvider{}) -} - -func registerWorkqueueMetric(c prometheus.Collector, _, _ string) { - prometheus.MustRegister(c) -} - -type workqueueMetricsProvider struct{} - -func (workqueueMetricsProvider) NewDepthMetric(queue string) workqueue.GaugeMetric { - const name = "workqueue_depth" - m := prometheus.NewGauge(prometheus.GaugeOpts{ - Name: name, - Help: "Current depth of workqueue", - ConstLabels: prometheus.Labels{"name": queue}, - }) - registerWorkqueueMetric(m, name, queue) - return m -} - -func (workqueueMetricsProvider) NewAddsMetric(queue string) workqueue.CounterMetric { - const name = "workqueue_adds_total" - m := prometheus.NewCounter(prometheus.CounterOpts{ - Name: name, - Help: "Total number of adds handled by workqueue", - ConstLabels: prometheus.Labels{"name": queue}, - }) - registerWorkqueueMetric(m, name, queue) - return m -} - -func (workqueueMetricsProvider) NewLatencyMetric(queue string) workqueue.HistogramMetric { - const name = "workqueue_queue_duration_seconds" - m := prometheus.NewHistogram(prometheus.HistogramOpts{ - Name: name, - Help: "How long in seconds an item stays in workqueue before being requested.", - ConstLabels: prometheus.Labels{"name": queue}, - Buckets: prometheus.ExponentialBuckets(10e-9, 10, 10), - }) - registerWorkqueueMetric(m, name, queue) - return m -} - -func (workqueueMetricsProvider) NewWorkDurationMetric(queue string) workqueue.HistogramMetric { - const name = "workqueue_work_duration_seconds" - m := prometheus.NewHistogram(prometheus.HistogramOpts{ - Name: name, - Help: "How long in seconds processing an item from workqueue takes.", - ConstLabels: prometheus.Labels{"name": queue}, - Buckets: prometheus.ExponentialBuckets(10e-9, 10, 10), - }) - registerWorkqueueMetric(m, name, queue) - return m -} - -func (workqueueMetricsProvider) NewUnfinishedWorkSecondsMetric(queue string) workqueue.SettableGaugeMetric { - const name = "workqueue_unfinished_work_seconds" - m := prometheus.NewGauge(prometheus.GaugeOpts{ - Name: name, - Help: "How many seconds of work has done that " + - "is in progress and hasn't been observed by work_duration. Large " + - "values indicate stuck threads. One can deduce the number of stuck " + - "threads by observing the rate at which this increases.", - ConstLabels: prometheus.Labels{"name": queue}, - }) - registerWorkqueueMetric(m, name, queue) - return m -} - -func (workqueueMetricsProvider) NewLongestRunningProcessorSecondsMetric(queue string) workqueue.SettableGaugeMetric { - const name = "workqueue_longest_running_processor_seconds" - m := prometheus.NewGauge(prometheus.GaugeOpts{ - Name: name, - Help: "How many seconds has the longest running " + - "processor for workqueue been running.", - ConstLabels: prometheus.Labels{"name": queue}, - }) - registerWorkqueueMetric(m, name, queue) - return m -} - -func (workqueueMetricsProvider) NewRetriesMetric(queue string) workqueue.CounterMetric { - const name = "workqueue_retries_total" - m := prometheus.NewCounter(prometheus.CounterOpts{ - Name: name, - Help: "Total number of retries handled by workqueue", - ConstLabels: prometheus.Labels{"name": queue}, - }) - registerWorkqueueMetric(m, name, queue) - return m -} - -// TODO(abursavich): Remove the following deprecated metrics when they are -// removed from k8s.io/client-go/util/workqueue. - -func (workqueueMetricsProvider) NewDeprecatedLongestRunningProcessorMicrosecondsMetric(queue string) workqueue.SettableGaugeMetric { - const name = "workqueue_longest_running_processor_microseconds" - m := prometheus.NewGauge(prometheus.GaugeOpts{ - Name: name, - Help: "(Deprecated) How many microseconds has the longest running " + - "processor for workqueue been running.", - ConstLabels: prometheus.Labels{"name": queue}, - }) - registerWorkqueueMetric(m, name, queue) - return m -} - -// NOTE: The following deprecated metrics are noops because they were never -// included in controller-runtime. - -func (workqueueMetricsProvider) NewDeprecatedDepthMetric(_ string) workqueue.GaugeMetric { - return noopMetric{} -} - -func (workqueueMetricsProvider) NewDeprecatedAddsMetric(_ string) workqueue.CounterMetric { - return noopMetric{} -} - -func (workqueueMetricsProvider) NewDeprecatedLatencyMetric(_ string) workqueue.SummaryMetric { - return noopMetric{} -} - -func (workqueueMetricsProvider) NewDeprecatedWorkDurationMetric(_ string) workqueue.SummaryMetric { - return noopMetric{} -} - -func (workqueueMetricsProvider) NewDeprecatedUnfinishedWorkSecondsMetric(_ string) workqueue.SettableGaugeMetric { - return noopMetric{} -} - -func (workqueueMetricsProvider) NewDeprecatedRetriesMetric(_ string) workqueue.CounterMetric { - return noopMetric{} -} - -type noopMetric struct{} - -func (noopMetric) Inc() {} -func (noopMetric) Dec() {} -func (noopMetric) Set(float64) {} -func (noopMetric) Observe(float64) {} diff --git a/pkg/daemon/config.go b/pkg/daemon/config.go index 96daa47cbfde..276ce85a2c32 100644 --- a/pkg/daemon/config.go +++ b/pkg/daemon/config.go @@ -49,7 +49,8 @@ type Configuration struct { EncapChecksum bool EnablePprof bool MacLearningFallback bool - PprofPort int + PprofPort int32 + SecureServing bool NetworkType string CniConfDir string CniConfFile string @@ -62,8 +63,8 @@ type Configuration struct { EnableArpDetectIPConflict bool KubeletDir string EnableVerboseConnCheck bool - TCPConnCheckPort int - UDPConnCheckPort int + TCPConnCheckPort int32 + UDPConnCheckPort int32 EnableTProxy bool OVSVsctlConcurrency int32 } @@ -86,7 +87,8 @@ func ParseFlags() *Configuration { argNodeSwitch = pflag.String("node-switch", "join", "The name of node gateway switch which help node to access pod network") argEncapChecksum = pflag.Bool("encap-checksum", true, "Enable checksum") argEnablePprof = pflag.Bool("enable-pprof", false, "Enable pprof") - argPprofPort = pflag.Int("pprof-port", 10665, "The port to get profiling data") + argPprofPort = pflag.Int32("pprof-port", 10665, "The port to get profiling data") + argSecureServing = pflag.Bool("secure-serving", false, "Enable secure serving") argMacLearningFallback = pflag.Bool("mac-learning-fallback", false, "Fallback to the legacy MAC learning mode") argsNetworkType = pflag.String("network-type", util.NetworkTypeGeneve, "Tunnel encapsulation protocol in overlay networks") @@ -101,8 +103,8 @@ func ParseFlags() *Configuration { argEnableArpDetectIPConflict = pflag.Bool("enable-arp-detect-ip-conflict", true, "Whether to support arp detect ip conflict in vlan network") argKubeletDir = pflag.String("kubelet-dir", "/var/lib/kubelet", "Path of the kubelet dir, default: /var/lib/kubelet") argEnableVerboseConnCheck = pflag.Bool("enable-verbose-conn-check", false, "enable TCP/UDP connectivity check listen port") - argTCPConnectivityCheckPort = pflag.Int("tcp-conn-check-port", 8100, "TCP connectivity Check Port") - argUDPConnectivityCheckPort = pflag.Int("udp-conn-check-port", 8101, "UDP connectivity Check Port") + argTCPConnectivityCheckPort = pflag.Int32("tcp-conn-check-port", 8100, "TCP connectivity Check Port") + argUDPConnectivityCheckPort = pflag.Int32("udp-conn-check-port", 8101, "UDP connectivity Check Port") argEnableTProxy = pflag.Bool("enable-tproxy", false, "enable tproxy for vpc pod liveness or readiness probe") argOVSVsctlConcurrency = pflag.Int32("ovs-vsctl-concurrency", 100, "concurrency limit of ovs-vsctl") ) @@ -138,6 +140,7 @@ func ParseFlags() *Configuration { OvsSocket: *argOvsSocket, KubeConfigFile: *argKubeConfigFile, EnablePprof: *argEnablePprof, + SecureServing: *argSecureServing, PprofPort: *argPprofPort, MacLearningFallback: *argMacLearningFallback, NodeName: strings.ToLower(*argNodeName), @@ -172,7 +175,7 @@ func (config *Configuration) Init(nicBridgeMappings map[string]string) error { klog.Info("node name not specified in environment variables, fall back to the hostname") hostname, err := os.Hostname() if err != nil { - return fmt.Errorf("failed to get hostname: %v", err) + return fmt.Errorf("failed to get hostname: %w", err) } config.NodeName = strings.ToLower(hostname) } @@ -230,11 +233,11 @@ func (config *Configuration) initNicConfig(nicBridgeMappings map[string]string) } srcIPs, err := getSrcIPsByRoutes(iface) if err != nil { - return fmt.Errorf("failed to get src IPs by routes on interface %s: %v", iface.Name, err) + return fmt.Errorf("failed to get src IPs by routes on interface %s: %w", iface.Name, err) } addrs, err := iface.Addrs() if err != nil { - return fmt.Errorf("failed to get iface addr. %v", err) + return fmt.Errorf("failed to get iface addr. %w", err) } for _, addr := range addrs { _, ipCidr, err := net.ParseCIDR(addr.String()) diff --git a/pkg/daemon/config_linux.go b/pkg/daemon/config_linux.go index eeadc6cdb19d..e53fe42f9a97 100644 --- a/pkg/daemon/config_linux.go +++ b/pkg/daemon/config_linux.go @@ -13,11 +13,11 @@ const defaultBindSocket = "/run/openvswitch/kube-ovn-daemon.sock" func getSrcIPsByRoutes(iface *net.Interface) ([]string, error) { link, err := netlink.LinkByName(iface.Name) if err != nil { - return nil, fmt.Errorf("failed to get link %s: %v", iface.Name, err) + return nil, fmt.Errorf("failed to get link %s: %w", iface.Name, err) } routes, err := netlink.RouteList(link, netlink.FAMILY_ALL) if err != nil { - return nil, fmt.Errorf("failed to get routes on link %s: %v", iface.Name, err) + return nil, fmt.Errorf("failed to get routes on link %s: %w", iface.Name, err) } srcIPs := make([]string, 0, 2) @@ -38,7 +38,7 @@ func getIfaceByIP(ip string) (string, int, error) { for _, link := range links { addrs, err := netlink.AddrList(link, netlink.FAMILY_ALL) if err != nil { - return "", 0, fmt.Errorf("failed to get addresses of link %s: %v", link.Attrs().Name, err) + return "", 0, fmt.Errorf("failed to get addresses of link %s: %w", link.Attrs().Name, err) } for _, addr := range addrs { if addr.IPNet.Contains(net.ParseIP(ip)) && addr.IP.String() == ip { diff --git a/pkg/daemon/controller.go b/pkg/daemon/controller.go index c178c4e4067c..a3c18db22cc5 100644 --- a/pkg/daemon/controller.go +++ b/pkg/daemon/controller.go @@ -244,7 +244,7 @@ func (c *Controller) processNextDeleteProviderNetworkWorkItem() bool { return nil } if err := c.handleDeleteProviderNetwork(pn); err != nil { - return fmt.Errorf("error syncing '%s': %v, requeuing", pn.Name, err) + return fmt.Errorf("error syncing '%s': %w, requeuing", pn.Name, err) } c.deleteProviderNetworkQueue.Forget(obj) return nil @@ -590,7 +590,7 @@ func (c *Controller) markAndCleanInternalPort() error { // Remove ovs port output, err := ovs.Exec(ovs.IfExists, "--with-iface", "del-port", "br-int", portName) if err != nil { - return fmt.Errorf("failed to delete ovs port %v, %q", err, output) + return fmt.Errorf("failed to delete ovs port %w, %q", err, output) } } } diff --git a/pkg/daemon/controller_linux.go b/pkg/daemon/controller_linux.go index 7eb9ec7ca2d9..938047c0d7b1 100644 --- a/pkg/daemon/controller_linux.go +++ b/pkg/daemon/controller_linux.go @@ -45,11 +45,11 @@ type ControllerRuntime struct { func evalCommandSymlinks(cmd string) (string, error) { path, err := exec.LookPath(cmd) if err != nil { - return "", fmt.Errorf("failed to search for command %q: %v", cmd, err) + return "", fmt.Errorf("failed to search for command %q: %w", cmd, err) } file, err := filepath.EvalSymlinks(path) if err != nil { - return "", fmt.Errorf("failed to read evaluate symbolic links for file %q: %v", path, err) + return "", fmt.Errorf("failed to read evaluate symbolic links for file %q: %w", path, err) } return file, nil @@ -232,7 +232,7 @@ func (c *Controller) reconcileRouters(event *subnetEvent) error { gateway, ok := node.Annotations[util.GatewayAnnotation] if !ok { klog.Errorf("annotation for node %s ovn.kubernetes.io/gateway not exists", node.Name) - return fmt.Errorf("annotation for node ovn.kubernetes.io/gateway not exists") + return errors.New("annotation for node ovn.kubernetes.io/gateway not exists") } nic, err := netlink.LinkByName(util.NodeNic) if err != nil { diff --git a/pkg/daemon/gateway.go b/pkg/daemon/gateway.go index d13a15bee8d8..5c3af620a492 100644 --- a/pkg/daemon/gateway.go +++ b/pkg/daemon/gateway.go @@ -64,20 +64,20 @@ func (c *Controller) setICGateway() error { if enable == "true" { icEnabled, err := ovs.Exec(ovs.IfExists, "get", "open", ".", "external_ids:ovn-is-interconn") if err != nil { - return fmt.Errorf("failed to get if ic enabled, %v", err) + return fmt.Errorf("failed to get if ic enabled, %w", err) } if strings.Trim(icEnabled, "\"") != "true" { if _, err := ovs.Exec("set", "open", ".", "external_ids:ovn-is-interconn=true"); err != nil { - return fmt.Errorf("failed to enable ic gateway, %v", err) + return fmt.Errorf("failed to enable ic gateway, %w", err) } output, err := exec.Command("/usr/share/ovn/scripts/ovn-ctl", "restart_controller").CombinedOutput() if err != nil { - return fmt.Errorf("failed to restart ovn-controller, %v, %q", err, output) + return fmt.Errorf("failed to restart ovn-controller, %w, %q", err, output) } } } else { if _, err := ovs.Exec("set", "open", ".", "external_ids:ovn-is-interconn=false"); err != nil { - return fmt.Errorf("failed to disable ic gateway, %v", err) + return fmt.Errorf("failed to disable ic gateway, %w", err) } } return nil @@ -271,8 +271,7 @@ func (c *Controller) getTProxyConditionPod(needSort bool) ([]*v1.Pod, error) { subnet, err := c.subnetsLister.Get(subnetName) if err != nil { - err = fmt.Errorf("failed to get subnet '%s', err: %v", subnetName, err) - return nil, err + return nil, fmt.Errorf("failed to get subnet '%s', err: %w", subnetName, err) } if subnet.Spec.Vpc == c.config.ClusterRouter { diff --git a/pkg/daemon/gateway_linux.go b/pkg/daemon/gateway_linux.go index a9427ade6696..e8ae2adbf218 100644 --- a/pkg/daemon/gateway_linux.go +++ b/pkg/daemon/gateway_linux.go @@ -329,7 +329,7 @@ func (c *Controller) addPolicyRouting(family int, gateway string, priority, tabl Table: int(tableID), } if err := netlink.RouteReplace(route); err != nil && !errors.Is(err, syscall.EEXIST) { - err = fmt.Errorf("failed to replace route in table %d: %+v", tableID, err) + err = fmt.Errorf("failed to replace route in table %d: %w", tableID, err) klog.Error(err) return err } @@ -350,7 +350,7 @@ func (c *Controller) addPolicyRouting(family int, gateway string, priority, tabl var err error if rule.Src, err = netlink.ParseIPNet(ip); err != nil { klog.Errorf("unexpected CIDR: %s", ip) - err = fmt.Errorf("failed to add route in table %d: %+v", tableID, err) + err = fmt.Errorf("failed to add route in table %d: %w", tableID, err) klog.Error(err) return err } @@ -359,7 +359,7 @@ func (c *Controller) addPolicyRouting(family int, gateway string, priority, tabl } if err := netlink.RuleAdd(rule); err != nil && !errors.Is(err, syscall.EEXIST) { - err = fmt.Errorf("failed to add network rule: %+v", err) + err = fmt.Errorf("failed to add network rule: %w", err) klog.Error(err) return err } @@ -385,7 +385,7 @@ func (c *Controller) deletePolicyRouting(family int, _ string, priority, tableID var err error if rule.Src, err = netlink.ParseIPNet(ip); err != nil { klog.Errorf("unexpected CIDR: %s", ip) - err = fmt.Errorf("failed to delete route in table %d: %+v", tableID, err) + err = fmt.Errorf("failed to delete route in table %d: %w", tableID, err) klog.Error(err) return err } @@ -394,7 +394,7 @@ func (c *Controller) deletePolicyRouting(family int, _ string, priority, tableID } if err := netlink.RuleDel(rule); err != nil && !errors.Is(err, syscall.ENOENT) { - err = fmt.Errorf("failed to delete network rule: %+v", err) + err = fmt.Errorf("failed to delete network rule: %w", err) klog.Error(err) return err } @@ -1433,7 +1433,7 @@ func (c *Controller) setExGateway() error { linkName, exist := cm.Data["external-gw-nic"] if !exist || len(linkName) == 0 { - err = fmt.Errorf("external-gw-nic not configured in ovn-external-gw-config") + err = errors.New("external-gw-nic not configured in ovn-external-gw-config") klog.Error(err) return err } @@ -1454,7 +1454,7 @@ func (c *Controller) setExGateway() error { } else { klog.Infof("external bridge should change from %s to %s, delete external bridge %s", existBr, externalBridge, existBr) if _, err := ovs.Exec(ovs.IfExists, "del-br", existBr); err != nil { - err = fmt.Errorf("failed to del external br %s, %v", existBr, err) + err = fmt.Errorf("failed to del external br %s, %w", existBr, err) klog.Error(err) return err } @@ -1467,7 +1467,7 @@ func (c *Controller) setExGateway() error { ovs.MayExist, "add-br", externalBridge, "--", ovs.MayExist, "add-port", externalBridge, linkName, ); err != nil { - err = fmt.Errorf("failed to enable external gateway, %v", err) + err = fmt.Errorf("failed to enable external gateway, %w", err) klog.Error(err) } } @@ -1478,7 +1478,7 @@ func (c *Controller) setExGateway() error { } else { brExists, err := ovs.BridgeExists(externalBridge) if err != nil { - return fmt.Errorf("failed to check OVS bridge existence: %v", err) + return fmt.Errorf("failed to check OVS bridge existence: %w", err) } if !brExists { return nil @@ -1517,7 +1517,7 @@ func (c *Controller) setExGateway() error { klog.Infof("delete external bridge %s", externalBridge) if _, err := ovs.Exec( ovs.IfExists, "del-br", externalBridge); err != nil { - err = fmt.Errorf("failed to disable external gateway, %v", err) + err = fmt.Errorf("failed to disable external gateway, %w", err) klog.Error(err) return err } @@ -1667,7 +1667,7 @@ func (c *Controller) deleteObsoleteSnatRules(ipt *iptables.IPTables, table, chai func (c *Controller) ipsetExists(name string) (bool, error) { sets, err := c.k8sipsets.ListSets() if err != nil { - return false, fmt.Errorf("failed to list ipset names: %v", err) + return false, fmt.Errorf("failed to list ipset names: %w", err) } return slices.Contains(sets, name), nil diff --git a/pkg/daemon/handler.go b/pkg/daemon/handler.go index 84e2d00fc132..39333b95fd91 100644 --- a/pkg/daemon/handler.go +++ b/pkg/daemon/handler.go @@ -26,7 +26,7 @@ import ( ) const ( - gatewayModeDisabled = iota + gatewayCheckModeDisabled = iota gatewayCheckModePing gatewayCheckModeArping gatewayCheckModePingNotConcerned @@ -61,7 +61,7 @@ func (csh cniServerHandler) providerExists(provider string) (*kubeovnv1.Subnet, func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Response) { podRequest := request.CniRequest{} if err := req.ReadEntity(&podRequest); err != nil { - errMsg := fmt.Errorf("parse add request failed %v", err) + errMsg := fmt.Errorf("parse add request failed %w", err) klog.Error(errMsg) if err := resp.WriteHeaderAndEntity(http.StatusBadRequest, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) @@ -96,7 +96,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon var err error for i := 0; i < 20; i++ { if pod, err = csh.Controller.podsLister.Pods(podRequest.PodNamespace).Get(podRequest.PodName); err != nil { - errMsg := fmt.Errorf("get pod %s/%s failed %v", podRequest.PodNamespace, podRequest.PodName, err) + errMsg := fmt.Errorf("get pod %s/%s failed %w", podRequest.PodNamespace, podRequest.PodName, err) klog.Error(errMsg) if err := resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) @@ -132,7 +132,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon vmName = pod.Annotations[fmt.Sprintf(util.VMAnnotationTemplate, podRequest.Provider)] ipAddr, err = util.GetIPAddrWithMask(ip, cidr) if err != nil { - errMsg := fmt.Errorf("failed to get ip address with mask, %v", err) + errMsg := fmt.Errorf("failed to get ip address with mask, %w", err) klog.Error(errMsg) if err := resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) @@ -142,7 +142,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon oldPodName = podRequest.PodName if s := pod.Annotations[fmt.Sprintf(util.RoutesAnnotationTemplate, podRequest.Provider)]; s != "" { if err = json.Unmarshal([]byte(s), &routes); err != nil { - errMsg := fmt.Errorf("invalid routes for pod %s/%s: %v", pod.Namespace, pod.Name, err) + errMsg := fmt.Errorf("invalid routes for pod %s/%s: %w", pod.Namespace, pod.Name, err) klog.Error(errMsg) if err = resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response: %v", err) @@ -231,7 +231,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon if strings.HasSuffix(podRequest.Provider, util.OvnProvider) && subnet != "" { podSubnet, err := csh.Controller.subnetsLister.Get(subnet) if err != nil { - errMsg := fmt.Errorf("failed to get subnet %s: %v", subnet, err) + errMsg := fmt.Errorf("failed to get subnet %s: %w", subnet, err) klog.Error(errMsg) if err = resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response: %v", err) @@ -270,6 +270,9 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon // do not perform ipv4 conflict detection during VM live migration detectIPConflict = false } + if pod.Annotations[fmt.Sprintf(util.ActivationStrategyTemplate, podRequest.Provider)] != "" { + gatewayCheckMode = gatewayCheckModeDisabled + } if podSubnet.Spec.Mtu > 0 { mtu = int(podSubnet.Spec.Mtu) @@ -277,7 +280,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon if providerNetwork != "" && !podSubnet.Spec.LogicalGateway && !podSubnet.Spec.U2OInterconnection { node, err := csh.Controller.nodesLister.Get(csh.Config.NodeName) if err != nil { - errMsg := fmt.Errorf("failed to get node %s: %v", csh.Config.NodeName, err) + errMsg := fmt.Errorf("failed to get node %s: %w", csh.Config.NodeName, err) klog.Error(errMsg) if err = resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response: %v", err) @@ -287,7 +290,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon mtuStr := node.Labels[fmt.Sprintf(util.ProviderNetworkMtuTemplate, providerNetwork)] if mtuStr != "" { if mtu, err = strconv.Atoi(mtuStr); err != nil || mtu <= 0 { - errMsg := fmt.Errorf("failed to parse provider network MTU %s: %v", mtuStr, err) + errMsg := fmt.Errorf("failed to parse provider network MTU %s: %w", mtuStr, err) klog.Error(errMsg) if err = resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response: %v", err) @@ -313,7 +316,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon routes, err = csh.configureNic(podRequest.PodName, podRequest.PodNamespace, podRequest.Provider, podRequest.NetNs, podRequest.ContainerID, podRequest.VfDriver, ifName, macAddr, mtu, ipAddr, gw, isDefaultRoute, detectIPConflict, routes, podRequest.DNS.Nameservers, podRequest.DNS.Search, ingress, egress, podRequest.DeviceID, nicType, latency, limit, loss, jitter, gatewayCheckMode, u2oInterconnectionIP, oldPodName) } if err != nil { - errMsg := fmt.Errorf("configure nic %s for pod %s/%s failed: %v", ifName, podRequest.PodName, podRequest.PodNamespace, err) + errMsg := fmt.Errorf("configure nic %s for pod %s/%s failed: %w", ifName, podRequest.PodName, podRequest.PodNamespace, err) klog.Error(errMsg) if err := resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) @@ -328,7 +331,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon } if err = csh.Controller.addEgressConfig(podSubnet, ip); err != nil { - errMsg := fmt.Errorf("failed to add egress configuration: %v", err) + errMsg := fmt.Errorf("failed to add egress configuration: %w", err) klog.Error(errMsg) if err = resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) @@ -351,7 +354,7 @@ func (csh cniServerHandler) handleAdd(req *restful.Request, resp *restful.Respon if len(hasDefaultRoute) != 0 { // remove existing default route so other CNI plugins, such as macvlan, can add the new default route correctly if err = csh.removeDefaultRoute(podRequest.NetNs, hasDefaultRoute[kubeovnv1.ProtocolIPv4], hasDefaultRoute[kubeovnv1.ProtocolIPv6]); err != nil { - errMsg := fmt.Errorf("failed to remove existing default route for interface %s of pod %s/%s: %v", podRequest.IfName, podRequest.PodNamespace, podRequest.PodName, err) + errMsg := fmt.Errorf("failed to remove existing default route for interface %s of pod %s/%s: %w", podRequest.IfName, podRequest.PodNamespace, podRequest.PodName, err) klog.Error(errMsg) if err = resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response: %v", err) @@ -383,7 +386,7 @@ func (csh cniServerHandler) UpdateIPCR(podRequest request.CniRequest, subnet, ip for i := 0; i < 20; i++ { ipCR, err := csh.KubeOvnClient.KubeovnV1().IPs().Get(context.Background(), ipCRName, metav1.GetOptions{}) if err != nil { - err = fmt.Errorf("failed to get ip crd for %s, %v", ip, err) + err = fmt.Errorf("failed to get ip crd for %s, %w", ip, err) // maybe create a backup pod with previous annotations klog.Error(err) } else if ipCR.Spec.NodeName != csh.Config.NodeName { @@ -395,7 +398,7 @@ func (csh cniServerHandler) UpdateIPCR(podRequest request.CniRequest, subnet, ip ipCR.Spec.AttachSubnets = []string{} ipCR.Spec.AttachMacs = []string{} if _, err := csh.KubeOvnClient.KubeovnV1().IPs().Update(context.Background(), ipCR, metav1.UpdateOptions{}); err != nil { - err = fmt.Errorf("failed to update ip crd for %s, %v", ip, err) + err = fmt.Errorf("failed to update ip crd for %s, %w", ip, err) klog.Error(err) } else { return nil @@ -415,7 +418,7 @@ func (csh cniServerHandler) UpdateIPCR(podRequest request.CniRequest, subnet, ip func (csh cniServerHandler) handleDel(req *restful.Request, resp *restful.Response) { var podRequest request.CniRequest if err := req.ReadEntity(&podRequest); err != nil { - errMsg := fmt.Errorf("parse del request failed %v", err) + errMsg := fmt.Errorf("parse del request failed %w", err) klog.Error(errMsg) if err := resp.WriteHeaderAndEntity(http.StatusBadRequest, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) @@ -430,7 +433,7 @@ func (csh cniServerHandler) handleDel(req *restful.Request, resp *restful.Respon return } - errMsg := fmt.Errorf("parse del request failed %v", err) + errMsg := fmt.Errorf("parse del request failed %w", err) klog.Error(errMsg) if err := resp.WriteHeaderAndEntity(http.StatusBadRequest, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) @@ -458,7 +461,7 @@ func (csh cniServerHandler) handleDel(req *restful.Request, resp *restful.Respon if subnet != "" { ip := pod.Annotations[fmt.Sprintf(util.IPAddressAnnotationTemplate, podRequest.Provider)] if err = csh.Controller.removeEgressConfig(subnet, ip); err != nil { - errMsg := fmt.Errorf("failed to remove egress configuration: %v", err) + errMsg := fmt.Errorf("failed to remove egress configuration: %w", err) klog.Error(errMsg) if err = resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) @@ -495,7 +498,7 @@ func (csh cniServerHandler) handleDel(req *restful.Request, resp *restful.Respon err = csh.deleteNic(podRequest.PodName, podRequest.PodNamespace, podRequest.ContainerID, podRequest.NetNs, podRequest.DeviceID, podRequest.IfName, nicType, podRequest.Provider) if err != nil { - errMsg := fmt.Errorf("del nic failed %v", err) + errMsg := fmt.Errorf("del nic failed %w", err) klog.Error(errMsg) if err := resp.WriteHeaderAndEntity(http.StatusInternalServerError, request.CniResponse{Err: errMsg.Error()}); err != nil { klog.Errorf("failed to write response, %v", err) diff --git a/pkg/daemon/handler_linux.go b/pkg/daemon/handler_linux.go index dc82c1aa41cd..8d626a2f759c 100644 --- a/pkg/daemon/handler_linux.go +++ b/pkg/daemon/handler_linux.go @@ -46,14 +46,14 @@ func createShortSharedDir(pod *v1.Pod, volumeName, socketConsumption, kubeletDir err = os.MkdirAll(newSharedDir, 0o777) // #nosec G301 if err != nil { klog.Error(err) - return fmt.Errorf("createSharedDir: Failed to create dir (%s): %v", newSharedDir, err) + return fmt.Errorf("createSharedDir: Failed to create dir (%s): %w", newSharedDir, err) } if strings.Contains(newSharedDir, util.DefaultHostVhostuserBaseDir) { klog.Infof("createSharedDir: Mount from %s to %s", originSharedDir, newSharedDir) err = unix.Mount(originSharedDir, newSharedDir, "", unix.MS_BIND, "") if err != nil { - return fmt.Errorf("createSharedDir: Failed to bind mount: %s", err) + return fmt.Errorf("createSharedDir: Failed to bind mount: %w", err) } } return nil @@ -76,11 +76,11 @@ func removeShortSharedDir(pod *v1.Pod, volumeName, socketConsumption string) (er return nil } - // keep mount util dpdk sock not used by kuebvirt + // keep mount util dpdk sock not used by kubevirt if socketConsumption == util.ConsumptionKubevirt { files, err := os.ReadDir(sharedDir) if err != nil { - return fmt.Errorf("read file from dpdk share dir error: %s", err) + return fmt.Errorf("read file from dpdk share dir error: %w", err) } if len(files) != 0 { return nil diff --git a/pkg/daemon/init.go b/pkg/daemon/init.go index bc43b6579093..3d7095e2da8f 100644 --- a/pkg/daemon/init.go +++ b/pkg/daemon/init.go @@ -31,14 +31,14 @@ func InitOVSBridges() (map[string]string, error) { output, err := ovs.Exec("list-ports", brName) if err != nil { - return nil, fmt.Errorf("failed to list ports of OVS bridge %s, %v: %q", brName, err, output) + return nil, fmt.Errorf("failed to list ports of OVS bridge %s, %w: %q", brName, err, output) } if output != "" { for _, port := range strings.Split(output, "\n") { ok, err := ovs.ValidatePortVendor(port) if err != nil { - return nil, fmt.Errorf("failed to check vendor of port %s: %v", port, err) + return nil, fmt.Errorf("failed to check vendor of port %s: %w", port, err) } if ok { mappings[port] = brName @@ -79,7 +79,7 @@ func InitNodeGateway(config *Configuration) error { } mac, err := net.ParseMAC(macAddr) if err != nil { - return fmt.Errorf("failed to parse mac %s %v", mac, err) + return fmt.Errorf("failed to parse mac %s %w", mac, err) } ipAddr, err = util.GetIPAddrWithMask(ip, cidr) @@ -113,14 +113,14 @@ func (c *Controller) ovsInitProviderNetwork(provider, nic string, trunks []strin klog.V(3).Infof("configure external bridge %s", brName) if err := c.configExternalBridge(provider, brName, nic, exchangeLinkName, macLearningFallback); err != nil { - errMsg := fmt.Errorf("failed to create and configure external bridge %s: %v", brName, err) + errMsg := fmt.Errorf("failed to create and configure external bridge %s: %w", brName, err) klog.Error(errMsg) return 0, errMsg } // init provider chassis mac if err := initProviderChassisMac(provider); err != nil { - errMsg := fmt.Errorf("failed to init chassis mac for provider %s, %v", provider, err) + errMsg := fmt.Errorf("failed to init chassis mac for provider %s, %w", provider, err) klog.Error(errMsg) return 0, errMsg } @@ -129,7 +129,7 @@ func (c *Controller) ovsInitProviderNetwork(provider, nic string, trunks []strin klog.Infof("config provider nic %s on bridge %s", nic, brName) mtu, err := c.configProviderNic(nic, brName, trunks) if err != nil { - errMsg := fmt.Errorf("failed to add nic %s to external bridge %s: %v", nic, brName, err) + errMsg := fmt.Errorf("failed to add nic %s to external bridge %s: %w", nic, brName, err) klog.Error(errMsg) return 0, errMsg } @@ -151,7 +151,7 @@ func (c *Controller) ovsCleanProviderNetwork(provider string) error { output, err := ovs.Exec("list-br") if err != nil { - return fmt.Errorf("failed to list OVS bridges: %v, %q", err, output) + return fmt.Errorf("failed to list OVS bridges: %w, %q", err, output) } if !slices.Contains(strings.Split(output, "\n"), brName) { @@ -161,7 +161,7 @@ func (c *Controller) ovsCleanProviderNetwork(provider string) error { // get host nic if output, err = ovs.Exec("list-ports", brName); err != nil { - return fmt.Errorf("failed to list ports of OVS bridge %s, %v: %q", brName, err, output) + return fmt.Errorf("failed to list ports of OVS bridge %s, %w: %q", brName, err, output) } // remove host nic from the external bridge @@ -169,14 +169,14 @@ func (c *Controller) ovsCleanProviderNetwork(provider string) error { for _, port := range strings.Split(output, "\n") { // patch port created by ovn-controller has an external ID ovn-localnet-port=localnet. if output, err = ovs.Exec("--data=bare", "--no-heading", "--columns=_uuid", "find", "port", "name="+port, `external-ids:ovn-localnet-port!=""`); err != nil { - return fmt.Errorf("failed to find ovs port %s, %v: %q", port, err, output) + return fmt.Errorf("failed to find ovs port %s, %w: %q", port, err, output) } if output != "" { continue } klog.V(3).Infof("removing ovs port %s from bridge %s", port, brName) if err = c.removeProviderNic(port, brName); err != nil { - errMsg := fmt.Errorf("failed to remove port %s from external bridge %s: %v", port, brName, err) + errMsg := fmt.Errorf("failed to remove port %s from external bridge %s: %w", port, brName, err) klog.Error(errMsg) return errMsg } @@ -187,7 +187,7 @@ func (c *Controller) ovsCleanProviderNetwork(provider string) error { // remove OVS bridge klog.Infof("delete external bridge %s", brName) if output, err = ovs.Exec(ovs.IfExists, "del-br", brName); err != nil { - return fmt.Errorf("failed to remove OVS bridge %s, %v: %q", brName, err, output) + return fmt.Errorf("failed to remove OVS bridge %s, %w: %q", brName, err, output) } klog.V(3).Infof("ovs bridge %s has been deleted", brName) diff --git a/pkg/daemon/metrics.go b/pkg/daemon/metrics.go index b6b4162b79b4..45cb8bd37bee 100644 --- a/pkg/daemon/metrics.go +++ b/pkg/daemon/metrics.go @@ -1,14 +1,8 @@ package daemon import ( - "context" - "net/url" - "strings" - "time" - "github.com/prometheus/client_golang/prometheus" - reflectormetrics "k8s.io/client-go/tools/cache" - clientmetrics "k8s.io/client-go/tools/metrics" + "sigs.k8s.io/controller-runtime/pkg/metrics" ) var ( @@ -48,24 +42,6 @@ var ( []string{"node_name"}, ) - // client metrics - requestLatency = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Name: "rest_client_request_latency_seconds", - Help: "Request latency in seconds. Broken down by verb and URL.", - Buckets: prometheus.ExponentialBuckets(0.001, 2, 10), - }, - []string{"verb", "url"}, - ) - - requestResult = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "rest_client_requests_total", - Help: "Number of HTTP requests, partitioned by status code, method, and host.", - }, - []string{"code", "method", "host"}, - ) - metricOvnSubnetGatewayPacketBytes = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "ovn_subnet_gateway_packet_bytes", @@ -169,182 +145,30 @@ var ( }, []string{ "hostname", }) - - // reflector metrics - - // TODO(directxman12): update these to be histograms once the metrics overhaul KEP - // PRs start landing. - - reflectorSubsystem = "reflector" - - listsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: reflectorSubsystem, - Name: "lists_total", - Help: "Total number of API lists done by the reflectors", - }, []string{"name"}) - - listsDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: reflectorSubsystem, - Name: "list_duration_seconds", - Help: "How long an API list takes to return and decode for the reflectors", - }, []string{"name"}) - - itemsPerList = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: reflectorSubsystem, - Name: "items_per_list", - Help: "How many items an API list returns to the reflectors", - }, []string{"name"}) - - watchesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: reflectorSubsystem, - Name: "watches_total", - Help: "Total number of API watches done by the reflectors", - }, []string{"name"}) - - shortWatchesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: reflectorSubsystem, - Name: "short_watches_total", - Help: "Total number of short API watches done by the reflectors", - }, []string{"name"}) - - watchDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: reflectorSubsystem, - Name: "watch_duration_seconds", - Help: "How long an API watch takes to return and decode for the reflectors", - }, []string{"name"}) - - itemsPerWatch = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: reflectorSubsystem, - Name: "items_per_watch", - Help: "How many items an API watch returns to the reflectors", - }, []string{"name"}) - - lastResourceVersion = prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Subsystem: reflectorSubsystem, - Name: "last_resource_version", - Help: "Last resource version seen for the reflectors", - }, []string{"name"}) ) func InitMetrics() { - registerReflectorMetrics() - registerClientMetrics() registerOvnSubnetGatewayMetrics() registerSystemParameterMetrics() - prometheus.MustRegister(cniOperationHistogram) - prometheus.MustRegister(cniWaitAddressResult) - prometheus.MustRegister(cniConnectivityResult) + metrics.Registry.MustRegister(cniOperationHistogram) + metrics.Registry.MustRegister(cniWaitAddressResult) + metrics.Registry.MustRegister(cniConnectivityResult) } func registerOvnSubnetGatewayMetrics() { - prometheus.MustRegister(metricOvnSubnetGatewayPacketBytes) - prometheus.MustRegister(metricOvnSubnetGatewayPackets) + metrics.Registry.MustRegister(metricOvnSubnetGatewayPacketBytes) + metrics.Registry.MustRegister(metricOvnSubnetGatewayPackets) } func registerSystemParameterMetrics() { - prometheus.MustRegister(metricIPLocalPortRange) - prometheus.MustRegister(metricCheckSumErr) - prometheus.MustRegister(metricCniConfig) - prometheus.MustRegister(metricDNSSearch) - prometheus.MustRegister(metricTCPTwRecycle) - prometheus.MustRegister(metricTCPMtuProbing) - prometheus.MustRegister(metricConntrackTCPLiberal) - prometheus.MustRegister(metricBridgeNfCallIptables) - prometheus.MustRegister(metricTCPMem) - prometheus.MustRegister(metricIPv6RouteMaxsize) -} - -// registerClientMetrics sets up the client latency metrics from client-go -func registerClientMetrics() { - // register the metrics with our registry - prometheus.MustRegister(requestLatency) - prometheus.MustRegister(requestResult) - - // register the metrics with client-go - opts := clientmetrics.RegisterOpts{ - RequestLatency: clientmetrics.LatencyMetric(&latencyAdapter{metric: requestLatency}), - RequestResult: clientmetrics.ResultMetric(&resultAdapter{metric: requestResult}), - } - clientmetrics.Register(opts) -} - -// registerReflectorMetrics sets up reflector (reconcile) loop metrics -func registerReflectorMetrics() { - prometheus.MustRegister(listsTotal) - prometheus.MustRegister(listsDuration) - prometheus.MustRegister(itemsPerList) - prometheus.MustRegister(watchesTotal) - prometheus.MustRegister(shortWatchesTotal) - prometheus.MustRegister(watchDuration) - prometheus.MustRegister(itemsPerWatch) - prometheus.MustRegister(lastResourceVersion) - - reflectormetrics.SetReflectorMetricsProvider(reflectorMetricsProvider{}) -} - -// this section contains adapters, implementations, and other sundry organic, artisanally -// hand-crafted syntax trees required to convince client-go that it actually wants to let -// someone use its metrics. - -// Client metrics adapters (method #1 for client-go metrics), -// copied (more-or-less directly) from k8s.io/kubernetes setup code -// (which isn't anywhere in an easily-importable place). - -type latencyAdapter struct { - metric *prometheus.HistogramVec -} - -func (l *latencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) { - url := u.String() - last := strings.LastIndex(url, "/") - if last != -1 { - url = url[:last] - } - l.metric.WithLabelValues(verb, url).Observe(latency.Seconds()) -} - -type resultAdapter struct { - metric *prometheus.CounterVec -} - -func (r *resultAdapter) Increment(_ context.Context, code, method, host string) { - r.metric.WithLabelValues(code, method, host).Inc() -} - -// Reflector metrics provider (method #2 for client-go metrics), -// copied (more-or-less directly) from k8s.io/kubernetes setup code -// (which isn't anywhere in an easily-importable place). - -type reflectorMetricsProvider struct{} - -func (reflectorMetricsProvider) NewListsMetric(name string) reflectormetrics.CounterMetric { - return listsTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewListDurationMetric(name string) reflectormetrics.SummaryMetric { - return listsDuration.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewItemsInListMetric(name string) reflectormetrics.SummaryMetric { - return itemsPerList.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewWatchesMetric(name string) reflectormetrics.CounterMetric { - return watchesTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewShortWatchesMetric(name string) reflectormetrics.CounterMetric { - return shortWatchesTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewWatchDurationMetric(name string) reflectormetrics.SummaryMetric { - return watchDuration.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewItemsInWatchMetric(name string) reflectormetrics.SummaryMetric { - return itemsPerWatch.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewLastResourceVersionMetric(name string) reflectormetrics.GaugeMetric { - return lastResourceVersion.WithLabelValues(name) + metrics.Registry.MustRegister(metricIPLocalPortRange) + metrics.Registry.MustRegister(metricCheckSumErr) + metrics.Registry.MustRegister(metricCniConfig) + metrics.Registry.MustRegister(metricDNSSearch) + metrics.Registry.MustRegister(metricTCPTwRecycle) + metrics.Registry.MustRegister(metricTCPMtuProbing) + metrics.Registry.MustRegister(metricConntrackTCPLiberal) + metrics.Registry.MustRegister(metricBridgeNfCallIptables) + metrics.Registry.MustRegister(metricTCPMem) + metrics.Registry.MustRegister(metricIPv6RouteMaxsize) } diff --git a/pkg/daemon/ovs.go b/pkg/daemon/ovs.go index 06e6debc8766..29b799f0dc88 100644 --- a/pkg/daemon/ovs.go +++ b/pkg/daemon/ovs.go @@ -1,6 +1,7 @@ package daemon import ( + "errors" "fmt" "strings" "time" @@ -17,7 +18,7 @@ const gatewayCheckMaxRetry = 200 func pingGateway(gw, src string, verbose bool, maxRetry int, done chan struct{}) (count int, err error) { pinger, err := goping.NewPinger(gw) if err != nil { - return 0, fmt.Errorf("failed to init pinger: %v", err) + return 0, fmt.Errorf("failed to init pinger: %w", err) } pinger.SetPrivileged(true) // CNITimeoutSec = 220, cannot exceed @@ -96,7 +97,7 @@ func configureGlobalMirror(portName string, mtu int) error { "add", "bridge", "br-int", "mirrors", "@m") if err != nil { klog.Errorf("failed to configure mirror nic %s, %q, %v", portName, raw, err) - return fmt.Errorf(raw) + return errors.New(raw) } } else { klog.Infof("nic %s exist, configure it", portName) @@ -107,7 +108,7 @@ func configureGlobalMirror(portName string, mtu int) error { "add", "bridge", "br-int", "mirrors", "@m") if err != nil { klog.Errorf("failed to configure mirror nic %s, %q, %v", portName, raw, err) - return fmt.Errorf(raw) + return errors.New(raw) } } @@ -131,7 +132,7 @@ func configureEmptyMirror(portName string, mtu int) error { "add", "bridge", "br-int", "mirrors", "@m") if err != nil { klog.Errorf("failed to configure mirror nic %s %q, %v", portName, raw, err) - return fmt.Errorf(raw) + return errors.New(raw) } } else { klog.Infof("nic %s exist, configure it", portName) @@ -142,7 +143,7 @@ func configureEmptyMirror(portName string, mtu int) error { "add", "bridge", "br-int", "mirrors", "@m") if err != nil { klog.Errorf("failed to configure mirror nic %s %q", portName, raw) - return fmt.Errorf(raw) + return errors.New(raw) } } return configureMirrorLink(portName, mtu) @@ -181,7 +182,7 @@ func encodeOvnMappings(mappings map[string]string) string { func getOvnMappings(name string) (map[string]string, error) { output, err := ovs.Exec(ovs.IfExists, "get", "open", ".", "external-ids:"+name) if err != nil { - return nil, fmt.Errorf("failed to get %s, %v: %q", name, err, output) + return nil, fmt.Errorf("failed to get %s, %w: %q", name, err, output) } return decodeOvnMappings(output), nil @@ -196,7 +197,7 @@ func setOvnMappings(name string, mappings map[string]string) error { output, err = ovs.Exec("set", "open", ".", fmt.Sprintf("external-ids:%s=%s", name, s)) } if err != nil { - return fmt.Errorf("failed to set %s, %v: %q", name, err, output) + return fmt.Errorf("failed to set %s, %w: %q", name, err, output) } return nil @@ -235,7 +236,7 @@ func removeOvnMapping(name, key string) error { func (c *Controller) configExternalBridge(provider, bridge, nic string, exchangeLinkName, macLearningFallback bool) error { brExists, err := ovs.BridgeExists(bridge) if err != nil { - return fmt.Errorf("failed to check OVS bridge existence: %v", err) + return fmt.Errorf("failed to check OVS bridge existence: %w", err) } cmd := []string{ ovs.MayExist, "add-br", bridge, @@ -249,21 +250,21 @@ func (c *Controller) configExternalBridge(provider, bridge, nic string, exchange } output, err := ovs.Exec(cmd...) if err != nil { - return fmt.Errorf("failed to create OVS bridge %s, %v: %q", bridge, err, output) + return fmt.Errorf("failed to create OVS bridge %s, %w: %q", bridge, err, output) } if output, err = ovs.Exec("list-ports", bridge); err != nil { - return fmt.Errorf("failed to list ports of OVS bridge %s, %v: %q", bridge, err, output) + return fmt.Errorf("failed to list ports of OVS bridge %s, %w: %q", bridge, err, output) } if output != "" { for _, port := range strings.Split(output, "\n") { if port != nic { ok, err := ovs.ValidatePortVendor(port) if err != nil { - return fmt.Errorf("failed to check vendor of port %s: %v", port, err) + return fmt.Errorf("failed to check vendor of port %s: %w", port, err) } if ok { if err = c.removeProviderNic(port, bridge); err != nil { - return fmt.Errorf("failed to remove port %s from OVS bridge %s: %v", port, bridge, err) + return fmt.Errorf("failed to remove port %s from OVS bridge %s: %w", port, bridge, err) } } } diff --git a/pkg/daemon/ovs_linux.go b/pkg/daemon/ovs_linux.go index b98de0325fec..96550013322b 100644 --- a/pkg/daemon/ovs_linux.go +++ b/pkg/daemon/ovs_linux.go @@ -61,7 +61,7 @@ func (csh cniServerHandler) configureDpdkNic(podName, podNamespace, provider, ne fmt.Sprintf("external_ids:ip=%s", ipStr), fmt.Sprintf("external_ids:pod_netns=%s", netns)) if err != nil { - return fmt.Errorf("add nic to ovs failed %v: %q", err, output) + return fmt.Errorf("add nic to ovs failed %w: %q", err, output) } return ovs.SetInterfaceBandwidth(podName, podNamespace, ifaceID, egress, ingress) } @@ -83,7 +83,6 @@ func (csh cniServerHandler) configureNic(podName, podNamespace, provider, netns, } } }() - } else { hostNicName, containerNicName, err = setupSriovInterface(containerID, deviceID, vfDriver, ifName, mtu, mac) if err != nil { @@ -104,7 +103,7 @@ func (csh cniServerHandler) configureNic(podName, podNamespace, provider, netns, fmt.Sprintf("external_ids:ip=%s", ipStr), fmt.Sprintf("external_ids:pod_netns=%s", netns)) if err != nil { - return nil, fmt.Errorf("add nic to ovs failed %v: %q", err, output) + return nil, fmt.Errorf("add nic to ovs failed %w: %q", err, output) } defer func() { if err != nil { @@ -148,7 +147,7 @@ func (csh cniServerHandler) configureNic(podName, podNamespace, provider, netns, // lsp and container nic must use same mac address, otherwise ovn will reject these packets by default macAddr, err := net.ParseMAC(mac) if err != nil { - return nil, fmt.Errorf("failed to parse mac %s %v", macAddr, err) + return nil, fmt.Errorf("failed to parse mac %s %w", macAddr, err) } if err = configureHostNic(hostNicName); err != nil { klog.Error(err) @@ -182,7 +181,7 @@ func (csh cniServerHandler) configureNic(podName, podNamespace, provider, netns, podNS, err := ns.GetNS(netns) if err != nil { - err = fmt.Errorf("failed to open netns %q: %v", netns, err) + err = fmt.Errorf("failed to open netns %q: %w", netns, err) klog.Error(err) return nil, err } @@ -203,13 +202,13 @@ func (csh cniServerHandler) releaseVf(podName, podNamespace, podNetns, ifName, n klog.Infof("Tear down interface %s", podDesc) netns, err := ns.GetNS(podNetns) if err != nil { - return fmt.Errorf("failed to get container namespace %s: %v", podDesc, err) + return fmt.Errorf("failed to get container namespace %s: %w", podDesc, err) } defer netns.Close() hostNS, err := ns.GetCurrentNS() if err != nil { - return fmt.Errorf("failed to get host namespace %s: %v", podDesc, err) + return fmt.Errorf("failed to get host namespace %s: %w", podDesc, err) } defer hostNS.Close() @@ -217,10 +216,10 @@ func (csh cniServerHandler) releaseVf(podName, podNamespace, podNetns, ifName, n // container side interface deletion link, err := netlink.LinkByName(ifName) if err != nil { - return fmt.Errorf("failed to get container interface %s %s: %v", ifName, podDesc, err) + return fmt.Errorf("failed to get container interface %s %s: %w", ifName, podDesc, err) } if err = netlink.LinkSetDown(link); err != nil { - return fmt.Errorf("failed to bring down container interface %s %s: %v", ifName, podDesc, err) + return fmt.Errorf("failed to bring down container interface %s %s: %w", ifName, podDesc, err) } // rename VF device back to its original name in the host namespace: pod, err := csh.Controller.podsLister.Pods(podNamespace).Get(podName) @@ -230,12 +229,12 @@ func (csh cniServerHandler) releaseVf(podName, podNamespace, podNetns, ifName, n } vfName := pod.Annotations[fmt.Sprintf(util.VfNameTemplate, provider)] if err = netlink.LinkSetName(link, vfName); err != nil { - return fmt.Errorf("failed to rename container interface %s to %s %s: %v", + return fmt.Errorf("failed to rename container interface %s to %s %s: %w", ifName, vfName, podDesc, err) } // move VF device to host netns if err = netlink.LinkSetNsFd(link, int(hostNS.Fd())); err != nil { - return fmt.Errorf("failed to move container interface %s back to host namespace %s: %v", + return fmt.Errorf("failed to move container interface %s back to host namespace %s: %w", ifName, podDesc, err) } return nil @@ -250,7 +249,7 @@ func (csh cniServerHandler) releaseVf(podName, podNamespace, podNetns, ifName, n func (csh cniServerHandler) deleteNic(podName, podNamespace, containerID, netns, deviceID, ifName, nicType, provider string) error { if err := csh.releaseVf(podName, podNamespace, netns, ifName, nicType, provider, deviceID); err != nil { return fmt.Errorf("failed to release VF %s assigned to the Pod %s/%s back to the host network namespace: "+ - "%v", ifName, podName, podNamespace, err) + "%w", ifName, podName, podNamespace, err) } var nicName string @@ -265,7 +264,7 @@ func (csh cniServerHandler) deleteNic(podName, podNamespace, containerID, netns, // Remove ovs port output, err := ovs.Exec(ovs.IfExists, "--with-iface", "del-port", "br-int", nicName) if err != nil { - return fmt.Errorf("failed to delete ovs port %v, %q", err, output) + return fmt.Errorf("failed to delete ovs port %w, %q", err, output) } if err = ovs.ClearPodBandwidth(podName, podNamespace, ""); err != nil { @@ -285,14 +284,14 @@ func (csh cniServerHandler) deleteNic(podName, podNamespace, containerID, netns, if _, ok := err.(netlink.LinkNotFoundError); ok { return nil } - return fmt.Errorf("find host link %s failed %v", nicName, err) + return fmt.Errorf("find host link %s failed %w", nicName, err) } hostLinkType := hostLink.Type() // Sometimes no deviceID input for vf nic, avoid delete vf nic. if hostLinkType == "veth" { if err = netlink.LinkDel(hostLink); err != nil { - return fmt.Errorf("delete host link %s failed %v", hostLink, err) + return fmt.Errorf("delete host link %s failed %w", hostLink, err) } } } else if pciAddrRegexp.MatchString(deviceID) { @@ -340,16 +339,16 @@ func generateNicName(containerID, ifname string) (string, string) { func configureHostNic(nicName string) error { hostLink, err := netlink.LinkByName(nicName) if err != nil { - return fmt.Errorf("can not find host nic %s: %v", nicName, err) + return fmt.Errorf("can not find host nic %s: %w", nicName, err) } if hostLink.Attrs().OperState != netlink.OperUp { if err = netlink.LinkSetUp(hostLink); err != nil { - return fmt.Errorf("can not set host nic %s up: %v", nicName, err) + return fmt.Errorf("can not set host nic %s up: %w", nicName, err) } } if err = netlink.LinkSetTxQLen(hostLink, 1000); err != nil { - return fmt.Errorf("can not set host nic %s qlen: %v", nicName, err) + return fmt.Errorf("can not set host nic %s qlen: %w", nicName, err) } return nil @@ -358,7 +357,7 @@ func configureHostNic(nicName string) error { func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName, ifName, ipAddr, gateway string, isDefaultRoute, detectIPConflict bool, routes []request.Route, macAddr net.HardwareAddr, netns ns.NetNS, mtu int, nicType string, gwCheckMode int, u2oInterconnectionIP string) ([]request.Route, error) { containerLink, err := netlink.LinkByName(nicName) if err != nil { - return nil, fmt.Errorf("can not find container nic %s: %v", nicName, err) + return nil, fmt.Errorf("can not find container nic %s: %w", nicName, err) } // Set link alias to its origin link name for fastpath to recognize and bypass netfilter @@ -368,7 +367,7 @@ func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName } if err = netlink.LinkSetNsFd(containerLink, int(netns.Fd())); err != nil { - return nil, fmt.Errorf("failed to move link to netns: %v", err) + return nil, fmt.Errorf("failed to move link to netns: %w", err) } var finalRoutes []request.Route @@ -380,21 +379,6 @@ func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName } } - if util.CheckProtocol(ipAddr) == kubeovnv1.ProtocolDual || util.CheckProtocol(ipAddr) == kubeovnv1.ProtocolIPv6 { - // For docker version >=17.x the "none" network will disable ipv6 by default. - // We have to enable ipv6 here to add v6 address and gateway. - // See https://github.com/containernetworking/cni/issues/531 - value, err := sysctl.Sysctl("net.ipv6.conf.all.disable_ipv6") - if err != nil { - return fmt.Errorf("failed to get sysctl net.ipv6.conf.all.disable_ipv6: %v", err) - } - if value != "0" { - if _, err = sysctl.Sysctl("net.ipv6.conf.all.disable_ipv6", "0"); err != nil { - return fmt.Errorf("failed to enable ipv6 on all nic: %v", err) - } - } - } - if nicType == util.InternalType { if err = addAdditionalNic(ifName); err != nil { klog.Error(err) @@ -428,7 +412,7 @@ func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName Scope: netlink.SCOPE_UNIVERSE, Gw: net.ParseIP(gw), }); err != nil { - return fmt.Errorf("failed to configure default gateway %s: %v", gw, err) + return fmt.Errorf("failed to configure default gateway %s: %w", gw, err) } } } @@ -462,7 +446,7 @@ func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName linkRoutes, err := netlink.RouteList(containerLink, netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("failed to get routes on interface %s: %v", ifName, err) + return fmt.Errorf("failed to get routes on interface %s: %w", ifName, err) } for _, r := range linkRoutes { @@ -489,7 +473,7 @@ func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName finalRoutes = append(finalRoutes, route) } - if gwCheckMode != gatewayModeDisabled { + if gwCheckMode != gatewayCheckModeDisabled { var ( underlayGateway = gwCheckMode == gatewayCheckModeArping || gwCheckMode == gatewayCheckModeArpingNotConcerned interfaceName = nicName @@ -563,7 +547,7 @@ func waitNetworkReady(nic, ipAddr, gateway string, underlayGateway, verbose bool mac, count, err := util.ArpResolve(nic, gw, time.Second, maxRetry, done) cniConnectivityResult.WithLabelValues(nodeName).Add(float64(count)) if err != nil { - err = fmt.Errorf("network %s with gateway %s is not ready for interface %s after %d checks: %v", ips[i], gw, nic, count, err) + err = fmt.Errorf("network %s with gateway %s is not ready for interface %s after %d checks: %w", ips[i], gw, nic, count, err) klog.Warning(err) return err } @@ -590,14 +574,14 @@ func configureNodeNic(portName, ip, gw, joinCIDR string, macAddr net.HardwareAdd fmt.Sprintf("external_ids:ip=%s", ipStr)) if err != nil { klog.Errorf("failed to configure node nic %s: %v, %q", portName, err, raw) - return fmt.Errorf(raw) + return errors.New(raw) } value, err := sysctl.Sysctl(fmt.Sprintf("net.ipv6.conf.%s.addr_gen_mode", util.NodeNic)) if err == nil { if value != "0" { if _, err = sysctl.Sysctl(fmt.Sprintf("net.ipv6.conf.%s.addr_gen_mode", util.NodeNic), "0"); err != nil { - return fmt.Errorf("failed to set ovn0 addr_gen_mode: %v", err) + return fmt.Errorf("failed to set ovn0 addr_gen_mode: %w", err) } } } @@ -609,11 +593,11 @@ func configureNodeNic(portName, ip, gw, joinCIDR string, macAddr net.HardwareAdd hostLink, err := netlink.LinkByName(util.NodeNic) if err != nil { - return fmt.Errorf("can not find nic %s: %v", util.NodeNic, err) + return fmt.Errorf("can not find nic %s: %w", util.NodeNic, err) } if err = netlink.LinkSetTxQLen(hostLink, 1000); err != nil { - return fmt.Errorf("can not set host nic %s qlen: %v", util.NodeNic, err) + return fmt.Errorf("can not set host nic %s qlen: %w", util.NodeNic, err) } // check and add default route for ovn0 in case of can not add automatically @@ -724,7 +708,7 @@ func (c *Controller) checkNodeGwNicInNs(nodeExtIP, ip, gw string, gwNS ns.NetNS) if err == nil { cmd := exec.Command("sh", "-c", "bfdd-control status") if err := cmd.Run(); err != nil { - err := fmt.Errorf("failed to get bfdd status, %v", err) + err := fmt.Errorf("failed to get bfdd status, %w", err) klog.Error(err) return err } @@ -741,7 +725,7 @@ func (c *Controller) checkNodeGwNicInNs(nodeExtIP, ip, gw string, gwNS ns.NetNS) // not exist cmd = exec.Command("sh", "-c", fmt.Sprintf("bfdd-control allow %s", eip.Spec.V4Ip)) // #nosec G204 if err := cmd.Run(); err != nil { - err := fmt.Errorf("failed to add lrp %s ip %s into bfd listening list, %v", eip.Name, eip.Status.V4Ip, err) + err := fmt.Errorf("failed to add lrp %s ip %s into bfd listening list, %w", eip.Name, eip.Status.V4Ip, err) klog.Error(err) return err } @@ -751,7 +735,6 @@ func (c *Controller) checkNodeGwNicInNs(nodeExtIP, ip, gw string, gwNS ns.NetNS) klog.Error(err) return err } - } } } @@ -759,7 +742,7 @@ func (c *Controller) checkNodeGwNicInNs(nodeExtIP, ip, gw string, gwNS ns.NetNS) }) } - err = fmt.Errorf("node external gw not ready") + err = errors.New("node external gw not ready") klog.Error(err) return err } @@ -773,7 +756,7 @@ func configureNodeGwNic(portName, ip, gw string, macAddr net.HardwareAddr, mtu i fmt.Sprintf("external_ids:pod_netns=%s", util.NodeGwNsPath)) if err != nil { klog.Errorf("failed to configure node external nic %s: %v, %q", portName, err, output) - return fmt.Errorf(output) + return errors.New(output) } gwLink, err := netlink.LinkByName(util.NodeGwNic) if err == nil { @@ -785,23 +768,8 @@ func configureNodeGwNic(portName, ip, gw string, macAddr net.HardwareAddr, mtu i klog.V(3).Infof("node external nic %q already in ns %s", util.NodeGwNic, util.NodeGwNsPath) } return ns.WithNetNSPath(gwNS.Path(), func(_ ns.NetNS) error { - if util.CheckProtocol(ip) == kubeovnv1.ProtocolDual || util.CheckProtocol(ip) == kubeovnv1.ProtocolIPv6 { - // For docker version >=17.x the "none" network will disable ipv6 by default. - // We have to enable ipv6 here to add v6 address and gateway. - // See https://github.com/containernetworking/cni/issues/531 - value, err := sysctl.Sysctl("net.ipv6.conf.all.disable_ipv6") - if err != nil { - return fmt.Errorf("failed to get sysctl net.ipv6.conf.all.disable_ipv6: %v", err) - } - if value != "0" { - if _, err = sysctl.Sysctl("net.ipv6.conf.all.disable_ipv6", "0"); err != nil { - return fmt.Errorf("failed to enable ipv6 on all nic: %v", err) - } - } - } - if err = configureNic(util.NodeGwNic, ip, macAddr, mtu, true); err != nil { - klog.Errorf("failed to congigure node gw nic %s, %v", util.NodeGwNic, err) + klog.Errorf("failed to configure node gw nic %s, %v", util.NodeGwNic, err) return err } @@ -841,7 +809,7 @@ func configureNodeGwNic(portName, ip, gw string, macAddr net.HardwareAddr, mtu i Gw: net.ParseIP(gws[0]), }) if err != nil { - return fmt.Errorf("config v4 gateway failed: %v", err) + return fmt.Errorf("config v4 gateway failed: %w", err) } _, defaultNet, _ = net.ParseCIDR("::/0") @@ -853,11 +821,11 @@ func configureNodeGwNic(portName, ip, gw string, macAddr net.HardwareAddr, mtu i }) } if err != nil { - return fmt.Errorf("failed to configure gateway: %v", err) + return fmt.Errorf("failed to configure gateway: %w", err) } cmd := exec.Command("sh", "-c", "/usr/local/bin/bfdd-beacon --listen=0.0.0.0") if err := cmd.Run(); err != nil { - err := fmt.Errorf("failed to get start bfd listen, %v", err) + err := fmt.Errorf("failed to get start bfd listen, %w", err) klog.Error(err) return err } @@ -867,7 +835,7 @@ func configureNodeGwNic(portName, ip, gw string, macAddr net.HardwareAddr, mtu i func removeNodeGwNic() error { if _, err := ovs.Exec(ovs.IfExists, "del-port", "br-int", util.NodeGwNic); err != nil { - return fmt.Errorf("failed to remove ecmp external port %s from OVS bridge %s: %v", "br-int", util.NodeGwNic, err) + return fmt.Errorf("failed to remove ecmp external port %s from OVS bridge %s: %w", "br-int", util.NodeGwNic, err) } klog.Infof("removed node external gw nic %q", util.NodeGwNic) return nil @@ -875,7 +843,7 @@ func removeNodeGwNic() error { func removeNodeGwNs() error { if err := DeleteNamedNs(util.NodeGwNs); err != nil { - return fmt.Errorf("failed to remove node external gw ns %s: %v", util.NodeGwNs, err) + return fmt.Errorf("failed to remove node external gw ns %s: %w", util.NodeGwNs, err) } klog.Infof("node external gw ns %s removed", util.NodeGwNs) return nil @@ -948,12 +916,12 @@ func (c *Controller) loopOvnExt0Check() { // ns not exist, create node external gw ns cmd := exec.Command("sh", "-c", fmt.Sprintf("/usr/sbin/ip netns add %s", util.NodeGwNs)) // #nosec G204 if err := cmd.Run(); err != nil { - err := fmt.Errorf("failed to get create gw ns %s, %v", util.NodeGwNs, err) + err := fmt.Errorf("failed to get create gw ns %s, %w", util.NodeGwNs, err) klog.Error(err) return } if gwNS, err = ns.GetNS(util.NodeGwNsPath); err != nil { - err := fmt.Errorf("failed to get node gw ns %s, %v", util.NodeGwNs, err) + err := fmt.Errorf("failed to get node gw ns %s, %w", util.NodeGwNs, err) klog.Error(err) return } @@ -1030,13 +998,13 @@ func configureMirrorLink(portName string, _ int) error { mirrorLink, err := netlink.LinkByName(portName) if err != nil { klog.Error(err) - return fmt.Errorf("can not find mirror nic %s: %v", portName, err) + return fmt.Errorf("can not find mirror nic %s: %w", portName, err) } if mirrorLink.Attrs().OperState != netlink.OperUp { if err = netlink.LinkSetUp(mirrorLink); err != nil { klog.Error(err) - return fmt.Errorf("can not set mirror nic %s up: %v", portName, err) + return fmt.Errorf("can not set mirror nic %s up: %w", portName, err) } } @@ -1047,12 +1015,12 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo nodeLink, err := netlink.LinkByName(link) if err != nil { klog.Error(err) - return fmt.Errorf("can not find nic %s: %v", link, err) + return fmt.Errorf("can not find nic %s: %w", link, err) } if err = netlink.LinkSetHardwareAddr(nodeLink, macAddr); err != nil { klog.Error(err) - return fmt.Errorf("can not set mac address to nic %s: %v", link, err) + return fmt.Errorf("can not set mac address to nic %s: %w", link, err) } if mtu > 0 { @@ -1062,14 +1030,14 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo err = netlink.LinkSetMTU(nodeLink, mtu) } if err != nil { - return fmt.Errorf("failed to set nic %s mtu: %v", link, err) + return fmt.Errorf("failed to set nic %s mtu: %w", link, err) } } if nodeLink.Attrs().OperState != netlink.OperUp { if err = netlink.LinkSetUp(nodeLink); err != nil { klog.Error(err) - return fmt.Errorf("can not set node nic %s up: %v", link, err) + return fmt.Errorf("can not set node nic %s up: %w", link, err) } } @@ -1078,7 +1046,7 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo ipAddrs, err := netlink.AddrList(nodeLink, unix.AF_UNSPEC) if err != nil { klog.Error(err) - return fmt.Errorf("can not get addr %s: %v", nodeLink, err) + return fmt.Errorf("can not get addr %s: %w", nodeLink, err) } for _, ipAddr := range ipAddrs { if ipAddr.IP.IsLinkLocalUnicast() { @@ -1097,7 +1065,7 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo ipAddr, err := netlink.ParseAddr(ipStr) if err != nil { - return fmt.Errorf("can not parse address %s: %v", ipStr, err) + return fmt.Errorf("can not parse address %s: %w", ipStr, err) } ipAddMap[ipStr] = *ipAddr } @@ -1106,7 +1074,7 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo klog.Infof("delete ip address %s on %s", ip, link) if err = netlink.AddrDel(nodeLink, &addr); err != nil { klog.Error(err) - return fmt.Errorf("delete address %s: %v", addr, err) + return fmt.Errorf("delete address %s: %w", addr, err) } } for ip, addr := range ipAddMap { @@ -1114,7 +1082,7 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo ip := addr.IP.String() mac, err := util.ArpDetectIPConflict(link, ip, macAddr) if err != nil { - err = fmt.Errorf("failed to detect address conflict for %s on link %s: %v", ip, link, err) + err = fmt.Errorf("failed to detect address conflict for %s on link %s: %w", ip, link, err) klog.Error(err) return err } @@ -1132,7 +1100,7 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo klog.Infof("add ip address %s to %s", ip, link) if err = netlink.AddrAdd(nodeLink, &addr); err != nil { klog.Error(err) - return fmt.Errorf("can not add address %v to nic %s: %v", addr, link, err) + return fmt.Errorf("can not add address %s to nic %s: %w", addr, link, err) } } @@ -1142,14 +1110,14 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo func configureLoNic() error { loLink, err := netlink.LinkByName(util.LoNic) if err != nil { - err := fmt.Errorf("can not find nic %s, %v", util.LoNic, err) + err := fmt.Errorf("can not find nic %s, %w", util.LoNic, err) klog.Error(err) return err } if loLink.Attrs().OperState != netlink.OperUp { if err = netlink.LinkSetUp(loLink); err != nil { - err := fmt.Errorf("failed to set up nic %s, %v", util.LoNic, err) + err := fmt.Errorf("failed to set up nic %s, %w", util.LoNic, err) klog.Error(err) return err } @@ -1161,25 +1129,25 @@ func configureLoNic() error { func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExistent bool) (int, error) { nic, err := netlink.LinkByName(nicName) if err != nil { - return 0, fmt.Errorf("failed to get nic by name %s: %v", nicName, err) + return 0, fmt.Errorf("failed to get nic by name %s: %w", nicName, err) } bridge, err := netlink.LinkByName(brName) if err != nil { - return 0, fmt.Errorf("failed to get bridge by name %s: %v", brName, err) + return 0, fmt.Errorf("failed to get bridge by name %s: %w", brName, err) } addrs, err := netlink.AddrList(nic, netlink.FAMILY_ALL) if err != nil { - return 0, fmt.Errorf("failed to get addresses on nic %s: %v", nicName, err) + return 0, fmt.Errorf("failed to get addresses on nic %s: %w", nicName, err) } routes, err := netlink.RouteList(nic, netlink.FAMILY_ALL) if err != nil { - return 0, fmt.Errorf("failed to get routes on nic %s: %v", nicName, err) + return 0, fmt.Errorf("failed to get routes on nic %s: %w", nicName, err) } brAddrs, err := netlink.AddrList(bridge, netlink.FAMILY_ALL) if err != nil { - return 0, fmt.Errorf("failed to get addresses on OVS bridge %s: %v", brName, err) + return 0, fmt.Errorf("failed to get addresses on OVS bridge %s: %w", brName, err) } var delAddrs []netlink.Addr @@ -1222,7 +1190,7 @@ func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExiste count++ if err = netlink.AddrDel(nic, &addr); err != nil { - errMsg := fmt.Errorf("failed to delete address %q on nic %s: %v", addr.String(), nicName, err) + errMsg := fmt.Errorf("failed to delete address %q on nic %s: %w", addr.String(), nicName, err) klog.Error(errMsg) return 0, errMsg } @@ -1231,7 +1199,7 @@ func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExiste addr.Label = "" addr.PreferedLft, addr.ValidLft = 0, 0 if err = netlink.AddrReplace(bridge, &addr); err != nil { - return 0, fmt.Errorf("failed to replace address %q on OVS bridge %s: %v", addr.String(), brName, err) + return 0, fmt.Errorf("failed to replace address %q on OVS bridge %s: %w", addr.String(), brName, err) } klog.Infof("address %q has been added/replaced to link %s", addr.String(), brName) } @@ -1239,7 +1207,7 @@ func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExiste if count != 0 { for _, addr := range delAddrs { if err = netlink.AddrDel(bridge, &addr); err != nil { - errMsg := fmt.Errorf("failed to delete address %q on OVS bridge %s: %v", addr.String(), brName, err) + errMsg := fmt.Errorf("failed to delete address %q on OVS bridge %s: %w", addr.String(), brName, err) klog.Error(errMsg) return 0, errMsg } @@ -1255,12 +1223,12 @@ func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExiste } if !albBond { if _, err = ovs.Exec("set", "bridge", brName, fmt.Sprintf(`other-config:hwaddr="%s"`, nic.Attrs().HardwareAddr.String())); err != nil { - return 0, fmt.Errorf("failed to set MAC address of OVS bridge %s: %v", brName, err) + return 0, fmt.Errorf("failed to set MAC address of OVS bridge %s: %w", brName, err) } } if err = netlink.LinkSetUp(bridge); err != nil { - return 0, fmt.Errorf("failed to set OVS bridge %s up: %v", brName, err) + return 0, fmt.Errorf("failed to set OVS bridge %s up: %w", brName, err) } for _, scope := range routeScopeOrders { @@ -1272,7 +1240,7 @@ func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExiste if route.Scope == scope { route.LinkIndex = bridge.Attrs().Index if err = netlink.RouteReplace(&route); err != nil { - return 0, fmt.Errorf("failed to add/replace route %s to OVS bridge %s: %v", route.String(), brName, err) + return 0, fmt.Errorf("failed to add/replace route %s to OVS bridge %s: %w", route.String(), brName, err) } klog.Infof("route %q has been added/replaced to OVS bridge %s", route.String(), brName) } @@ -1281,7 +1249,7 @@ func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExiste brRoutes, err := netlink.RouteList(bridge, netlink.FAMILY_ALL) if err != nil { - return 0, fmt.Errorf("failed to get routes on OVS bridge %s: %v", brName, err) + return 0, fmt.Errorf("failed to get routes on OVS bridge %s: %w", brName, err) } var delRoutes []netlink.Route @@ -1311,7 +1279,7 @@ func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExiste for _, route := range delRoutes { if route.Scope == routeScopeOrders[i] { if err = netlink.RouteDel(&route); err != nil { - return 0, fmt.Errorf("failed to delete route %s from OVS bridge %s: %v", route.String(), brName, err) + return 0, fmt.Errorf("failed to delete route %s from OVS bridge %s: %w", route.String(), brName, err) } klog.Infof("route %q has been deleted from OVS bridge %s", route.String(), brName) } @@ -1319,7 +1287,7 @@ func (c *Controller) transferAddrsAndRoutes(nicName, brName string, delNonExiste } if err = netlink.LinkSetUp(nic); err != nil { - return 0, fmt.Errorf("failed to set link %s up: %v", nicName, err) + return 0, fmt.Errorf("failed to set link %s up: %w", nicName, err) } return nic.Attrs().MTU, nil @@ -1331,22 +1299,22 @@ func (c *Controller) configProviderNic(nicName, brName string, trunks []string) sysctlDisableIPv6 := fmt.Sprintf("net.ipv6.conf.%s.disable_ipv6", brName) disableIPv6, err := sysctl.Sysctl(sysctlDisableIPv6) if err != nil { - return 0, fmt.Errorf("failed to get sysctl %s: %v", sysctlDisableIPv6, err) + return 0, fmt.Errorf("failed to get sysctl %s: %w", sysctlDisableIPv6, err) } if disableIPv6 != "0" { if _, err = sysctl.Sysctl(sysctlDisableIPv6, "0"); err != nil { - return 0, fmt.Errorf("failed to enable ipv6 on OVS bridge %s: %v", brName, err) + return 0, fmt.Errorf("failed to enable ipv6 on OVS bridge %s: %w", brName, err) } } mtu, err := c.transferAddrsAndRoutes(nicName, brName, false) if err != nil { - return 0, fmt.Errorf("failed to transfer addresess and routes from %s to %s: %v", nicName, brName, err) + return 0, fmt.Errorf("failed to transfer addresses and routes from %s to %s: %w", nicName, brName, err) } if _, err = ovs.Exec(ovs.MayExist, "add-port", brName, nicName, "--", "set", "port", nicName, "trunks="+strings.Join(trunks, ","), "external_ids:vendor="+util.CniTypeName); err != nil { - return 0, fmt.Errorf("failed to add %s to OVS bridge %s: %v", nicName, brName, err) + return 0, fmt.Errorf("failed to add %s to OVS bridge %s: %w", nicName, brName, err) } klog.V(3).Infof("ovs port %s has been added to bridge %s", nicName, brName) @@ -1387,24 +1355,24 @@ func (c *Controller) removeProviderNic(nicName, brName string) error { klog.Warningf("failed to get nic by name %s: %v", nicName, err) return nil } - return fmt.Errorf("failed to get nic by name %s: %v", nicName, err) + return fmt.Errorf("failed to get nic by name %s: %w", nicName, err) } bridge, err := netlink.LinkByName(brName) if err != nil { - return fmt.Errorf("failed to get bridge by name %s: %v", brName, err) + return fmt.Errorf("failed to get bridge by name %s: %w", brName, err) } addrs, err := netlink.AddrList(bridge, netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("failed to get addresses on bridge %s: %v", brName, err) + return fmt.Errorf("failed to get addresses on bridge %s: %w", brName, err) } routes, err := netlink.RouteList(bridge, netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("failed to get routes on bridge %s: %v", brName, err) + return fmt.Errorf("failed to get routes on bridge %s: %w", brName, err) } if _, err = ovs.Exec(ovs.IfExists, "del-port", brName, nicName); err != nil { - return fmt.Errorf("failed to remove %s from OVS bridge %s: %v", nicName, brName, err) + return fmt.Errorf("failed to remove %s from OVS bridge %s: %w", nicName, brName, err) } klog.V(3).Infof("ovs port %s has been removed from bridge %s", nicName, brName) @@ -1415,7 +1383,7 @@ func (c *Controller) removeProviderNic(nicName, brName string) error { } if err = netlink.AddrDel(bridge, &addr); err != nil { - errMsg := fmt.Errorf("failed to delete address %q on OVS bridge %s: %v", addr.String(), brName, err) + errMsg := fmt.Errorf("failed to delete address %q on OVS bridge %s: %w", addr.String(), brName, err) klog.Error(errMsg) return errMsg } @@ -1423,7 +1391,7 @@ func (c *Controller) removeProviderNic(nicName, brName string) error { addr.Label = "" if err = netlink.AddrReplace(nic, &addr); err != nil { - return fmt.Errorf("failed to replace address %q on nic %s: %v", addr.String(), nicName, err) + return fmt.Errorf("failed to replace address %q on nic %s: %w", addr.String(), nicName, err) } klog.Infof("address %q has been added/replaced to link %s", addr.String(), nicName) } @@ -1448,7 +1416,7 @@ func (c *Controller) removeProviderNic(nicName, brName string) error { if route.Scope == scope { route.LinkIndex = nic.Attrs().Index if err = netlink.RouteReplace(&route); err != nil { - return fmt.Errorf("failed to add/replace route %s: %v", route.String(), err) + return fmt.Errorf("failed to add/replace route %s: %w", route.String(), err) } klog.Infof("route %q has been added/replaced to link %s", route.String(), nicName) } @@ -1456,7 +1424,7 @@ func (c *Controller) removeProviderNic(nicName, brName string) error { } if err = netlink.LinkSetDown(bridge); err != nil { - return fmt.Errorf("failed to set OVS bridge %s down: %v", brName, err) + return fmt.Errorf("failed to set OVS bridge %s down: %w", brName, err) } klog.V(3).Infof("link %s has been set down", brName) @@ -1479,7 +1447,7 @@ func setupVethPair(containerID, ifName string, mtu int) (string, string, error) klog.Errorf("failed to delete veth %v", err) return "", "", err } - return "", "", fmt.Errorf("failed to create veth for %v", err) + return "", "", fmt.Errorf("failed to create veth for %w", err) } return hostNicName, containerNicName, nil } @@ -1491,7 +1459,7 @@ func setupSriovInterface(containerID, deviceID, vfDriver, ifName string, mtu int if vfDriver == "vfio-pci" { matches, err := filepath.Glob(filepath.Join(util.VfioSysDir, "*")) if err != nil { - return "", "", fmt.Errorf("failed to check %s 'vfio-pci' driver path, %v", deviceID, err) + return "", "", fmt.Errorf("failed to check %s 'vfio-pci' driver path, %w", deviceID, err) } for _, match := range matches { @@ -1551,7 +1519,7 @@ func setupSriovInterface(containerID, deviceID, vfDriver, ifName string, mtu int // 5. rename the host VF representor hostNicName, _ := generateNicName(containerID, ifName) if err = renameLink(oldHostRepName, hostNicName); err != nil { - return "", "", fmt.Errorf("failed to rename %s to %s: %v", oldHostRepName, hostNicName, err) + return "", "", fmt.Errorf("failed to rename %s to %s: %w", oldHostRepName, hostNicName, err) } link, err := netlink.LinkByName(hostNicName) @@ -1561,7 +1529,7 @@ func setupSriovInterface(containerID, deviceID, vfDriver, ifName string, mtu int // 6. set MTU on VF representor if err = netlink.LinkSetMTU(link, mtu); err != nil { - return "", "", fmt.Errorf("failed to set MTU on %s: %v", hostNicName, err) + return "", "", fmt.Errorf("failed to set MTU on %s: %w", hostNicName, err) } // 7. set MAC address to VF @@ -1606,7 +1574,7 @@ func (csh cniServerHandler) configureNicWithInternalPort(podName, podNamespace, fmt.Sprintf("external_ids:ip=%s", ipStr), fmt.Sprintf("external_ids:pod_netns=%s", netns)) if err != nil { - err := fmt.Errorf("add nic to ovs failed %v: %q", err, output) + err := fmt.Errorf("add nic to ovs failed %w: %q", err, output) klog.Error(err) return containerNicName, nil, err } @@ -1622,7 +1590,7 @@ func (csh cniServerHandler) configureNicWithInternalPort(podName, podNamespace, // container nic must use same mac address from pod annotation, otherwise ovn will reject these packets by default macAddr, err := net.ParseMAC(mac) if err != nil { - return containerNicName, nil, fmt.Errorf("failed to parse mac %s %v", macAddr, err) + return containerNicName, nil, fmt.Errorf("failed to parse mac %s %w", macAddr, err) } if err = ovs.SetInterfaceBandwidth(podName, podNamespace, ifaceID, egress, ingress); err != nil { @@ -1635,7 +1603,7 @@ func (csh cniServerHandler) configureNicWithInternalPort(podName, podNamespace, podNS, err := ns.GetNS(netns) if err != nil { - return containerNicName, nil, fmt.Errorf("failed to open netns %q: %v", netns, err) + return containerNicName, nil, fmt.Errorf("failed to open netns %q: %w", netns, err) } routes, err = csh.configureContainerNic(podName, podNamespace, containerNicName, ifName, ip, gateway, isDefaultRoute, detectIPConflict, routes, macAddr, podNS, mtu, nicType, gwCheckMode, u2oInterconnectionIP) return containerNicName, routes, err @@ -1644,13 +1612,13 @@ func (csh cniServerHandler) configureNicWithInternalPort(podName, podNamespace, func (csh cniServerHandler) removeDefaultRoute(netns string, ipv4, ipv6 bool) error { podNS, err := ns.GetNS(netns) if err != nil { - return fmt.Errorf("failed to open netns %q: %v", netns, err) + return fmt.Errorf("failed to open netns %q: %w", netns, err) } return ns.WithNetNSPath(podNS.Path(), func(_ ns.NetNS) error { routes, err := netlink.RouteList(nil, netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("failed to get all routes: %v", err) + return fmt.Errorf("failed to get all routes: %w", err) } for _, r := range routes { @@ -1662,14 +1630,14 @@ func (csh cniServerHandler) removeDefaultRoute(netns string, ipv4, ipv6 bool) er if ipv4 && r.Family == netlink.FAMILY_V4 { klog.Infof("deleting default ipv4 route %+v", r) if err = netlink.RouteDel(&r); err != nil { - return fmt.Errorf("failed to delete route %+v: %v", r, err) + return fmt.Errorf("failed to delete route %+v: %w", r, err) } continue } if ipv6 && r.Family == netlink.FAMILY_V6 { klog.Infof("deleting default ipv6 route %+v", r) if err = netlink.RouteDel(&r); err != nil { - return fmt.Errorf("failed to delete route %+v: %v", r, err) + return fmt.Errorf("failed to delete route %+v: %w", r, err) } } } @@ -1681,14 +1649,14 @@ func (csh cniServerHandler) removeDefaultRoute(netns string, ipv4, ipv6 bool) er func configureAdditionalNic(link, ip string) error { nodeLink, err := netlink.LinkByName(link) if err != nil { - return fmt.Errorf("can not find nic %s %v", link, err) + return fmt.Errorf("can not find nic %s %w", link, err) } ipDelMap := make(map[string]netlink.Addr) ipAddMap := make(map[string]netlink.Addr) ipAddrs, err := netlink.AddrList(nodeLink, 0x0) if err != nil { - return fmt.Errorf("can not get addr %s %v", nodeLink, err) + return fmt.Errorf("can not get addr %s %w", nodeLink, err) } for _, ipAddr := range ipAddrs { if ipAddr.IP.IsLinkLocalUnicast() { @@ -1707,19 +1675,19 @@ func configureAdditionalNic(link, ip string) error { ipAddr, err := netlink.ParseAddr(ipStr) if err != nil { - return fmt.Errorf("can not parse %s %v", ipStr, err) + return fmt.Errorf("can not parse %s %w", ipStr, err) } ipAddMap[ipStr] = *ipAddr } for _, addr := range ipDelMap { if err = netlink.AddrDel(nodeLink, &addr); err != nil { - return fmt.Errorf("delete address %s %v", addr, err) + return fmt.Errorf("delete address %s %w", addr, err) } } for _, addr := range ipAddMap { if err = netlink.AddrAdd(nodeLink, &addr); err != nil { - return fmt.Errorf("can not add address %v to nic %s, %v", addr, link, err) + return fmt.Errorf("can not add address %v to nic %s, %w", addr, link, err) } } @@ -1738,7 +1706,7 @@ func addAdditionalNic(ifName string) error { klog.Errorf("failed to delete static iface %v, err %v", ifName, err) return err } - return fmt.Errorf("failed to create static iface %v, err %v", ifName, err) + return fmt.Errorf("failed to create static iface %v, err %w", ifName, err) } return nil } @@ -1746,17 +1714,17 @@ func addAdditionalNic(ifName string) error { func setVfMac(deviceID string, vfIndex int, mac string) error { macAddr, err := net.ParseMAC(mac) if err != nil { - return fmt.Errorf("failed to parse mac %s %v", macAddr, err) + return fmt.Errorf("failed to parse mac %s %w", macAddr, err) } pfPci, err := sriovnet.GetPfPciFromVfPci(deviceID) if err != nil { - return fmt.Errorf("failed to get pf of device %s %v", deviceID, err) + return fmt.Errorf("failed to get pf of device %s %w", deviceID, err) } netDevs, err := sriovnet.GetNetDevicesFromPci(pfPci) if err != nil { - return fmt.Errorf("failed to get pf of device %s %v", deviceID, err) + return fmt.Errorf("failed to get pf of device %s %w", deviceID, err) } // get real pf @@ -1779,10 +1747,10 @@ func setVfMac(deviceID string, vfIndex int, mac string) error { pfLink, err := netlink.LinkByName(pfName) if err != nil { - return fmt.Errorf("failed to lookup pf %s: %v", pfName, err) + return fmt.Errorf("failed to lookup pf %s: %w", pfName, err) } if err := netlink.LinkSetVfHardwareAddr(pfLink, vfIndex, macAddr); err != nil { - return fmt.Errorf("can not set mac address to vf nic:%s vf:%d %v", pfName, vfIndex, err) + return fmt.Errorf("can not set mac address to vf nic:%s vf:%d %w", pfName, vfIndex, err) } return nil } @@ -1822,7 +1790,7 @@ func rollBackVethPair(nicName string) error { return nil } klog.Error(err) - return fmt.Errorf("find host link %s failed %v", nicName, err) + return fmt.Errorf("find host link %s failed %w", nicName, err) } hostLinkType := hostLink.Type() @@ -1830,7 +1798,7 @@ func rollBackVethPair(nicName string) error { if hostLinkType == "veth" { if err = netlink.LinkDel(hostLink); err != nil { klog.Error(err) - return fmt.Errorf("delete host link %s failed %v", hostLink, err) + return fmt.Errorf("delete host link %s failed %w", hostLink, err) } } klog.Infof("rollback veth success %s", nicName) diff --git a/pkg/daemon/server.go b/pkg/daemon/server.go index 0976939a8f03..01045d9ec680 100644 --- a/pkg/daemon/server.go +++ b/pkg/daemon/server.go @@ -3,6 +3,7 @@ package daemon import ( "fmt" "net/http" + "strconv" "time" "github.com/emicklei/go-restful/v3" @@ -69,7 +70,7 @@ func requestAndResponseLogger(request *restful.Request, response *restful.Respon cniOperationHistogram.WithLabelValues( nodeName, getRequestURI(request), - fmt.Sprintf("%d", response.StatusCode())).Observe(elapsed / 1000) + strconv.Itoa(response.StatusCode())).Observe(elapsed / 1000) klog.Infof(formatResponseLog(response, request, elapsed)) } diff --git a/pkg/daemon/tproxy_linux.go b/pkg/daemon/tproxy_linux.go index d509fbc450bc..79b7706f1d53 100644 --- a/pkg/daemon/tproxy_linux.go +++ b/pkg/daemon/tproxy_linux.go @@ -6,7 +6,6 @@ import ( "io" "net" "strconv" - "strings" "sync" "syscall" @@ -23,23 +22,18 @@ import ( ) var ( - tcpListener net.Listener - customVPCPodIPToNs sync.Map customVPCPodTCPProbeIPPort sync.Map ) func (c *Controller) StartTProxyForwarding() { - var err error - addr := util.GetDefaultListenAddr() - protocol := "tcp" - if strings.HasPrefix(addr, "[") && strings.HasSuffix(addr, "]") { - addr = addr[1 : len(addr)-1] + addr := util.GetDefaultListenAddr() + if util.CheckProtocol(addr) == kubeovnv1.ProtocolIPv6 { protocol = "tcp6" } - tcpListener, err = goTProxy.ListenTCP(protocol, &net.TCPAddr{IP: net.ParseIP(addr), Port: util.TProxyListenPort}) + tcpListener, err := goTProxy.ListenTCP(protocol, &net.TCPAddr{IP: net.ParseIP(addr), Port: util.TProxyListenPort}) if err != nil { klog.Fatalf("Encountered error while binding listener: %s", err) return @@ -168,7 +162,7 @@ func (c *Controller) cleanTProxyRoutes(protocol string) { func addRuleIfNotExist(family, mark, mask, table int) error { curRules, err := netlink.RuleListFiltered(family, &netlink.Rule{Mark: mark}, netlink.RT_FILTER_MARK) if err != nil { - return fmt.Errorf("list rules with mark %x failed err: %v", mark, err) + return fmt.Errorf("list rules with mark %x failed err: %w", mark, err) } if len(curRules) != 0 { @@ -192,13 +186,13 @@ func addRuleIfNotExist(family, mark, mask, table int) error { func deleteRuleIfExists(family, mark int) error { curRules, err := netlink.RuleListFiltered(family, &netlink.Rule{Mark: mark}, netlink.RT_FILTER_MARK) if err != nil { - return fmt.Errorf("list rules with mark %x failed err: %v", mark, err) + return fmt.Errorf("list rules with mark %x failed err: %w", mark, err) } if len(curRules) != 0 { for _, r := range curRules { if err := netlink.RuleDel(&r); err != nil && !errors.Is(err, syscall.ENOENT) { - return fmt.Errorf("delete rule %v failed with err: %v", r, err) + return fmt.Errorf("delete rule %v failed with err: %w", r, err) } } } @@ -208,7 +202,7 @@ func deleteRuleIfExists(family, mark int) error { func addRouteIfNotExist(family, table int, dst *net.IPNet) error { curRoutes, err := netlink.RouteListFiltered(family, &netlink.Route{Table: table, Dst: dst}, netlink.RT_FILTER_TABLE|netlink.RT_FILTER_DST) if err != nil { - return fmt.Errorf("list routes with table %d failed with err: %v", table, err) + return fmt.Errorf("list routes with table %d failed with err: %w", table, err) } if len(curRoutes) != 0 { @@ -249,7 +243,7 @@ func delRouteIfExist(family, table int, dst *net.IPNet) error { link, err := netlink.LinkByName("lo") if err != nil { - return fmt.Errorf("can't find device lo") + return errors.New("can't find device lo") } route := netlink.Route{ diff --git a/pkg/metrics/client_go_adapter.go b/pkg/metrics/client_go_adapter.go new file mode 100644 index 000000000000..08829879cbbe --- /dev/null +++ b/pkg/metrics/client_go_adapter.go @@ -0,0 +1,60 @@ +/* +Copyright 2018 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. +*/ + +// This file comes from sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go + +package metrics + +import ( + "context" + "net/url" + "path" + "time" + + "github.com/prometheus/client_golang/prometheus" + "k8s.io/client-go/tools/metrics" + ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var requestLatency = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "rest_client_request_latency_seconds", + Help: "Request latency in seconds. Broken down by verb and URL.", + Buckets: prometheus.ExponentialBuckets(0.001, 2, 10), + }, + []string{"verb", "url"}, +) + +func InitClientGoMetrics() { + registerClientMetrics() +} + +// registerClientMetrics sets up the client latency metrics from client-go +func registerClientMetrics() { + // register the metrics with our registry + ctrlmetrics.Registry.MustRegister(requestLatency) + + // register the metrics with client-go + metrics.RequestLatency = &latencyAdapter{metric: requestLatency} +} + +type latencyAdapter struct { + metric *prometheus.HistogramVec +} + +func (l *latencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) { + l.metric.WithLabelValues(verb, path.Dir(u.Path)).Observe(latency.Seconds()) +} diff --git a/pkg/util/klog_metrics.go b/pkg/metrics/klog.go similarity index 87% rename from pkg/util/klog_metrics.go rename to pkg/metrics/klog.go index e4c317636996..1226ecfb2e0e 100644 --- a/pkg/util/klog_metrics.go +++ b/pkg/metrics/klog.go @@ -1,8 +1,10 @@ -package util +package metrics import ( "time" + "sigs.k8s.io/controller-runtime/pkg/metrics" + "github.com/prometheus/client_golang/prometheus" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/klog/v2" @@ -25,8 +27,8 @@ func InitKlogMetrics() { } func registerKlogMetrics() { - prometheus.MustRegister(klogLinesGaugeVec) - prometheus.MustRegister(klogBytesGaugeVec) + metrics.Registry.MustRegister(klogLinesGaugeVec) + metrics.Registry.MustRegister(klogBytesGaugeVec) } func fetchKlogMetrics() { diff --git a/pkg/metrics/server.go b/pkg/metrics/server.go new file mode 100644 index 000000000000..f389f398e390 --- /dev/null +++ b/pkg/metrics/server.go @@ -0,0 +1,38 @@ +package metrics + +import ( + "context" + "fmt" + + "k8s.io/client-go/rest" + "k8s.io/klog/v2" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/metrics/filters" + "sigs.k8s.io/controller-runtime/pkg/metrics/server" +) + +func Run(ctx context.Context, config *rest.Config, addr string, secureServing bool) error { + if config == nil { + config = ctrl.GetConfigOrDie() + } + client, err := rest.HTTPClientFor(config) + if err != nil { + klog.Error(err) + return fmt.Errorf("failed to create http client: %w", err) + } + + options := server.Options{ + SecureServing: secureServing, + BindAddress: addr, + } + if secureServing { + options.FilterProvider = filters.WithAuthenticationAndAuthorization + } + svr, err := server.NewServer(options, config, client) + if err != nil { + klog.Error(err) + return fmt.Errorf("failed to create metrics server: %w", err) + } + + return svr.Start(ctx) +} diff --git a/pkg/ovn_ic_controller/config.go b/pkg/ovn_ic_controller/config.go index a97fbbe29a58..29779e967861 100644 --- a/pkg/ovn_ic_controller/config.go +++ b/pkg/ovn_ic_controller/config.go @@ -88,7 +88,7 @@ func ParseFlags() (*Configuration, error) { } if err := config.initKubeClient(); err != nil { - return nil, fmt.Errorf("failed to init kube client, %v", err) + return nil, fmt.Errorf("failed to init kube client, %w", err) } return config, nil diff --git a/pkg/ovn_ic_controller/ovn_ic_controller.go b/pkg/ovn_ic_controller/ovn_ic_controller.go index cccc76e7044b..9a86e65957bf 100644 --- a/pkg/ovn_ic_controller/ovn_ic_controller.go +++ b/pkg/ovn_ic_controller/ovn_ic_controller.go @@ -393,7 +393,7 @@ func (c *Controller) startOVNIC(icHost, icNbPort, icSbPort string) error { } output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("output: %s, err: %v", output, err) + return fmt.Errorf("output: %s, err: %w", output, err) } return nil } @@ -402,7 +402,7 @@ func (c *Controller) stopOVNIC() error { cmd := exec.Command("/usr/share/ovn/scripts/ovn-ctl", "stop_ic") output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("output: %s, err: %v", output, err) + return fmt.Errorf("output: %s, err: %w", output, err) } return nil } @@ -435,7 +435,6 @@ func (c *Controller) delLearnedRoute() error { klog.Errorf("failed to delete learned static route %#v on logical router %s: %v", r, lr.Name, err) return err } - } } @@ -632,7 +631,7 @@ func (c *Controller) listRemoteLogicalSwitchPortAddress() (*strset.Set, error) { }) if err != nil { klog.Error(err) - return nil, fmt.Errorf("list remote logical switch ports: %v", err) + return nil, fmt.Errorf("list remote logical switch ports: %w", err) } existAddress := strset.NewWithSize(len(lsps)) diff --git a/pkg/ovn_leader_checker/ovn.go b/pkg/ovn_leader_checker/ovn.go index 06a9aa7ee30a..60ffae15b386 100755 --- a/pkg/ovn_leader_checker/ovn.go +++ b/pkg/ovn_leader_checker/ovn.go @@ -2,6 +2,7 @@ package ovn_leader_checker import ( "context" + "errors" "flag" "fmt" "net" @@ -94,7 +95,7 @@ func ParseFlags() (*Configuration, error) { // KubeClientInit funcs to check apiserver alive func KubeClientInit(cfg *Configuration) error { if cfg == nil { - return fmt.Errorf("invalid cfg") + return errors.New("invalid cfg") } // init kubeconfig here @@ -453,7 +454,7 @@ func updateTS() error { cmd := exec.Command("ovn-ic-nbctl", "show") output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("ovn-ic-nbctl show output: %s, err: %v", output, err) + return fmt.Errorf("ovn-ic-nbctl show output: %s, err: %w", output, err) } var existTSCount int if lines := strings.TrimSpace(string(output)); lines != "" { @@ -461,7 +462,7 @@ func updateTS() error { } expectTSCount, err := strconv.Atoi(os.Getenv("TS_NUM")) if err != nil { - return fmt.Errorf("expectTSCount atoi failed output: %s, err: %v", output, err) + return fmt.Errorf("expectTSCount atoi failed output: %s, err: %w", output, err) } if expectTSCount == existTSCount { klog.V(3).Infof("expectTSCount %d no changes required.", expectTSCount) @@ -490,7 +491,7 @@ func updateTS() error { } output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("output: %s, err: %v", output, err) + return fmt.Errorf("output: %s, err: %w", output, err) } } } else { @@ -507,7 +508,7 @@ func updateTS() error { } output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("output: %s, err: %v", output, err) + return fmt.Errorf("output: %s, err: %w", output, err) } } } diff --git a/pkg/ovnmonitor/config.go b/pkg/ovnmonitor/config.go index 1dd2d39d6be9..e48070a01bf6 100644 --- a/pkg/ovnmonitor/config.go +++ b/pkg/ovnmonitor/config.go @@ -45,6 +45,7 @@ type Configuration struct { ServiceNorthdFileLogPath string ServiceNorthdFilePidPath string EnableMetrics bool + SecureServing bool } // ParseFlags get parameters information. @@ -55,6 +56,7 @@ func ParseFlags() (*Configuration, error) { argPollTimeout = pflag.Int("ovs.timeout", 2, "Timeout on JSON-RPC requests to OVN.") argPollInterval = pflag.Int("ovs.poll-interval", 30, "The minimum interval (in seconds) between collections from OVN server.") argEnableMetrics = pflag.Bool("enable-metrics", true, "Whether to support metrics query") + argSecureServing = pflag.Bool("secure-serving", false, "Whether to serve metrics securely") argSystemRunDir = pflag.String("system.run.dir", "/var/run/openvswitch", "OVS default run directory.") argDatabaseVswitchName = pflag.String("database.vswitch.name", "Open_vSwitch", "The name of OVS db.") @@ -144,6 +146,7 @@ func ParseFlags() (*Configuration, error) { ServiceNorthdFileLogPath: *argServiceNorthdFileLogPath, ServiceNorthdFilePidPath: *argServiceNorthdFilePidPath, EnableMetrics: *argEnableMetrics, + SecureServing: *argSecureServing, } klog.Infof("ovn monitor config is %+v", config) diff --git a/pkg/ovnmonitor/metric.go b/pkg/ovnmonitor/metric.go index 30f7634dc68f..834125dc5796 100644 --- a/pkg/ovnmonitor/metric.go +++ b/pkg/ovnmonitor/metric.go @@ -1,6 +1,9 @@ package ovnmonitor -import "github.com/prometheus/client_golang/prometheus" +import ( + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) var ( // OVN basic info @@ -476,48 +479,48 @@ var ( func registerOvnMetrics() { // ovn status metrics - prometheus.MustRegister(metricOvnHealthyStatus) - prometheus.MustRegister(metricOvnHealthyStatusContent) - prometheus.MustRegister(metricRequestErrorNums) - prometheus.MustRegister(metricLogFileSize) - prometheus.MustRegister(metricDBFileSize) - prometheus.MustRegister(metricDBStatus) + metrics.Registry.MustRegister(metricOvnHealthyStatus) + metrics.Registry.MustRegister(metricOvnHealthyStatusContent) + metrics.Registry.MustRegister(metricRequestErrorNums) + metrics.Registry.MustRegister(metricLogFileSize) + metrics.Registry.MustRegister(metricDBFileSize) + metrics.Registry.MustRegister(metricDBStatus) // ovn chassis metrics - prometheus.MustRegister(metricChassisInfo) - prometheus.MustRegister(metricLogicalSwitchInfo) - prometheus.MustRegister(metricLogicalSwitchExternalIDs) - prometheus.MustRegister(metricLogicalSwitchPortBinding) - prometheus.MustRegister(metricLogicalSwitchTunnelKey) - prometheus.MustRegister(metricLogicalSwitchPortsNum) - prometheus.MustRegister(metricLogicalSwitchPortInfo) - prometheus.MustRegister(metricLogicalSwitchPortTunnelKey) + metrics.Registry.MustRegister(metricChassisInfo) + metrics.Registry.MustRegister(metricLogicalSwitchInfo) + metrics.Registry.MustRegister(metricLogicalSwitchExternalIDs) + metrics.Registry.MustRegister(metricLogicalSwitchPortBinding) + metrics.Registry.MustRegister(metricLogicalSwitchTunnelKey) + metrics.Registry.MustRegister(metricLogicalSwitchPortsNum) + metrics.Registry.MustRegister(metricLogicalSwitchPortInfo) + metrics.Registry.MustRegister(metricLogicalSwitchPortTunnelKey) // OVN Cluster basic info metrics - prometheus.MustRegister(metricClusterEnabled) - prometheus.MustRegister(metricClusterRole) - prometheus.MustRegister(metricClusterStatus) - prometheus.MustRegister(metricClusterTerm) - - prometheus.MustRegister(metricClusterLeaderSelf) - prometheus.MustRegister(metricClusterVoteSelf) - prometheus.MustRegister(metricClusterElectionTimer) - prometheus.MustRegister(metricClusterNotCommittedEntryCount) - prometheus.MustRegister(metricClusterNotAppliedEntryCount) - - prometheus.MustRegister(metricClusterLogIndexStart) - prometheus.MustRegister(metricClusterLogIndexNext) - prometheus.MustRegister(metricClusterInConnTotal) - prometheus.MustRegister(metricClusterOutConnTotal) - prometheus.MustRegister(metricClusterInConnErrTotal) - prometheus.MustRegister(metricClusterOutConnErrTotal) + metrics.Registry.MustRegister(metricClusterEnabled) + metrics.Registry.MustRegister(metricClusterRole) + metrics.Registry.MustRegister(metricClusterStatus) + metrics.Registry.MustRegister(metricClusterTerm) + + metrics.Registry.MustRegister(metricClusterLeaderSelf) + metrics.Registry.MustRegister(metricClusterVoteSelf) + metrics.Registry.MustRegister(metricClusterElectionTimer) + metrics.Registry.MustRegister(metricClusterNotCommittedEntryCount) + metrics.Registry.MustRegister(metricClusterNotAppliedEntryCount) + + metrics.Registry.MustRegister(metricClusterLogIndexStart) + metrics.Registry.MustRegister(metricClusterLogIndexNext) + metrics.Registry.MustRegister(metricClusterInConnTotal) + metrics.Registry.MustRegister(metricClusterOutConnTotal) + metrics.Registry.MustRegister(metricClusterInConnErrTotal) + metrics.Registry.MustRegister(metricClusterOutConnErrTotal) // to be implemented - prometheus.MustRegister(metricClusterPeerNextIndex) - prometheus.MustRegister(metricClusterPeerMatchIndex) - prometheus.MustRegister(metricClusterNextIndex) - prometheus.MustRegister(metricClusterMatchIndex) - prometheus.MustRegister(metricClusterPeerInConnInfo) - prometheus.MustRegister(metricClusterPeerOutConnInfo) - prometheus.MustRegister(metricClusterPeerCount) + metrics.Registry.MustRegister(metricClusterPeerNextIndex) + metrics.Registry.MustRegister(metricClusterPeerMatchIndex) + metrics.Registry.MustRegister(metricClusterNextIndex) + metrics.Registry.MustRegister(metricClusterMatchIndex) + metrics.Registry.MustRegister(metricClusterPeerInConnInfo) + metrics.Registry.MustRegister(metricClusterPeerOutConnInfo) + metrics.Registry.MustRegister(metricClusterPeerCount) } diff --git a/pkg/ovnmonitor/util.go b/pkg/ovnmonitor/util.go index 1a803a5da09e..612eac48d296 100644 --- a/pkg/ovnmonitor/util.go +++ b/pkg/ovnmonitor/util.go @@ -184,7 +184,7 @@ func getClusterInfo(direction, dbName string) (*OVNDBClusterStatus, error) { cmd := exec.Command("sh", "-c", cmdstr) // #nosec G204 output, err := cmd.CombinedOutput() if err != nil { - return nil, fmt.Errorf("failed to retrieve cluster/status info for database %s: %v", dbName, err) + return nil, fmt.Errorf("failed to retrieve cluster/status info for database %s: %w", dbName, err) } for _, line := range strings.Split(string(output), "\n") { diff --git a/pkg/ovs/adapter.go b/pkg/ovs/adapter.go index a2315b68194c..63c33e57e575 100644 --- a/pkg/ovs/adapter.go +++ b/pkg/ovs/adapter.go @@ -1,6 +1,9 @@ package ovs -import "github.com/prometheus/client_golang/prometheus" +import ( + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) // OVN NB metrics var ovsClientRequestLatency = prometheus.NewHistogramVec( @@ -16,5 +19,5 @@ func init() { } func registerOvsClientMetrics() { - prometheus.MustRegister(ovsClientRequestLatency) + metrics.Registry.MustRegister(ovsClientRequestLatency) } diff --git a/pkg/ovs/interface.go b/pkg/ovs/interface.go index 0f6f72fdcd30..801fdb373516 100644 --- a/pkg/ovs/interface.go +++ b/pkg/ovs/interface.go @@ -5,6 +5,8 @@ import ( "github.com/ovn-org/libovsdb/ovsdb" + v1alpha1 "sigs.k8s.io/network-policy-api/apis/v1alpha1" + kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb" "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnsb" @@ -92,6 +94,7 @@ type LogicalSwitchPort interface { ListLogicalSwitchPortsWithLegacyExternalIDs() ([]ovnnb.LogicalSwitchPort, error) GetLogicalSwitchPort(lspName string, ignoreNotFound bool) (*ovnnb.LogicalSwitchPort, error) LogicalSwitchPortExists(name string) (bool, error) + SetLogicalSwitchPortActivationStrategy(lspName, chassis string) error // vm live migrate SetLogicalSwitchPortMigrateOptions(lspName, srcNodeName, targetNodeName string) error ResetLogicalSwitchPortMigrateOptions(lspName, srcNodeName, targetNodeName string, migratedFail bool) error @@ -149,6 +152,7 @@ type ACL interface { SGLostACL(sg *kubeovnv1.SecurityGroup) (bool, error) DeleteAcls(parentName, parentType, direction string, externalIDs map[string]string) error DeleteAclsOps(parentName, parentType, direction string, externalIDs map[string]string) ([]ovsdb.Operation, error) + UpdateAnpRuleACLOps(pgName, asName, protocol string, priority int, aclAction ovnnb.ACLAction, rulePorts []v1alpha1.AdminNetworkPolicyPort, isIngress, isBanp bool) ([]ovsdb.Operation, error) } type AddressSet interface { diff --git a/pkg/ovs/ovn-ic-nbctl.go b/pkg/ovs/ovn-ic-nbctl.go index 1ac9d90475da..4d6e070a8fa4 100644 --- a/pkg/ovs/ovn-ic-nbctl.go +++ b/pkg/ovs/ovn-ic-nbctl.go @@ -30,7 +30,7 @@ func (c LegacyClient) ovnIcNbCommand(cmdArgs ...string) (string, error) { if err != nil { code = "1" klog.Warningf("ovn-ic-nbctl command error: %s %s in %vms", OVNIcNbCtl, strings.Join(cmdArgs, " "), elapsed) - return "", fmt.Errorf("%s, %q", raw, err) + return "", fmt.Errorf("%s, %w", raw, err) } else if elapsed > 500 { klog.Warningf("ovn-ic-nbctl command took too long: %s %s in %vms", OVNIcNbCtl, strings.Join(cmdArgs, " "), elapsed) } @@ -41,7 +41,7 @@ func (c LegacyClient) GetTsSubnet(ts string) (string, error) { subnet, err := c.ovnIcNbCommand("get", "Transit_Switch", ts, "external_ids:subnet") if err != nil { klog.Error(err) - return "", fmt.Errorf("failed to get ts subnet, %v", err) + return "", fmt.Errorf("failed to get ts subnet, %w", err) } return subnet, nil } diff --git a/pkg/ovs/ovn-ic-sbctl.go b/pkg/ovs/ovn-ic-sbctl.go index a864d57c3913..a80ed60e8f47 100644 --- a/pkg/ovs/ovn-ic-sbctl.go +++ b/pkg/ovs/ovn-ic-sbctl.go @@ -1,6 +1,7 @@ package ovs import ( + "errors" "fmt" "os/exec" "strings" @@ -30,7 +31,7 @@ func (c LegacyClient) ovnIcSbCommand(cmdArgs ...string) (string, error) { if err != nil { code = "1" klog.Warningf("ovn-ic-sbctl command error: %s %s in %vms", OVNIcSbCtl, strings.Join(cmdArgs, " "), elapsed) - return "", fmt.Errorf("%s, %q", raw, err) + return "", fmt.Errorf("%s, %w", raw, err) } else if elapsed > 500 { klog.Warningf("ovn-ic-sbctl command took too long: %s %s in %vms", OVNIcSbCtl, strings.Join(cmdArgs, " "), elapsed) } @@ -41,7 +42,7 @@ func (c LegacyClient) FindUUIDWithAttrInTable(attribute, value, table string) ([ key := attribute + "=" + value output, err := c.ovnIcSbCommand("--format=csv", "--no-heading", "--data=bare", "--columns=_uuid", "find", table, key) if err != nil { - err := fmt.Errorf("failed to find ovn-ic-sb db, %v", err) + err := fmt.Errorf("failed to find ovn-ic-sb db, %w", err) klog.Error(err) return nil, err } @@ -60,7 +61,7 @@ func (c LegacyClient) DestroyTableWithUUID(uuid, table string) error { _, err := c.ovnIcSbCommand("destroy", table, uuid) if err != nil { klog.Error(err) - return fmt.Errorf("failed to destroy record %s in table %s: %v", uuid, table, err) + return fmt.Errorf("failed to destroy record %s in table %s: %w", uuid, table, err) } return nil } @@ -69,21 +70,21 @@ func (c LegacyClient) GetAzUUID(az string) (string, error) { uuids, err := c.FindUUIDWithAttrInTable("name", az, "availability_zone") if err != nil { klog.Error(err) - return "", fmt.Errorf("failed to get ovn-ic-sb availability_zone uuid: %v", err) + return "", fmt.Errorf("failed to get ovn-ic-sb availability_zone uuid: %w", err) } if len(uuids) == 1 { return uuids[0], nil } else if len(uuids) == 0 { return "", nil } - return "", fmt.Errorf("two same-name chassises in one db is insane") + return "", errors.New("two same-name chassises in one db is insane") } func (c LegacyClient) GetGatewayUUIDsInOneAZ(uuid string) ([]string, error) { gateways, err := c.FindUUIDWithAttrInTable("availability_zone", uuid, "gateway") if err != nil { klog.Error(err) - return nil, fmt.Errorf("failed to get ovn-ic-sb gateways with uuid %v: %v", uuid, err) + return nil, fmt.Errorf("failed to get ovn-ic-sb gateways with uuid %v: %w", uuid, err) } return gateways, nil } @@ -92,7 +93,7 @@ func (c LegacyClient) GetRouteUUIDsInOneAZ(uuid string) ([]string, error) { routes, err := c.FindUUIDWithAttrInTable("availability_zone", uuid, "route") if err != nil { klog.Error(err) - return nil, fmt.Errorf("failed to get ovn-ic-sb routes with uuid %v: %v", uuid, err) + return nil, fmt.Errorf("failed to get ovn-ic-sb routes with uuid %v: %w", uuid, err) } return routes, nil } @@ -100,7 +101,7 @@ func (c LegacyClient) GetRouteUUIDsInOneAZ(uuid string) ([]string, error) { func (c LegacyClient) GetPortBindingUUIDsInOneAZ(uuid string) ([]string, error) { portBindings, err := c.FindUUIDWithAttrInTable("availability_zone", uuid, "Port_Binding") if err != nil { - return nil, fmt.Errorf("failed to get ovn-ic-sb Port_Binding with uuid %v: %v", uuid, err) + return nil, fmt.Errorf("failed to get ovn-ic-sb Port_Binding with uuid %v: %w", uuid, err) } return portBindings, nil } @@ -108,7 +109,7 @@ func (c LegacyClient) GetPortBindingUUIDsInOneAZ(uuid string) ([]string, error) func (c LegacyClient) DestroyGateways(uuids []string) error { for _, uuid := range uuids { if err := c.DestroyTableWithUUID(uuid, "gateway"); err != nil { - return fmt.Errorf("failed to delete gateway %v: %v", uuid, err) + return fmt.Errorf("failed to delete gateway %v: %w", uuid, err) } } return nil @@ -117,7 +118,7 @@ func (c LegacyClient) DestroyGateways(uuids []string) error { func (c LegacyClient) DestroyRoutes(uuids []string) error { for _, uuid := range uuids { if err := c.DestroyTableWithUUID(uuid, "route"); err != nil { - return fmt.Errorf("failed to delete route %v: %v", uuid, err) + return fmt.Errorf("failed to delete route %v: %w", uuid, err) } } return nil @@ -126,7 +127,7 @@ func (c LegacyClient) DestroyRoutes(uuids []string) error { func (c LegacyClient) DestroyPortBindings(uuids []string) error { for _, uuid := range uuids { if err := c.DestroyTableWithUUID(uuid, "Port_Binding"); err != nil { - return fmt.Errorf("failed to delete Port_Binding %v: %v", uuid, err) + return fmt.Errorf("failed to delete Port_Binding %v: %w", uuid, err) } } return nil @@ -134,7 +135,7 @@ func (c LegacyClient) DestroyPortBindings(uuids []string) error { func (c LegacyClient) DestroyChassis(uuid string) error { if err := c.DestroyTableWithUUID(uuid, "availability_zone"); err != nil { - return fmt.Errorf("failed to delete chassis %v: %v", uuid, err) + return fmt.Errorf("failed to delete chassis %v: %w", uuid, err) } return nil } diff --git a/pkg/ovs/ovn-nb-acl.go b/pkg/ovs/ovn-nb-acl.go index bb8ec2bf1131..095b2f3cb2ec 100644 --- a/pkg/ovs/ovn-nb-acl.go +++ b/pkg/ovs/ovn-nb-acl.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "slices" "strconv" @@ -13,6 +14,8 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/klog/v2" + v1alpha1 "sigs.k8s.io/network-policy-api/apis/v1alpha1" + kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" ovsclient "github.com/kubeovn/kube-ovn/pkg/ovsdb/client" "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb" @@ -37,9 +40,9 @@ func (c *OVNNbClient) UpdateIngressACLOps(pgName, asIngressName, asExceptName, p } } - defaultDropACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionToLport, util.IngressDefaultDrop, allIPMatch.String(), ovnnb.ACLActionDrop, options) + defaultDropACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionToLport, util.IngressDefaultDrop, allIPMatch.String(), ovnnb.ACLActionDrop, util.NetpolACLTier, options) if err != nil { - return nil, fmt.Errorf("new default drop ingress acl for port group %s: %v", pgName, err) + return nil, fmt.Errorf("new default drop ingress acl for port group %s: %w", pgName, err) } acls = append(acls, defaultDropACL) @@ -48,9 +51,9 @@ func (c *OVNNbClient) UpdateIngressACLOps(pgName, asIngressName, asExceptName, p /* allow acl */ matches := newNetworkPolicyACLMatch(pgName, asIngressName, asExceptName, protocol, ovnnb.ACLDirectionToLport, npp, namedPortMap) for _, m := range matches { - allowACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionToLport, util.IngressAllowPriority, m, ovnnb.ACLActionAllowRelated) + allowACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionToLport, util.IngressAllowPriority, m, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) if err != nil { - return nil, fmt.Errorf("new allow ingress acl for port group %s: %v", pgName, err) + return nil, fmt.Errorf("new allow ingress acl for port group %s: %w", pgName, err) } acls = append(acls, allowACL) @@ -87,10 +90,10 @@ func (c *OVNNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, pro acl.Options["apply-after-lb"] = "true" } - defaultDropACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionFromLport, util.EgressDefaultDrop, allIPMatch.String(), ovnnb.ACLActionDrop, options) + defaultDropACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionFromLport, util.EgressDefaultDrop, allIPMatch.String(), ovnnb.ACLActionDrop, util.NetpolACLTier, options) if err != nil { klog.Error(err) - return nil, fmt.Errorf("new default drop egress acl for port group %s: %v", pgName, err) + return nil, fmt.Errorf("new default drop egress acl for port group %s: %w", pgName, err) } acls = append(acls, defaultDropACL) @@ -99,7 +102,7 @@ func (c *OVNNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, pro /* allow acl */ matches := newNetworkPolicyACLMatch(pgName, asEgressName, asExceptName, protocol, ovnnb.ACLDirectionFromLport, npp, namedPortMap) for _, m := range matches { - allowACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionFromLport, util.EgressAllowPriority, m, ovnnb.ACLActionAllowRelated, func(acl *ovnnb.ACL) { + allowACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionFromLport, util.EgressAllowPriority, m, ovnnb.ACLActionAllowRelated, util.NetpolACLTier, func(acl *ovnnb.ACL) { if acl.Options == nil { acl.Options = make(map[string]string) } @@ -107,7 +110,7 @@ func (c *OVNNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, pro }) if err != nil { klog.Error(err) - return nil, fmt.Errorf("new allow egress acl for port group %s: %v", pgName, err) + return nil, fmt.Errorf("new allow egress acl for port group %s: %w", pgName, err) } acls = append(acls, allowACL) @@ -133,7 +136,7 @@ func (c *OVNNbClient) CreateGatewayACL(lsName, pgName, gateway string) error { case len(lsName) != 0: parentName, parentType = lsName, logicalSwitchKey default: - return fmt.Errorf("one of port group name and logical switch name must be specified") + return errors.New("one of port group name and logical switch name must be specified") } for _, gw := range strings.Split(gateway, ",") { @@ -143,10 +146,10 @@ func (c *OVNNbClient) CreateGatewayACL(lsName, pgName, gateway string) error { ipSuffix = "ip6" } - allowIngressACL, err := c.newACL(parentName, ovnnb.ACLDirectionToLport, util.IngressAllowPriority, fmt.Sprintf("%s.src == %s", ipSuffix, gw), ovnnb.ACLActionAllowStateless) + allowIngressACL, err := c.newACL(parentName, ovnnb.ACLDirectionToLport, util.IngressAllowPriority, fmt.Sprintf("%s.src == %s", ipSuffix, gw), ovnnb.ACLActionAllowStateless, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new allow ingress acl for %s: %v", parentName, err) + return fmt.Errorf("new allow ingress acl for %s: %w", parentName, err) } options := func(acl *ovnnb.ACL) { @@ -156,28 +159,27 @@ func (c *OVNNbClient) CreateGatewayACL(lsName, pgName, gateway string) error { acl.Options["apply-after-lb"] = "true" } - allowEgressACL, err := c.newACL(parentName, ovnnb.ACLDirectionFromLport, util.EgressAllowPriority, fmt.Sprintf("%s.dst == %s", ipSuffix, gw), ovnnb.ACLActionAllowStateless, options) + allowEgressACL, err := c.newACL(parentName, ovnnb.ACLDirectionFromLport, util.EgressAllowPriority, fmt.Sprintf("%s.dst == %s", ipSuffix, gw), ovnnb.ACLActionAllowStateless, util.NetpolACLTier, options) if err != nil { klog.Error(err) - return fmt.Errorf("new allow egress acl for %s: %v", parentName, err) + return fmt.Errorf("new allow egress acl for %s: %w", parentName, err) } acls = append(acls, allowIngressACL, allowEgressACL) if ipSuffix == "ip6" { - ndACL, err := c.newACL(parentName, ovnnb.ACLDirectionFromLport, util.EgressAllowPriority, "nd || nd_ra || nd_rs", ovnnb.ACLActionAllowStateless, options) + ndACL, err := c.newACL(parentName, ovnnb.ACLDirectionFromLport, util.EgressAllowPriority, "nd || nd_ra || nd_rs", ovnnb.ACLActionAllowStateless, util.NetpolACLTier, options) if err != nil { klog.Error(err) - return fmt.Errorf("new nd acl for %s: %v", parentName, err) + return fmt.Errorf("new nd acl for %s: %w", parentName, err) } acls = append(acls, ndACL) } - } if err := c.CreateAcls(parentName, parentType, acls...); err != nil { - return fmt.Errorf("add gateway acls to %s: %v", pgName, err) + return fmt.Errorf("add gateway acls to %s: %w", pgName, err) } return nil @@ -195,10 +197,10 @@ func (c *OVNNbClient) CreateNodeACL(pgName, nodeIPStr, joinIPStr string) error { } pgAs := fmt.Sprintf("%s_%s", pgName, ipSuffix) - allowIngressACL, err := c.newACL(pgName, ovnnb.ACLDirectionToLport, util.NodeAllowPriority, fmt.Sprintf("%s.src == %s && %s.dst == $%s", ipSuffix, nodeIP, ipSuffix, pgAs), ovnnb.ACLActionAllowRelated) + allowIngressACL, err := c.newACL(pgName, ovnnb.ACLDirectionToLport, util.NodeAllowPriority, fmt.Sprintf("%s.src == %s && %s.dst == $%s", ipSuffix, nodeIP, ipSuffix, pgAs), ovnnb.ACLActionAllowRelated, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new allow ingress acl for port group %s: %v", pgName, err) + return fmt.Errorf("new allow ingress acl for port group %s: %w", pgName, err) } options := func(acl *ovnnb.ACL) { @@ -208,10 +210,10 @@ func (c *OVNNbClient) CreateNodeACL(pgName, nodeIPStr, joinIPStr string) error { acl.Options["apply-after-lb"] = "true" } - allowEgressACL, err := c.newACL(pgName, ovnnb.ACLDirectionFromLport, util.NodeAllowPriority, fmt.Sprintf("%s.dst == %s && %s.src == $%s", ipSuffix, nodeIP, ipSuffix, pgAs), ovnnb.ACLActionAllowRelated, options) + allowEgressACL, err := c.newACL(pgName, ovnnb.ACLDirectionFromLport, util.NodeAllowPriority, fmt.Sprintf("%s.dst == %s && %s.src == $%s", ipSuffix, nodeIP, ipSuffix, pgAs), ovnnb.ACLActionAllowRelated, util.NetpolACLTier, options) if err != nil { klog.Error(err) - return fmt.Errorf("new allow egress acl for port group %s: %v", pgName, err) + return fmt.Errorf("new allow egress acl for port group %s: %w", pgName, err) } acls = append(acls, allowIngressACL, allowEgressACL) @@ -242,7 +244,7 @@ func (c *OVNNbClient) CreateNodeACL(pgName, nodeIPStr, joinIPStr string) error { } if err := c.CreateAcls(pgName, portGroupKey, acls...); err != nil { - return fmt.Errorf("add node acls to port group %s: %v", pgName, err) + return fmt.Errorf("add node acls to port group %s: %w", pgName, err) } return nil @@ -251,20 +253,20 @@ func (c *OVNNbClient) CreateNodeACL(pgName, nodeIPStr, joinIPStr string) error { func (c *OVNNbClient) CreateSgDenyAllACL(sgName string) error { pgName := GetSgPortGroupName(sgName) - ingressACL, err := c.newACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupDropPriority, fmt.Sprintf("outport == @%s && ip", pgName), ovnnb.ACLActionDrop) + ingressACL, err := c.newACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupDropPriority, fmt.Sprintf("outport == @%s && ip", pgName), ovnnb.ACLActionDrop, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new deny all ingress acl for security group %s: %v", sgName, err) + return fmt.Errorf("new deny all ingress acl for security group %s: %w", sgName, err) } - egressACL, err := c.newACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupDropPriority, fmt.Sprintf("inport == @%s && ip", pgName), ovnnb.ACLActionDrop) + egressACL, err := c.newACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupDropPriority, fmt.Sprintf("inport == @%s && ip", pgName), ovnnb.ACLActionDrop, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new deny all egress acl for security group %s: %v", sgName, err) + return fmt.Errorf("new deny all egress acl for security group %s: %w", sgName, err) } if err := c.CreateAcls(pgName, portGroupKey, ingressACL, egressACL); err != nil { - return fmt.Errorf("add deny all acl to port group %s: %v", pgName, err) + return fmt.Errorf("add deny all acl to port group %s: %w", pgName, err) } return nil @@ -294,7 +296,7 @@ func (c *OVNNbClient) CreateSgBaseACL(sgName, direction string) error { acls := make([]*ovnnb.ACL, 0) newACL := func(match string) { - acl, err := c.newACL(pgName, direction, util.SecurityGroupBasePriority, match, ovnnb.ACLActionAllowRelated) + acl, err := c.newACL(pgName, direction, util.SecurityGroupBasePriority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) if err != nil { klog.Error(err) klog.Errorf("new base ingress acl for security group %s: %v", sgName, err) @@ -345,7 +347,7 @@ func (c *OVNNbClient) CreateSgBaseACL(sgName, direction string) error { newACL(vrrpMatch.String()) if err := c.CreateAcls(pgName, portGroupKey, acls...); err != nil { - return fmt.Errorf("add ingress acls to port group %s: %v", pgName, err) + return fmt.Errorf("add ingress acls to port group %s: %w", pgName, err) } return nil } @@ -355,7 +357,7 @@ func (c *OVNNbClient) UpdateSgACL(sg *kubeovnv1.SecurityGroup, direction string) // clear acl if err := c.DeleteAcls(pgName, portGroupKey, direction, nil); err != nil { - return fmt.Errorf("delete direction '%s' acls from port group %s: %v", direction, pgName, err) + return fmt.Errorf("delete direction '%s' acls from port group %s: %w", direction, pgName, err) } acls := make([]*ovnnb.ACL, 0, 2) @@ -381,10 +383,10 @@ func (c *OVNNbClient) UpdateSgACL(sg *kubeovnv1.SecurityGroup, direction string) NewACLMatch(ipSuffix, "", "", ""), NewACLMatch(ipSuffix+"."+srcOrDst, "==", "$"+asName, ""), ) - acl, err := c.newACL(pgName, direction, util.SecurityGroupAllowPriority, match.String(), ovnnb.ACLActionAllowRelated) + acl, err := c.newACL(pgName, direction, util.SecurityGroupAllowPriority, match.String(), ovnnb.ACLActionAllowRelated, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new allow acl for security group %s: %v", sg.Name, err) + return fmt.Errorf("new allow acl for security group %s: %w", sg.Name, err) } acls = append(acls, acl) @@ -396,13 +398,13 @@ func (c *OVNNbClient) UpdateSgACL(sg *kubeovnv1.SecurityGroup, direction string) acl, err := c.newSgRuleACL(sg.Name, direction, rule) if err != nil { klog.Error(err) - return fmt.Errorf("new rule acl for security group %s: %v", sg.Name, err) + return fmt.Errorf("new rule acl for security group %s: %w", sg.Name, err) } acls = append(acls, acl) } if err := c.CreateAcls(pgName, portGroupKey, acls...); err != nil { - return fmt.Errorf("add acl to port group %s: %v", pgName, err) + return fmt.Errorf("add acl to port group %s: %w", pgName, err) } return nil @@ -410,7 +412,7 @@ func (c *OVNNbClient) UpdateSgACL(sg *kubeovnv1.SecurityGroup, direction string) func (c *OVNNbClient) UpdateLogicalSwitchACL(lsName, cidrBlock string, subnetAcls []kubeovnv1.ACL, allowEWTraffic bool) error { if err := c.DeleteAcls(lsName, logicalSwitchKey, "", map[string]string{"subnet": lsName}); err != nil { - return fmt.Errorf("delete subnet acls from %s: %v", lsName, err) + return fmt.Errorf("delete subnet acls from %s: %w", lsName, err) } if len(subnetAcls) == 0 { @@ -440,17 +442,17 @@ func (c *OVNNbClient) UpdateLogicalSwitchACL(lsName, cidrBlock string, subnetAcl NewACLMatch(ipSuffix+".dst", "==", cidr, ""), ) - ingressSameSubnetACL, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.AllowEWTrafficPriority, sameSubnetMatch.String(), ovnnb.ACLActionAllow, options) + ingressSameSubnetACL, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.AllowEWTrafficPriority, sameSubnetMatch.String(), ovnnb.ACLActionAllow, util.NetpolACLTier, options) if err != nil { klog.Error(err) - return fmt.Errorf("new same subnet ingress acl for logical switch %s: %v", lsName, err) + return fmt.Errorf("new same subnet ingress acl for logical switch %s: %w", lsName, err) } acls = append(acls, ingressSameSubnetACL) - egressSameSubnetACL, err := c.newACL(lsName, ovnnb.ACLDirectionFromLport, util.AllowEWTrafficPriority, sameSubnetMatch.String(), ovnnb.ACLActionAllow, options) + egressSameSubnetACL, err := c.newACL(lsName, ovnnb.ACLDirectionFromLport, util.AllowEWTrafficPriority, sameSubnetMatch.String(), ovnnb.ACLActionAllow, util.NetpolACLTier, options) if err != nil { klog.Error(err) - return fmt.Errorf("new same subnet egress acl for logical switch %s: %v", lsName, err) + return fmt.Errorf("new same subnet egress acl for logical switch %s: %w", lsName, err) } acls = append(acls, egressSameSubnetACL) } @@ -458,16 +460,16 @@ func (c *OVNNbClient) UpdateLogicalSwitchACL(lsName, cidrBlock string, subnetAcl /* recreate logical switch acl */ for _, subnetACL := range subnetAcls { - acl, err := c.newACL(lsName, subnetACL.Direction, strconv.Itoa(subnetACL.Priority), subnetACL.Match, subnetACL.Action, options) + acl, err := c.newACL(lsName, subnetACL.Direction, strconv.Itoa(subnetACL.Priority), subnetACL.Match, subnetACL.Action, util.NetpolACLTier, options) if err != nil { klog.Error(err) - return fmt.Errorf("new acl for logical switch %s: %v", lsName, err) + return fmt.Errorf("new acl for logical switch %s: %w", lsName, err) } acls = append(acls, acl) } if err := c.CreateAcls(lsName, logicalSwitchKey, acls...); err != nil { - return fmt.Errorf("add acls to logical switch %s: %v", lsName, err) + return fmt.Errorf("add acls to logical switch %s: %w", lsName, err) } return nil @@ -476,17 +478,17 @@ func (c *OVNNbClient) UpdateLogicalSwitchACL(lsName, cidrBlock string, subnetAcl // UpdateACL update acl func (c *OVNNbClient) UpdateACL(acl *ovnnb.ACL, fields ...interface{}) error { if acl == nil { - return fmt.Errorf("address_set is nil") + return errors.New("address_set is nil") } op, err := c.Where(acl).Update(acl, fields...) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for updating acl with 'direction %s priority %d match %s': %v", acl.Direction, acl.Priority, acl.Match, err) + return fmt.Errorf("generate operations for updating acl with 'direction %s priority %d match %s': %w", acl.Direction, acl.Priority, acl.Match, err) } if err = c.Transact("acl-update", op); err != nil { - return fmt.Errorf("update acl with 'direction %s priority %d match %s': %v", acl.Direction, acl.Priority, acl.Match, err) + return fmt.Errorf("update acl with 'direction %s priority %d match %s': %w", acl.Direction, acl.Priority, acl.Match, err) } return nil @@ -496,7 +498,7 @@ func (c *OVNNbClient) UpdateACL(acl *ovnnb.ACL, fields ...interface{}) error { func (c *OVNNbClient) SetLogicalSwitchPrivate(lsName, cidrBlock, nodeSwitchCIDR string, allowSubnets []string) error { // clear acls if err := c.DeleteAcls(lsName, logicalSwitchKey, "", nil); err != nil { - return fmt.Errorf("clear logical switch %s acls: %v", lsName, err) + return fmt.Errorf("clear logical switch %s acls: %w", lsName, err) } acls := make([]*ovnnb.ACL, 0) @@ -510,10 +512,10 @@ func (c *OVNNbClient) SetLogicalSwitchPrivate(lsName, cidrBlock, nodeSwitchCIDR acl.Severity = &ovnnb.ACLSeverityWarning } - defaultDropACL, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.DefaultDropPriority, allIPMatch.String(), ovnnb.ACLActionDrop, options) + defaultDropACL, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.DefaultDropPriority, allIPMatch.String(), ovnnb.ACLActionDrop, util.NetpolACLTier, options) if err != nil { klog.Error(err) - return fmt.Errorf("new default drop ingress acl for logical switch %s: %v", lsName, err) + return fmt.Errorf("new default drop ingress acl for logical switch %s: %w", lsName, err) } acls = append(acls, defaultDropACL) @@ -527,10 +529,10 @@ func (c *OVNNbClient) SetLogicalSwitchPrivate(lsName, cidrBlock, nodeSwitchCIDR match := NewACLMatch(ipSuffix+".src", "==", nodeCidr, "") - acl, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.NodeAllowPriority, match.String(), ovnnb.ACLActionAllowRelated) + acl, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.NodeAllowPriority, match.String(), ovnnb.ACLActionAllowRelated, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new node subnet ingress acl for logical switch %s: %v", lsName, err) + return fmt.Errorf("new node subnet ingress acl for logical switch %s: %w", lsName, err) } acls = append(acls, acl) @@ -563,10 +565,10 @@ func (c *OVNNbClient) SetLogicalSwitchPrivate(lsName, cidrBlock, nodeSwitchCIDR ), ) - acl, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.SubnetAllowPriority, match.String(), ovnnb.ACLActionAllowRelated) + acl, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.SubnetAllowPriority, match.String(), ovnnb.ACLActionAllowRelated, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new allow subnet ingress acl for logical switch %s: %v", lsName, err) + return fmt.Errorf("new allow subnet ingress acl for logical switch %s: %w", lsName, err) } acls = append(acls, acl) @@ -588,10 +590,10 @@ func (c *OVNNbClient) SetLogicalSwitchPrivate(lsName, cidrBlock, nodeSwitchCIDR NewACLMatch(ipSuffix+".dst", "==", cidr, ""), ) - sameSubnetACL, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.SubnetAllowPriority, sameSubnetMatch.String(), ovnnb.ACLActionAllowRelated) + sameSubnetACL, err := c.newACL(lsName, ovnnb.ACLDirectionToLport, util.SubnetAllowPriority, sameSubnetMatch.String(), ovnnb.ACLActionAllowRelated, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new same subnet ingress acl for logical switch %s: %v", lsName, err) + return fmt.Errorf("new same subnet ingress acl for logical switch %s: %w", lsName, err) } acls = append(acls, sameSubnetACL) @@ -611,7 +613,7 @@ func (c *OVNNbClient) SetLogicalSwitchPrivate(lsName, cidrBlock, nodeSwitchCIDR if err := c.CreateAcls(lsName, logicalSwitchKey, acls...); err != nil { klog.Error(err) - return fmt.Errorf("add ingress acls to logical switch %s: %v", lsName, err) + return fmt.Errorf("add ingress acls to logical switch %s: %w", lsName, err) } return nil @@ -649,7 +651,7 @@ func (c *OVNNbClient) SetACLLog(pgName string, logEnable, isIngress bool) error err = c.UpdateACL(acl, &acl.Log) if err != nil { klog.Error(err) - return fmt.Errorf("update acl: %v", err) + return fmt.Errorf("update acl: %w", err) } return nil @@ -665,27 +667,27 @@ func (c *OVNNbClient) CreateAcls(parentName, parentType string, acls ...*ovnnb.A } if err = c.Transact("acls-add", ops); err != nil { - return fmt.Errorf("add acls to type %s %s: %v", parentType, parentName, err) + return fmt.Errorf("add acls to type %s %s: %w", parentType, parentName, err) } return nil } func (c *OVNNbClient) CreateBareACL(parentName, direction, priority, match, action string) error { - acl, err := c.newACL(parentName, direction, priority, match, action) + acl, err := c.newACL(parentName, direction, priority, match, action, util.NetpolACLTier) if err != nil { klog.Error(err) - return fmt.Errorf("new acl direction %s priority %s match %s action %s: %v", direction, priority, match, action, err) + return fmt.Errorf("new acl direction %s priority %s match %s action %s: %w", direction, priority, match, action, err) } op, err := c.ovsDbClient.Create(acl) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating acl direction %s priority %s match %s action %s: %v", direction, priority, match, action, err) + return fmt.Errorf("generate operations for creating acl direction %s priority %s match %s action %s: %w", direction, priority, match, action, err) } if err = c.Transact("acl-create", op); err != nil { - return fmt.Errorf("create acl direction %s priority %s match %s action %s: %v", direction, priority, match, action, err) + return fmt.Errorf("create acl direction %s priority %s match %s action %s: %w", direction, priority, match, action, err) } return nil @@ -702,7 +704,7 @@ func (c *OVNNbClient) DeleteAcls(parentName, parentType, direction string, exter } if err = c.Transact("acls-del", ops); err != nil { - return fmt.Errorf("del acls from type %s %s: %v", parentType, parentName, err) + return fmt.Errorf("del acls from type %s %s: %w", parentType, parentName, err) } return nil @@ -725,19 +727,19 @@ func (c *OVNNbClient) DeleteACL(parentName, parentType, direction, priority, mat removeACLOp, err = c.portGroupUpdateACLOp(parentName, []string{acl.UUID}, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for deleting acl from port group %s: %v", parentName, err) + return fmt.Errorf("generate operations for deleting acl from port group %s: %w", parentName, err) } } else { // remove acl from logical switch removeACLOp, err = c.logicalSwitchUpdateACLOp(parentName, []string{acl.UUID}, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for deleting acl from logical switch %s: %v", parentName, err) + return fmt.Errorf("generate operations for deleting acl from logical switch %s: %w", parentName, err) } } if err = c.Transact("acls-del", removeACLOp); err != nil { klog.Error(err) - return fmt.Errorf("del acls from type %s %s: %v", parentType, parentName, err) + return fmt.Errorf("del acls from type %s %s: %w", parentType, parentName, err) } return nil @@ -748,7 +750,7 @@ func (c *OVNNbClient) DeleteACL(parentName, parentType, direction, priority, mat func (c *OVNNbClient) GetACL(parent, direction, priority, match string, ignoreNotFound bool) (*ovnnb.ACL, error) { // this is necessary because may exist same direction, priority and match acl in different port group or logical switch if len(parent) == 0 { - return nil, fmt.Errorf("the parent name is required") + return nil, errors.New("the parent name is required") } ctx, cancel := context.WithTimeout(context.Background(), c.Timeout) @@ -760,7 +762,7 @@ func (c *OVNNbClient) GetACL(parent, direction, priority, match string, ignoreNo if err := c.ovsDbClient.WhereCache(func(acl *ovnnb.ACL) bool { return len(acl.ExternalIDs) != 0 && acl.ExternalIDs[aclParentKey] == parent && acl.Direction == direction && acl.Priority == intPriority && acl.Match == match }).List(ctx, &aclList); err != nil { - return nil, fmt.Errorf("get acl with 'parent %s direction %s priority %s match %s': %v", parent, direction, priority, match, err) + return nil, fmt.Errorf("get acl with 'parent %s direction %s priority %s match %s': %w", parent, direction, priority, match, err) } // not found @@ -792,7 +794,7 @@ func (c *OVNNbClient) ListAcls(direction string, externalIDs map[string]string) if err := c.WhereCache(aclFilter(direction, externalIDs)).List(ctx, &aclList); err != nil { klog.Error(err) - return nil, fmt.Errorf("list acls: %v", err) + return nil, fmt.Errorf("list acls: %w", err) } return aclList, nil @@ -804,9 +806,9 @@ func (c *OVNNbClient) ACLExists(parent, direction, priority, match string) (bool } // newACL return acl with basic information -func (c *OVNNbClient) newACL(parent, direction, priority, match, action string, options ...func(acl *ovnnb.ACL)) (*ovnnb.ACL, error) { +func (c *OVNNbClient) newACL(parent, direction, priority, match, action string, tier int, options ...func(acl *ovnnb.ACL)) (*ovnnb.ACL, error) { if len(parent) == 0 { - return nil, fmt.Errorf("the parent name is required") + return nil, errors.New("the parent name is required") } if len(direction) == 0 || len(priority) == 0 || len(match) == 0 || len(action) == 0 { @@ -816,7 +818,7 @@ func (c *OVNNbClient) newACL(parent, direction, priority, match, action string, exists, err := c.ACLExists(parent, direction, priority, match) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get parent %s acl: %v", parent, err) + return nil, fmt.Errorf("get parent %s acl: %w", parent, err) } // found, ignore @@ -835,6 +837,7 @@ func (c *OVNNbClient) newACL(parent, direction, priority, match, action string, ExternalIDs: map[string]string{ aclParentKey: parent, }, + Tier: tier, } for _, option := range options { @@ -847,9 +850,9 @@ func (c *OVNNbClient) newACL(parent, direction, priority, match, action string, // newACLWithoutCheck return acl with basic information without check acl exists, // this would cause duplicated acl, so don't use this function to create acl normally, // but maybe used for updating network policy acl -func (c *OVNNbClient) newACLWithoutCheck(parent, direction, priority, match, action string, options ...func(acl *ovnnb.ACL)) (*ovnnb.ACL, error) { +func (c *OVNNbClient) newACLWithoutCheck(parent, direction, priority, match, action string, tier int, options ...func(acl *ovnnb.ACL)) (*ovnnb.ACL, error) { if len(parent) == 0 { - return nil, fmt.Errorf("the parent name is required") + return nil, errors.New("the parent name is required") } if len(direction) == 0 || len(priority) == 0 || len(match) == 0 || len(action) == 0 { @@ -867,6 +870,7 @@ func (c *OVNNbClient) newACLWithoutCheck(parent, direction, priority, match, act ExternalIDs: map[string]string{ aclParentKey: parent, }, + Tier: tier, } for _, option := range options { @@ -949,10 +953,10 @@ func (c *OVNNbClient) newSgRuleACL(sgName, direction string, rule *kubeovnv1.SgR highestPriority, _ := strconv.Atoi(util.SecurityGroupHighestPriority) - acl, err := c.newACL(pgName, direction, strconv.Itoa(highestPriority-rule.Priority), match.String(), action) + acl, err := c.newACL(pgName, direction, strconv.Itoa(highestPriority-rule.Priority), match.String(), action, util.NetpolACLTier) if err != nil { klog.Error(err) - return nil, fmt.Errorf("new security group acl for port group %s: %v", pgName, err) + return nil, fmt.Errorf("new security group acl for port group %s: %w", pgName, err) } return acl, nil @@ -1026,7 +1030,7 @@ func newNetworkPolicyACLMatch(pgName, asAllowName, asExceptName, protocol, direc oneTCPMatch := NewAndACLMatch( allowedIPMatch, - NewACLMatch(tcpKey, "==", fmt.Sprintf("%d", portID), ""), + NewACLMatch(tcpKey, "==", strconv.Itoa(int(portID)), ""), ) matches = append(matches, oneTCPMatch.String()) @@ -1038,7 +1042,7 @@ func newNetworkPolicyACLMatch(pgName, asAllowName, asExceptName, protocol, direc tcpKey := protocol + ".dst" severalTCPMatch := NewAndACLMatch( allowedIPMatch, - NewACLMatch(tcpKey, "<=", fmt.Sprintf("%d", port.Port.IntVal), fmt.Sprintf("%d", *port.EndPort)), + NewACLMatch(tcpKey, "<=", strconv.Itoa(int(port.Port.IntVal)), strconv.Itoa(int(*port.EndPort))), ) matches = append(matches, severalTCPMatch.String()) } @@ -1104,7 +1108,7 @@ func (c *OVNNbClient) CreateAclsOps(parentName, parentType string, acls ...*ovnn createAclsOp, err := c.ovsDbClient.Create(models...) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for creating acls: %v", err) + return nil, fmt.Errorf("generate operations for creating acls: %w", err) } var aclAddOp []ovsdb.Operation @@ -1112,13 +1116,13 @@ func (c *OVNNbClient) CreateAclsOps(parentName, parentType string, acls ...*ovnn aclAddOp, err = c.portGroupUpdateACLOp(parentName, aclUUIDs, ovsdb.MutateOperationInsert) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for adding acls to port group %s: %v", parentName, err) + return nil, fmt.Errorf("generate operations for adding acls to port group %s: %w", parentName, err) } } else { // acl attach to logical switch aclAddOp, err = c.logicalSwitchUpdateACLOp(parentName, aclUUIDs, ovsdb.MutateOperationInsert) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for adding acls to logical switch %s: %v", parentName, err) + return nil, fmt.Errorf("generate operations for adding acls to logical switch %s: %w", parentName, err) } } @@ -1143,7 +1147,7 @@ func (c *OVNNbClient) DeleteAclsOps(parentName, parentType, direction string, ex acls, err := c.ListAcls(direction, externalIDs) if err != nil { klog.Error(err) - return nil, fmt.Errorf("list type %s %s acls: %v", parentType, parentName, err) + return nil, fmt.Errorf("list type %s %s acls: %w", parentType, parentName, err) } aclUUIDs := make([]string, 0, len(acls)) @@ -1157,13 +1161,13 @@ func (c *OVNNbClient) DeleteAclsOps(parentName, parentType, direction string, ex removeACLOp, err = c.portGroupUpdateACLOp(parentName, aclUUIDs, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for deleting acls from port group %s: %v", parentName, err) + return nil, fmt.Errorf("generate operations for deleting acls from port group %s: %w", parentName, err) } } else { // remove acl from logical switch removeACLOp, err = c.logicalSwitchUpdateACLOp(parentName, aclUUIDs, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for deleting acls from logical switch %s: %v", parentName, err) + return nil, fmt.Errorf("generate operations for deleting acls from logical switch %s: %w", parentName, err) } } @@ -1238,7 +1242,7 @@ func (c *OVNNbClient) sgRuleNoACL(sgName, direction string, rule *kubeovnv1.SgRu exists, err := c.ACLExists(pgName, direction, strconv.Itoa(rule.Priority), match.String()) if err != nil { - err = fmt.Errorf("failed to check acl rule for security group %s: %v", sgName, err) + err = fmt.Errorf("failed to check acl rule for security group %s: %w", sgName, err) klog.Error(err) return false, err } @@ -1278,3 +1282,111 @@ func (c *OVNNbClient) SGLostACL(sg *kubeovnv1.SecurityGroup) (bool, error) { } return false, nil } + +// UpdateAnpRuleACLOps return operation that creates an ingress/egress ACL +func (c *OVNNbClient) UpdateAnpRuleACLOps(pgName, asName, protocol string, priority int, aclAction ovnnb.ACLAction, rulePorts []v1alpha1.AdminNetworkPolicyPort, isIngress, isBanp bool) ([]ovsdb.Operation, error) { + acls := make([]*ovnnb.ACL, 0, 10) + + options := func(acl *ovnnb.ACL) { + if acl.ExternalIDs == nil { + acl.ExternalIDs = make(map[string]string) + } + acl.ExternalIDs[aclParentKey] = pgName + + if acl.Options == nil { + acl.Options = make(map[string]string) + } + acl.Options["apply-after-lb"] = "true" + } + + var direction ovnnb.ACLDirection + if isIngress { + direction = ovnnb.ACLDirectionToLport + } else { + direction = ovnnb.ACLDirectionFromLport + } + + var tier int + if isBanp { + tier = util.BanpACLTier + } else { + tier = util.AnpACLTier + } + + matches := newAnpACLMatch(pgName, asName, protocol, direction, rulePorts) + for _, m := range matches { + strPriority := strconv.Itoa(priority) + setACL, err := c.newACLWithoutCheck(pgName, direction, strPriority, m, aclAction, tier, options) + if err != nil { + return nil, fmt.Errorf("new ingress acl for port group %s: %w", pgName, err) + } + + acls = append(acls, setACL) + } + + ops, err := c.CreateAclsOps(pgName, portGroupKey, acls...) + if err != nil { + return nil, err + } + + return ops, nil +} + +func newAnpACLMatch(pgName, asName, protocol, direction string, rulePorts []v1alpha1.AdminNetworkPolicyPort) []string { + ipSuffix := "ip4" + if protocol == kubeovnv1.ProtocolIPv6 { + ipSuffix = "ip6" + } + + // ingress rule + srcOrDst, portDirection := "src", "outport" + if direction == ovnnb.ACLDirectionFromLport { // egress rule + srcOrDst = "dst" + portDirection = "inport" + } + + ipKey := ipSuffix + "." + srcOrDst + + // match all traffic to or from pgName + allIPMatch := NewAndACLMatch( + NewACLMatch(portDirection, "==", "@"+pgName, ""), + NewACLMatch("ip", "", "", ""), + ) + + selectIPMatch := NewAndACLMatch( + allIPMatch, + NewACLMatch(ipKey, "==", "$"+asName, ""), + ) + if len(rulePorts) == 0 { + return []string{selectIPMatch.String()} + } + + matches := make([]string, 0, 10) + for _, port := range rulePorts { + // Exactly one field must be set. + // Do not support NamedPort now + switch { + case port.PortNumber != nil: + protocol := strings.ToLower(string(port.PortNumber.Protocol)) + protocolKey := protocol + ".dst" + + oneMatch := NewAndACLMatch( + selectIPMatch, + NewACLMatch(protocolKey, "==", strconv.Itoa(int(port.PortNumber.Port)), ""), + ) + matches = append(matches, oneMatch.String()) + case port.PortRange != nil: + protocol := strings.ToLower(string(port.PortRange.Protocol)) + protocolKey := protocol + ".dst" + + severalMatch := NewAndACLMatch( + selectIPMatch, + NewACLMatch(protocolKey, "<=", strconv.Itoa(int(port.PortRange.Start)), strconv.Itoa(int(port.PortRange.End))), + ) + matches = append(matches, severalMatch.String()) + default: + klog.Errorf("failed to check port for anp ingress rule, pg %s, as %s", pgName, asName) + } + } + return matches +} diff --git a/pkg/ovs/ovn-nb-acl_test.go b/pkg/ovs/ovn-nb-acl_test.go index f792fbdda763..b41cb7b4e087 100644 --- a/pkg/ovs/ovn-nb-acl_test.go +++ b/pkg/ovs/ovn-nb-acl_test.go @@ -41,7 +41,7 @@ func mockNetworkPolicyPort() []netv1.NetworkPolicyPort { } } -func newACL(parentName, direction, priority, match, action string, options ...func(acl *ovnnb.ACL)) *ovnnb.ACL { +func newACL(parentName, direction, priority, match, action string, tier int, options ...func(acl *ovnnb.ACL)) *ovnnb.ACL { intPriority, _ := strconv.Atoi(priority) acl := &ovnnb.ACL{ @@ -53,6 +53,7 @@ func newACL(parentName, direction, priority, match, action string, options ...fu ExternalIDs: map[string]string{ aclParentKey: parentName, }, + Tier: tier, } for _, option := range options { @@ -224,7 +225,7 @@ func (suite *OvnClientTestSuite) testCreateGatewayACL() { acl, err := ovnClient.GetACL(name, direction, priority, match, false) require.NoError(t, err) - expect := newACL(name, direction, priority, match, ovnnb.ACLActionAllowStateless) + expect := newACL(name, direction, priority, match, ovnnb.ACLActionAllowStateless, util.NetpolACLTier) expect.UUID = acl.UUID if len(options) != 0 { expect.Options = options @@ -361,7 +362,7 @@ func (suite *OvnClientTestSuite) testCreateNodeACL() { checkACL := func(pg *ovnnb.PortGroup, direction, priority, match string, options map[string]string) { acl, err := ovnClient.GetACL(pg.Name, direction, priority, match, false) require.NoError(t, err) - expect := newACL(pg.Name, direction, priority, match, ovnnb.ACLActionAllowRelated) + expect := newACL(pg.Name, direction, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = acl.UUID if len(options) != 0 { expect.Options = options @@ -424,7 +425,7 @@ func (suite *OvnClientTestSuite) testCreateSgDenyAllACL() { match := fmt.Sprintf("outport == @%s && ip", pgName) ingressACL, err := ovnClient.GetACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupDropPriority, match, false) require.NoError(t, err) - expect := newACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupDropPriority, match, ovnnb.ACLActionDrop) + expect := newACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupDropPriority, match, ovnnb.ACLActionDrop, util.NetpolACLTier) expect.UUID = ingressACL.UUID require.Equal(t, expect, ingressACL) require.Contains(t, pg.ACLs, ingressACL.UUID) @@ -433,7 +434,7 @@ func (suite *OvnClientTestSuite) testCreateSgDenyAllACL() { match = fmt.Sprintf("inport == @%s && ip", pgName) egressACL, err := ovnClient.GetACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupDropPriority, match, false) require.NoError(t, err) - expect = newACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupDropPriority, match, ovnnb.ACLActionDrop) + expect = newACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupDropPriority, match, ovnnb.ACLActionDrop, util.NetpolACLTier) expect.UUID = egressACL.UUID require.Equal(t, expect, egressACL) require.Contains(t, pg.ACLs, egressACL.UUID) @@ -449,7 +450,7 @@ func (suite *OvnClientTestSuite) testCreateSgBaseACL() { arpACL, err := ovnClient.GetACL(pg.Name, direction, util.SecurityGroupBasePriority, match, false) require.NoError(t, err) - expect := newACL(pg.Name, direction, util.SecurityGroupBasePriority, match, ovnnb.ACLActionAllowRelated, func(acl *ovnnb.ACL) { + expect := newACL(pg.Name, direction, util.SecurityGroupBasePriority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier, func(acl *ovnnb.ACL) { acl.UUID = arpACL.UUID }) @@ -589,7 +590,7 @@ func (suite *OvnClientTestSuite) testUpdateSgACL() { match := fmt.Sprintf("outport == @%s && ip4 && ip4.src == $%s", pgName, v4AsName) v4Acl, err := ovnClient.GetACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupAllowPriority, match, false) require.NoError(t, err) - expect := newACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupAllowPriority, match, ovnnb.ACLActionAllowRelated) + expect := newACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupAllowPriority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = v4Acl.UUID require.Equal(t, expect, v4Acl) require.Contains(t, pg.ACLs, v4Acl.UUID) @@ -598,7 +599,7 @@ func (suite *OvnClientTestSuite) testUpdateSgACL() { match = fmt.Sprintf("outport == @%s && ip6 && ip6.src == $%s", pgName, v6AsName) v6Acl, err := ovnClient.GetACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupAllowPriority, match, false) require.NoError(t, err) - expect = newACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupAllowPriority, match, ovnnb.ACLActionAllowRelated) + expect = newACL(pgName, ovnnb.ACLDirectionToLport, util.SecurityGroupAllowPriority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = v6Acl.UUID require.Equal(t, expect, v6Acl) require.Contains(t, pg.ACLs, v6Acl.UUID) @@ -607,7 +608,7 @@ func (suite *OvnClientTestSuite) testUpdateSgACL() { match = fmt.Sprintf("outport == @%s && ip4 && ip4.src == 0.0.0.0/0 && icmp4", pgName) rulACL, err := ovnClient.GetACL(pgName, ovnnb.ACLDirectionToLport, "2288", match, false) require.NoError(t, err) - expect = newACL(pgName, ovnnb.ACLDirectionToLport, "2288", match, ovnnb.ACLActionAllowRelated) + expect = newACL(pgName, ovnnb.ACLDirectionToLport, "2288", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = rulACL.UUID require.Equal(t, expect, rulACL) require.Contains(t, pg.ACLs, rulACL.UUID) @@ -624,7 +625,7 @@ func (suite *OvnClientTestSuite) testUpdateSgACL() { match := fmt.Sprintf("inport == @%s && ip4 && ip4.dst == $%s", pgName, v4AsName) v4Acl, err := ovnClient.GetACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupAllowPriority, match, false) require.NoError(t, err) - expect := newACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupAllowPriority, match, ovnnb.ACLActionAllowRelated) + expect := newACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupAllowPriority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = v4Acl.UUID require.Equal(t, expect, v4Acl) require.Contains(t, pg.ACLs, v4Acl.UUID) @@ -633,7 +634,7 @@ func (suite *OvnClientTestSuite) testUpdateSgACL() { match = fmt.Sprintf("inport == @%s && ip6 && ip6.dst == $%s", pgName, v6AsName) v6Acl, err := ovnClient.GetACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupAllowPriority, match, false) require.NoError(t, err) - expect = newACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupAllowPriority, match, ovnnb.ACLActionAllowRelated) + expect = newACL(pgName, ovnnb.ACLDirectionFromLport, util.SecurityGroupAllowPriority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = v6Acl.UUID require.Equal(t, expect, v6Acl) require.Contains(t, pg.ACLs, v6Acl.UUID) @@ -642,7 +643,7 @@ func (suite *OvnClientTestSuite) testUpdateSgACL() { match = fmt.Sprintf("inport == @%s && ip4 && ip4.dst == 0.0.0.0/0", pgName) rulACL, err := ovnClient.GetACL(pgName, ovnnb.ACLDirectionFromLport, "2290", match, false) require.NoError(t, err) - expect = newACL(pgName, ovnnb.ACLDirectionFromLport, "2290", match, ovnnb.ACLActionAllowRelated) + expect = newACL(pgName, ovnnb.ACLDirectionFromLport, "2290", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = rulACL.UUID require.Equal(t, expect, rulACL) require.Contains(t, pg.ACLs, rulACL.UUID) @@ -690,14 +691,14 @@ func (suite *OvnClientTestSuite) testUpdateLogicalSwitchACL() { } ingressACL, err := ovnClient.GetACL(lsName, ovnnb.ACLDirectionToLport, util.AllowEWTrafficPriority, match, false) require.NoError(t, err) - ingressExpect := newACL(lsName, ovnnb.ACLDirectionToLport, util.AllowEWTrafficPriority, match, ovnnb.ACLActionAllow) + ingressExpect := newACL(lsName, ovnnb.ACLDirectionToLport, util.AllowEWTrafficPriority, match, ovnnb.ACLActionAllow, util.NetpolACLTier) ingressExpect.UUID = ingressACL.UUID ingressExpect.ExternalIDs["subnet"] = lsName require.Equal(t, ingressExpect, ingressACL) require.Contains(t, ls.ACLs, ingressACL.UUID) egressACL, err := ovnClient.GetACL(lsName, ovnnb.ACLDirectionFromLport, util.AllowEWTrafficPriority, match, false) require.NoError(t, err) - egressExpect := newACL(lsName, ovnnb.ACLDirectionFromLport, util.AllowEWTrafficPriority, match, ovnnb.ACLActionAllow) + egressExpect := newACL(lsName, ovnnb.ACLDirectionFromLport, util.AllowEWTrafficPriority, match, ovnnb.ACLActionAllow, util.NetpolACLTier) egressExpect.UUID = egressACL.UUID egressExpect.ExternalIDs["subnet"] = lsName require.Equal(t, egressExpect, egressACL) @@ -707,7 +708,7 @@ func (suite *OvnClientTestSuite) testUpdateLogicalSwitchACL() { for _, subnetACL := range subnetAcls { acl, err := ovnClient.GetACL(lsName, subnetACL.Direction, strconv.Itoa(subnetACL.Priority), subnetACL.Match, false) require.NoError(t, err) - expect := newACL(lsName, subnetACL.Direction, strconv.Itoa(subnetACL.Priority), subnetACL.Match, subnetACL.Action) + expect := newACL(lsName, subnetACL.Direction, strconv.Itoa(subnetACL.Priority), subnetACL.Match, subnetACL.Action, util.NetpolACLTier) expect.UUID = acl.UUID expect.ExternalIDs["subnet"] = lsName require.Equal(t, expect, acl) @@ -727,7 +728,7 @@ func (suite *OvnClientTestSuite) testSetACLLog() { t.Run("set ingress acl log to false", func(t *testing.T) { match := fmt.Sprintf("outport == @%s && ip", pgName) - acl := newACL(pgName, ovnnb.ACLDirectionToLport, util.IngressDefaultDrop, match, ovnnb.ACLActionDrop, func(acl *ovnnb.ACL) { + acl := newACL(pgName, ovnnb.ACLDirectionToLport, util.IngressDefaultDrop, match, ovnnb.ACLActionDrop, util.NetpolACLTier, func(acl *ovnnb.ACL) { acl.Name = &pgName acl.Log = true acl.Severity = &ovnnb.ACLSeverityWarning @@ -746,7 +747,7 @@ func (suite *OvnClientTestSuite) testSetACLLog() { t.Run("set egress acl log to false", func(t *testing.T) { match := fmt.Sprintf("inport == @%s && ip", pgName) - acl := newACL(pgName, ovnnb.ACLDirectionFromLport, util.IngressDefaultDrop, match, ovnnb.ACLActionDrop, func(acl *ovnnb.ACL) { + acl := newACL(pgName, ovnnb.ACLDirectionFromLport, util.IngressDefaultDrop, match, ovnnb.ACLActionDrop, util.NetpolACLTier, func(acl *ovnnb.ACL) { acl.Name = &pgName acl.Log = false acl.Severity = &ovnnb.ACLSeverityWarning @@ -948,7 +949,7 @@ func (suite *OvnClientTestSuite) testNewSgRuleACL() { require.NoError(t, err) match := fmt.Sprintf("outport == @%s && ip4 && ip4.src == $%s && icmp4", pgName, GetSgV4AssociatedName(sgRule.RemoteSecurityGroup)) - expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = acl.UUID require.Equal(t, expect, acl) }) @@ -970,7 +971,7 @@ func (suite *OvnClientTestSuite) testNewSgRuleACL() { require.NoError(t, err) match := fmt.Sprintf("outport == @%s && ip4 && ip4.src == %s && icmp4", pgName, sgRule.RemoteAddress) - expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = acl.UUID require.Equal(t, expect, acl) }) @@ -992,7 +993,7 @@ func (suite *OvnClientTestSuite) testNewSgRuleACL() { require.NoError(t, err) match := fmt.Sprintf("outport == @%s && ip6 && ip6.src == %s && icmp6", pgName, sgRule.RemoteAddress) - expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = acl.UUID require.Equal(t, expect, acl) }) @@ -1014,7 +1015,7 @@ func (suite *OvnClientTestSuite) testNewSgRuleACL() { require.NoError(t, err) match := fmt.Sprintf("inport == @%s && ip4 && ip4.dst == %s && icmp4", pgName, sgRule.RemoteAddress) - expect := newACL(pgName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated) + expect := newACL(pgName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = acl.UUID require.Equal(t, expect, acl) }) @@ -1036,7 +1037,7 @@ func (suite *OvnClientTestSuite) testNewSgRuleACL() { require.NoError(t, err) match := fmt.Sprintf("outport == @%s && ip4 && ip4.src == %s && icmp4", pgName, sgRule.RemoteAddress) - expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionDrop) + expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionDrop, util.NetpolACLTier) expect.UUID = acl.UUID require.Equal(t, expect, acl) }) @@ -1060,7 +1061,7 @@ func (suite *OvnClientTestSuite) testNewSgRuleACL() { require.NoError(t, err) match := fmt.Sprintf("outport == @%s && ip4 && ip4.src == %s && %d <= tcp.dst <= %d", pgName, sgRule.RemoteAddress, sgRule.PortRangeMin, sgRule.PortRangeMax) - expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + expect := newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) expect.UUID = acl.UUID require.Equal(t, expect, acl) }) @@ -1083,7 +1084,7 @@ func (suite *OvnClientTestSuite) testCreateAcls() { for i := 0; i < 3; i++ { match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1111,7 +1112,7 @@ func (suite *OvnClientTestSuite) testCreateAcls() { for i := 0; i < 3; i++ { match := fmt.Sprintf("%s && udp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1164,7 +1165,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // to-lport for i := 0; i < 2; i++ { match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1172,7 +1173,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // from-lport for i := 0; i < 3; i++ { match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1200,7 +1201,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // to-lport for i := 0; i < 2; i++ { match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1208,7 +1209,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // from-lport for i := 0; i < 3; i++ { match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1245,7 +1246,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // to-lport for i := 0; i < 2; i++ { match := fmt.Sprintf("%s && udp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1253,7 +1254,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // from-lport for i := 0; i < 3; i++ { match := fmt.Sprintf("%s && udp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1281,7 +1282,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // to-lport for i := 0; i < 2; i++ { match := fmt.Sprintf("%s && udp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1289,7 +1290,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // from-lport for i := 0; i < 3; i++ { match := fmt.Sprintf("%s && udp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionFromLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) acls = append(acls, acl) } @@ -1326,7 +1327,7 @@ func (suite *OvnClientTestSuite) testDeleteAcls() { // to-lport match := fmt.Sprintf("%s && udp.dst == %d", matchPrefix, basePort) - acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, func(acl *ovnnb.ACL) { + acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier, func(acl *ovnnb.ACL) { if acl.ExternalIDs == nil { acl.ExternalIDs = make(map[string]string) } @@ -1376,7 +1377,7 @@ func (suite *OvnClientTestSuite) testDeleteACL() { basePort := 5601 match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) err = ovnClient.CreateAcls(pgName, portGroupKey, acl) @@ -1399,7 +1400,7 @@ func (suite *OvnClientTestSuite) testDeleteACL() { basePort := 5601 match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort) - acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(lsName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) err = ovnClient.CreateAcls(lsName, logicalSwitchKey, acl) @@ -1430,7 +1431,7 @@ func (suite *OvnClientTestSuite) testGetACL() { err := ovnClient.CreatePortGroup(pgName, nil) require.NoError(t, err) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) err = ovnClient.CreateAcls(pgName, portGroupKey, acl) @@ -1489,7 +1490,7 @@ func (suite *OvnClientTestSuite) testListAcls() { // create two to-lport acl for i := 0; i < 2; i++ { match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, "9999", match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, "9999", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) err = ovnClient.CreateAcls(pgName, portGroupKey, acl) @@ -1499,7 +1500,7 @@ func (suite *OvnClientTestSuite) testListAcls() { // create two from-lport acl for i := 0; i < 3; i++ { match := fmt.Sprintf("%s && tcp.dst == %d", matchPrefix, basePort+i) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionFromLport, "9999", match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionFromLport, "9999", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) err = ovnClient.CreateAcls(pgName, portGroupKey, acl) @@ -1543,9 +1544,10 @@ func (suite *OvnClientTestSuite) testNewACL() { }, Log: true, Severity: &ovnnb.ACLSeverityWarning, + Tier: util.NetpolACLTier, } - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, options) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier, options) require.NoError(t, err) expect.UUID = acl.UUID require.Equal(t, expect, acl) @@ -1683,26 +1685,26 @@ func (suite *OvnClientTestSuite) testACLFilter() { match := "outport == @ovn.sg.test_list_acl_pg && ip" // create two to-lport acl for i := 0; i < 2; i++ { - acl := newACL(pgName, ovnnb.ACLDirectionToLport, "9999", match, ovnnb.ACLActionAllowRelated) + acl := newACL(pgName, ovnnb.ACLDirectionToLport, "9999", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) acls = append(acls, acl) } // create two to-lport acl without acl parent key for i := 0; i < 2; i++ { - acl := newACL(pgName, ovnnb.ACLDirectionToLport, "9999", match, ovnnb.ACLActionAllowRelated) + acl := newACL(pgName, ovnnb.ACLDirectionToLport, "9999", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) acl.ExternalIDs = nil acls = append(acls, acl) } // create two from-lport acl for i := 0; i < 3; i++ { - acl := newACL(pgName, ovnnb.ACLDirectionFromLport, "9999", match, ovnnb.ACLActionAllowRelated) + acl := newACL(pgName, ovnnb.ACLDirectionFromLport, "9999", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) acls = append(acls, acl) } // create four from-lport acl with other acl parent key for i := 0; i < 4; i++ { - acl := newACL(pgName, ovnnb.ACLDirectionFromLport, "9999", match, ovnnb.ACLActionAllowRelated) + acl := newACL(pgName, ovnnb.ACLDirectionFromLport, "9999", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) acl.ExternalIDs[aclParentKey] = pgName + "-test" acls = append(acls, acl) } @@ -1772,7 +1774,7 @@ func (suite *OvnClientTestSuite) testACLFilter() { t.Parallel() match := "outport == @ovn.sg.test_filter_acl_pg && ip" - acl := newACL(pgName, ovnnb.ACLDirectionToLport, "9999", match, ovnnb.ACLActionAllowRelated) + acl := newACL(pgName, ovnnb.ACLDirectionToLport, "9999", match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) filterFunc := aclFilter("", map[string]string{ aclParentKey: pgName, diff --git a/pkg/ovs/ovn-nb-address_set.go b/pkg/ovs/ovn-nb-address_set.go index 941fab810a52..798bb74194f4 100644 --- a/pkg/ovs/ovn-nb-address_set.go +++ b/pkg/ovs/ovn-nb-address_set.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "net" "strings" @@ -39,11 +40,11 @@ func (c *OVNNbClient) CreateAddressSet(asName string, externalIDs map[string]str ops, err := c.ovsDbClient.Create(as) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating address set %s: %v", asName, err) + return fmt.Errorf("generate operations for creating address set %s: %w", asName, err) } if err = c.Transact("as-add", ops); err != nil { - return fmt.Errorf("create address set %s: %v", asName, err) + return fmt.Errorf("create address set %s: %w", asName, err) } return nil @@ -55,7 +56,7 @@ func (c *OVNNbClient) AddressSetUpdateAddress(asName string, addresses ...string as, err := c.GetAddressSet(asName, false) if err != nil { klog.Error(err) - return fmt.Errorf("get address set %s: %v", asName, err) + return fmt.Errorf("get address set %s: %w", asName, err) } // format CIDR to keep addresses the same in both nb and sb @@ -77,7 +78,7 @@ func (c *OVNNbClient) AddressSetUpdateAddress(asName string, addresses ...string as.Addresses = addresses if err := c.UpdateAddressSet(as, &as.Addresses); err != nil { - return fmt.Errorf("set address set %s addresses %v: %v", asName, addresses, err) + return fmt.Errorf("set address set %s addresses %v: %w", asName, addresses, err) } return nil @@ -86,18 +87,18 @@ func (c *OVNNbClient) AddressSetUpdateAddress(asName string, addresses ...string // UpdateAddressSet update address set func (c *OVNNbClient) UpdateAddressSet(as *ovnnb.AddressSet, fields ...interface{}) error { if as == nil { - return fmt.Errorf("address_set is nil") + return errors.New("address_set is nil") } op, err := c.Where(as).Update(as, fields...) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for updating address set %s: %v", as.Name, err) + return fmt.Errorf("generate operations for updating address set %s: %w", as.Name, err) } if err = c.Transact("as-update", op); err != nil { klog.Error(err) - return fmt.Errorf("update address set %s: %v", as.Name, err) + return fmt.Errorf("update address set %s: %w", as.Name, err) } return nil @@ -107,7 +108,7 @@ func (c *OVNNbClient) DeleteAddressSet(asName string) error { as, err := c.GetAddressSet(asName, true) if err != nil { klog.Error(err) - return fmt.Errorf("get address set %s: %v", asName, err) + return fmt.Errorf("get address set %s: %w", asName, err) } // not found, skip @@ -122,7 +123,7 @@ func (c *OVNNbClient) DeleteAddressSet(asName string) error { } if err := c.Transact("as-del", op); err != nil { - return fmt.Errorf("delete address set %s: %v", asName, err) + return fmt.Errorf("delete address set %s: %w", asName, err) } return nil @@ -138,11 +139,11 @@ func (c *OVNNbClient) DeleteAddressSets(externalIDs map[string]string) error { op, err := c.WhereCache(addressSetFilter(externalIDs)).Delete() if err != nil { klog.Error(err) - return fmt.Errorf("generate operation for deleting address sets with external IDs %v: %v", externalIDs, err) + return fmt.Errorf("generate operation for deleting address sets with external IDs %v: %w", externalIDs, err) } if err := c.Transact("ass-del", op); err != nil { - return fmt.Errorf("delete address sets with external IDs %v: %v", externalIDs, err) + return fmt.Errorf("delete address sets with external IDs %v: %w", externalIDs, err) } return nil @@ -155,11 +156,11 @@ func (c *OVNNbClient) GetAddressSet(asName string, ignoreNotFound bool) (*ovnnb. as := &ovnnb.AddressSet{Name: asName} if err := c.ovsDbClient.Get(ctx, as); err != nil { - if ignoreNotFound && err == client.ErrNotFound { + if ignoreNotFound && errors.Is(err, client.ErrNotFound) { return nil, nil } klog.Error(err) - return nil, fmt.Errorf("get address set %s: %v", asName, err) + return nil, fmt.Errorf("get address set %s: %w", asName, err) } return as, nil @@ -178,7 +179,7 @@ func (c *OVNNbClient) ListAddressSets(externalIDs map[string]string) ([]ovnnb.Ad asList := make([]ovnnb.AddressSet, 0) if err := c.WhereCache(addressSetFilter(externalIDs)).List(ctx, &asList); err != nil { - return nil, fmt.Errorf("list address set: %v", err) + return nil, fmt.Errorf("list address set: %w", err) } return asList, nil diff --git a/pkg/ovs/ovn-nb-bfd.go b/pkg/ovs/ovn-nb-bfd.go index 3adfc77fa042..2ea3fa5d9106 100644 --- a/pkg/ovs/ovn-nb-bfd.go +++ b/pkg/ovs/ovn-nb-bfd.go @@ -25,7 +25,7 @@ func (c *OVNNbClient) ListBFDs(lrpName, dstIP string) ([]ovnnb.BFD, error) { } return dstIP == "" || bfd.DstIP == dstIP }).List(ctx, &bfdList); err != nil { - err := fmt.Errorf("failed to list BFD with logical_port=%s and dst_ip=%s: %v", lrpName, dstIP, err) + err := fmt.Errorf("failed to list BFD with logical_port=%s and dst_ip=%s: %w", lrpName, dstIP, err) klog.Error(err) return nil, err } @@ -44,7 +44,7 @@ func (c *OVNNbClient) ListDownBFDs(dstIP string) ([]ovnnb.BFD, error) { } return false }).List(ctx, &bfdList); err != nil { - err := fmt.Errorf("failed to list down BFDs: %v", err) + err := fmt.Errorf("failed to list down BFDs: %w", err) klog.Error(err) return nil, err } @@ -60,7 +60,7 @@ func (c *OVNNbClient) ListUpBFDs(dstIP string) ([]ovnnb.BFD, error) { if err := c.ovsDbClient.WhereCache(func(bfd *ovnnb.BFD) bool { return bfd.DstIP == dstIP && *bfd.Status == ovnnb.BFDStatusUp }).List(ctx, &bfdList); err != nil { - err := fmt.Errorf("failed to list up BFDs: %v", err) + err := fmt.Errorf("failed to list up BFDs: %w", err) klog.Error(err) return nil, err } @@ -87,18 +87,18 @@ func (c *OVNNbClient) CreateBFD(lrpName, dstIP string, minRx, minTx, detectMult } ops, err := c.Create(bfd) if err != nil { - err := fmt.Errorf("failed to generate operations for BFD creation with logical_port=%s and dst_ip=%s: %v", lrpName, dstIP, err) + err := fmt.Errorf("failed to generate operations for BFD creation with logical_port=%s and dst_ip=%s: %w", lrpName, dstIP, err) klog.Error(err) return nil, err } if err = c.Transact("bfd-add", ops); err != nil { - err := fmt.Errorf("failed to create BFD with logical_port=%s and dst_ip=%s: %v", lrpName, dstIP, err) + err := fmt.Errorf("failed to create BFD with logical_port=%s and dst_ip=%s: %w", lrpName, dstIP, err) klog.Error(err) return nil, err } if bfdList, err = c.ListBFDs(lrpName, dstIP); err != nil { - err := fmt.Errorf("failed to list BFDs: %v", err) + err := fmt.Errorf("failed to list BFDs: %w", err) klog.Error(err) return nil, err } @@ -112,12 +112,12 @@ func (c *OVNNbClient) CreateBFD(lrpName, dstIP string, minRx, minTx, detectMult func (c *OVNNbClient) UpdateBFD(bfd *ovnnb.BFD, fields ...interface{}) error { op, err := c.ovsDbClient.Where(bfd).Update(bfd, fields...) if err != nil { - err := fmt.Errorf("failed to generate bfd update operations for lrp %s with fields %v: %v", bfd.LogicalPort, fields, err) + err := fmt.Errorf("failed to generate bfd update operations for lrp %s with fields %v: %w", bfd.LogicalPort, fields, err) klog.Error(err) return err } if err = c.Transact("bfd-update", op); err != nil { - err := fmt.Errorf("failed to update bfd %s for lrp %s: %v", bfd.UUID, bfd.LogicalPort, err) + err := fmt.Errorf("failed to update bfd %s for lrp %s: %w", bfd.UUID, bfd.LogicalPort, err) klog.Error(err) return err } @@ -136,13 +136,13 @@ func (c *OVNNbClient) DeleteBFD(lrpName, dstIP string) error { for _, bfd := range bfdList { ops, err := c.Where(&bfd).Delete() if err != nil { - err := fmt.Errorf("failed to generate operations for BFD deletion with UUID %s: %v", bfd.UUID, err) + err := fmt.Errorf("failed to generate operations for BFD deletion with UUID %s: %w", bfd.UUID, err) klog.Error(err) return err } klog.Infof("delete lrp %s BFD dst ip %s", lrpName, bfd.DstIP) if err = c.Transact("bfd-del", ops); err != nil { - err := fmt.Errorf("failed to delete BFD with with UUID %s: %v", bfd.UUID, err) + err := fmt.Errorf("failed to delete BFD with with UUID %s: %w", bfd.UUID, err) klog.Error(err) return err } diff --git a/pkg/ovs/ovn-nb-dhcp_options.go b/pkg/ovs/ovn-nb-dhcp_options.go index 0cf963c70032..46af23007241 100644 --- a/pkg/ovs/ovn-nb-dhcp_options.go +++ b/pkg/ovs/ovn-nb-dhcp_options.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "strings" @@ -28,12 +29,12 @@ func (c *OVNNbClient) CreateDHCPOptions(lsName, cidr, options string) error { op, err := c.ovsDbClient.Create(dhcpOpt) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating dhcp options 'cidr %s options %s': %v", cidr, options, err) + return fmt.Errorf("generate operations for creating dhcp options 'cidr %s options %s': %w", cidr, options, err) } if err = c.Transact("dhcp-create", op); err != nil { klog.Error(err) - return fmt.Errorf("create dhcp options with cidr %q options %q: %v", cidr, options, err) + return fmt.Errorf("create dhcp options with cidr %q options %q: %w", cidr, options, err) } return nil @@ -51,7 +52,7 @@ func (c *OVNNbClient) UpdateDHCPOptions(subnet *kubeovnv1.Subnet, mtu int) (*DHC /* delete dhcp options */ if !enableDHCP { if err := c.DeleteDHCPOptions(lsName, subnet.Spec.Protocol); err != nil { - return nil, fmt.Errorf("delete dhcp options for logical switch %s: %v", lsName, err) + return nil, fmt.Errorf("delete dhcp options for logical switch %s: %w", lsName, err) } return &DHCPOptionsUUIDs{}, nil } @@ -77,7 +78,7 @@ func (c *OVNNbClient) UpdateDHCPOptions(subnet *kubeovnv1.Subnet, mtu int) (*DHC dhcpV4OptUUID, err := c.updateDHCPv4Options(lsName, v4CIDR, v4Gateway, subnet.Spec.DHCPv4Options, mtu) if err != nil { klog.Error(err) - return nil, fmt.Errorf("update IPv4 dhcp options for logical switch %s: %v", lsName, err) + return nil, fmt.Errorf("update IPv4 dhcp options for logical switch %s: %w", lsName, err) } dhcpOptionsUUIDs.DHCPv4OptionsUUID = dhcpV4OptUUID } @@ -86,7 +87,7 @@ func (c *OVNNbClient) UpdateDHCPOptions(subnet *kubeovnv1.Subnet, mtu int) (*DHC dhcpV6OptUUID, err := c.updateDHCPv6Options(lsName, v6CIDR, subnet.Spec.DHCPv6Options) if err != nil { klog.Error(err) - return nil, fmt.Errorf("update IPv6 dhcp options for logical switch %s: %v", lsName, err) + return nil, fmt.Errorf("update IPv6 dhcp options for logical switch %s: %w", lsName, err) } dhcpOptionsUUIDs.DHCPv6OptionsUUID = dhcpV6OptUUID } @@ -135,7 +136,7 @@ func (c *OVNNbClient) updateDHCPv4Options(lsName, cidr, gateway, options string, /* create */ if err := c.CreateDHCPOptions(lsName, cidr, options); err != nil { - return "", fmt.Errorf("create dhcp options: %v", err) + return "", fmt.Errorf("create dhcp options: %w", err) } dhcpOpt, err = c.GetDHCPOptions(lsName, protocol, false) @@ -188,7 +189,7 @@ func (c *OVNNbClient) updateDHCPv6Options(lsName, cidr, options string) (uuid st /* create */ if err := c.CreateDHCPOptions(lsName, cidr, options); err != nil { - return "", fmt.Errorf("create dhcp options: %v", err) + return "", fmt.Errorf("create dhcp options: %w", err) } dhcpOpt, err = c.GetDHCPOptions(lsName, protocol, false) @@ -203,17 +204,17 @@ func (c *OVNNbClient) updateDHCPv6Options(lsName, cidr, options string) (uuid st // updateDHCPOptions update dhcp options func (c *OVNNbClient) updateDHCPOptions(dhcpOpt *ovnnb.DHCPOptions, fields ...interface{}) error { if dhcpOpt == nil { - return fmt.Errorf("dhcp_options is nil") + return errors.New("dhcp_options is nil") } op, err := c.ovsDbClient.Where(dhcpOpt).Update(dhcpOpt, fields...) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for updating dhcp options %s: %v", dhcpOpt.UUID, err) + return fmt.Errorf("generate operations for updating dhcp options %s: %w", dhcpOpt.UUID, err) } if err = c.Transact("dhcp-options-update", op); err != nil { - return fmt.Errorf("update dhcp options %s: %v", dhcpOpt.UUID, err) + return fmt.Errorf("update dhcp options %s: %w", dhcpOpt.UUID, err) } return nil @@ -236,7 +237,7 @@ func (c *OVNNbClient) DeleteDHCPOptionsByUUIDs(uuidList ...string) error { } if err := c.Transact("dhcp-options-del", ops); err != nil { - return fmt.Errorf("delete dhcp options %v: %v", uuidList, err) + return fmt.Errorf("delete dhcp options %v: %w", uuidList, err) } return nil @@ -255,12 +256,12 @@ func (c *OVNNbClient) DeleteDHCPOptions(lsName, protocol string) error { op, err := c.WhereCache(dhcpOptionsFilter(true, externalIDs)).Delete() if err != nil { klog.Error(err) - return fmt.Errorf("generate operation for deleting dhcp options: %v", err) + return fmt.Errorf("generate operation for deleting dhcp options: %w", err) } if err = c.Transact("dhcp-options-del", op); err != nil { klog.Error(err) - return fmt.Errorf("delete logical switch %s dhcp options: %v", lsName, err) + return fmt.Errorf("delete logical switch %s dhcp options: %w", lsName, err) } return nil @@ -270,11 +271,11 @@ func (c *OVNNbClient) DeleteDHCPOptions(lsName, protocol string) error { // a dhcp options is uniquely identified by switch(lsName) and protocol func (c *OVNNbClient) GetDHCPOptions(lsName, protocol string, ignoreNotFound bool) (*ovnnb.DHCPOptions, error) { if len(lsName) == 0 { - return nil, fmt.Errorf("the logical router name is required") + return nil, errors.New("the logical router name is required") } if protocol != kubeovnv1.ProtocolIPv4 && protocol != kubeovnv1.ProtocolIPv6 { - return nil, fmt.Errorf("protocol must be IPv4 or IPv6") + return nil, errors.New("protocol must be IPv4 or IPv6") } dhcpOptList, err := c.ListDHCPOptions(true, map[string]string{ @@ -283,7 +284,7 @@ func (c *OVNNbClient) GetDHCPOptions(lsName, protocol string, ignoreNotFound boo }) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical switch %s %s dhcp options: %v", lsName, protocol, err) + return nil, fmt.Errorf("get logical switch %s %s dhcp options: %w", lsName, protocol, err) } // not found @@ -292,7 +293,7 @@ func (c *OVNNbClient) GetDHCPOptions(lsName, protocol string, ignoreNotFound boo return nil, nil } - return nil, fmt.Errorf("not found logical switch %s %s dhcp options: %v", lsName, protocol, err) + return nil, fmt.Errorf("not found logical switch %s %s dhcp options: %w", lsName, protocol, err) } if len(dhcpOptList) > 1 { @@ -310,7 +311,7 @@ func (c *OVNNbClient) ListDHCPOptions(needVendorFilter bool, externalIDs map[str dhcpOptList := make([]ovnnb.DHCPOptions, 0) if err := c.WhereCache(dhcpOptionsFilter(needVendorFilter, externalIDs)).List(ctx, &dhcpOptList); err != nil { - return nil, fmt.Errorf("list dhcp options with external IDs %v: %v", externalIDs, err) + return nil, fmt.Errorf("list dhcp options with external IDs %v: %w", externalIDs, err) } return dhcpOptList, nil diff --git a/pkg/ovs/ovn-nb-gateway_chassis.go b/pkg/ovs/ovn-nb-gateway_chassis.go index 20c9bc1db3dc..3e41c2d453a1 100644 --- a/pkg/ovs/ovn-nb-gateway_chassis.go +++ b/pkg/ovs/ovn-nb-gateway_chassis.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "github.com/ovn-org/libovsdb/client" @@ -17,13 +18,13 @@ import ( func (c *OVNNbClient) CreateGatewayChassises(lrpName string, chassises ...string) error { op, err := c.CreateGatewayChassisesOp(lrpName, chassises) if err != nil { - err := fmt.Errorf("generate operations for creating gateway chassis %v", err) + err := fmt.Errorf("generate operations for creating gateway chassis %w", err) klog.Error(err) return err } if err = c.Transact("gateway-chassises-add", op); err != nil { - err := fmt.Errorf("create gateway chassis %v for logical router port %s: %v", chassises, lrpName, err) + err := fmt.Errorf("create gateway chassis %v for logical router port %s: %w", chassises, lrpName, err) klog.Error(err) return err } @@ -35,12 +36,12 @@ func (c *OVNNbClient) CreateGatewayChassises(lrpName string, chassises ...string func (c *OVNNbClient) UpdateGatewayChassis(gwChassis *ovnnb.GatewayChassis, fields ...interface{}) error { op, err := c.ovsDbClient.Where(gwChassis).Update(gwChassis, fields...) if err != nil { - err := fmt.Errorf("failed to generate operations for gateway chassis %s with fields %v: %v", gwChassis.ChassisName, fields, err) + err := fmt.Errorf("failed to generate operations for gateway chassis %s with fields %v: %w", gwChassis.ChassisName, fields, err) klog.Error(err) return err } if err = c.Transact("gateway-chassis-update", op); err != nil { - err := fmt.Errorf("failed to update gateway chassis %s: %v", gwChassis.ChassisName, err) + err := fmt.Errorf("failed to update gateway chassis %s: %w", gwChassis.ChassisName, err) klog.Error(err) return err } @@ -83,7 +84,7 @@ func (c *OVNNbClient) DeleteGatewayChassises(lrpName string, chassises []string) } if err := c.Transact("gateway-chassises-delete", ops); err != nil { - return fmt.Errorf("delete gateway chassises %v from logical router port %s: %v", chassises, lrpName, err) + return fmt.Errorf("delete gateway chassises %v from logical router port %s: %w", chassises, lrpName, err) } return nil @@ -101,10 +102,10 @@ func (c *OVNNbClient) ListGatewayChassisByLogicalRouterPort(lrpName string, igno } return false }).List(ctx, &gwChassisList); err != nil { - if ignoreNotFound && err == client.ErrNotFound { + if ignoreNotFound && errors.Is(err, client.ErrNotFound) { return nil, nil } - err = fmt.Errorf("failed to list gw chassis for lrp %s: %v", lrpName, err) + err = fmt.Errorf("failed to list gw chassis for lrp %s: %w", lrpName, err) klog.Error(err) return nil, err } @@ -119,11 +120,11 @@ func (c *OVNNbClient) GetGatewayChassis(name string, ignoreNotFound bool) (*ovnn gwChassis := &ovnnb.GatewayChassis{Name: name} if err := c.Get(ctx, gwChassis); err != nil { - if ignoreNotFound && err == client.ErrNotFound { + if ignoreNotFound && errors.Is(err, client.ErrNotFound) { return nil, nil } - return nil, fmt.Errorf("get gateway chassis %s: %v", name, err) + return nil, fmt.Errorf("get gateway chassis %s: %w", name, err) } return gwChassis, nil @@ -196,7 +197,7 @@ func (c *OVNNbClient) CreateGatewayChassisesOp(lrpName string, chassises []strin gwChassisCreateop, err := c.Create(models...) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for creating gateway chassis %v", err) + return nil, fmt.Errorf("generate operations for creating gateway chassis %w", err) } /* add gateway chassis to logical router port */ diff --git a/pkg/ovs/ovn-nb-load_balancer.go b/pkg/ovs/ovn-nb-load_balancer.go index bb8b67870e2a..b17eeff3ed41 100644 --- a/pkg/ovs/ovn-nb-load_balancer.go +++ b/pkg/ovs/ovn-nb-load_balancer.go @@ -49,11 +49,11 @@ func (c *OVNNbClient) CreateLoadBalancer(lbName, protocol, selectFields string) } if ops, err = c.ovsDbClient.Create(lb); err != nil { - return fmt.Errorf("generate operations for creating load balancer %s: %v", lbName, err) + return fmt.Errorf("generate operations for creating load balancer %s: %w", lbName, err) } if err = c.Transact("lb-add", ops); err != nil { - return fmt.Errorf("create load balancer %s: %v", lbName, err) + return fmt.Errorf("create load balancer %s: %w", lbName, err) } return nil } @@ -66,11 +66,11 @@ func (c *OVNNbClient) UpdateLoadBalancer(lb *ovnnb.LoadBalancer, fields ...inter ) if ops, err = c.ovsDbClient.Where(lb).Update(lb, fields...); err != nil { - return fmt.Errorf("generate operations for updating load balancer %s: %v", lb.Name, err) + return fmt.Errorf("generate operations for updating load balancer %s: %w", lb.Name, err) } if err = c.Transact("lb-update", ops); err != nil { - return fmt.Errorf("update load balancer %s: %v", lb.Name, err) + return fmt.Errorf("update load balancer %s: %w", lb.Name, err) } return nil } @@ -120,12 +120,12 @@ func (c *OVNNbClient) LoadBalancerAddVip(lbName, vip string, backends ...string) return mutations }, ); err != nil { - return fmt.Errorf("failed to generate operations when adding vip %s with backends %v to load balancers %s: %v", vip, backends, lbName, err) + return fmt.Errorf("failed to generate operations when adding vip %s with backends %v to load balancers %s: %w", vip, backends, lbName, err) } if ops != nil { if err = c.Transact("lb-add", ops); err != nil { - return fmt.Errorf("failed to add vip %s with backends %v to load balancers %s: %v", vip, backends, lbName, err) + return fmt.Errorf("failed to add vip %s with backends %v to load balancers %s: %w", vip, backends, lbName, err) } } return nil @@ -177,14 +177,14 @@ func (c *OVNNbClient) LoadBalancerDeleteVip(lbName, vipEndpoint string, ignoreHe }, ) if err != nil { - return fmt.Errorf("failed to generate operations when deleting vip %s from load balancers %s: %v", vipEndpoint, lbName, err) + return fmt.Errorf("failed to generate operations when deleting vip %s from load balancers %s: %w", vipEndpoint, lbName, err) } if len(ops) == 0 { return nil } if err = c.Transact("lb-add", ops); err != nil { - return fmt.Errorf("failed to delete vip %s from load balancers %s: %v", vipEndpoint, lbName, err) + return fmt.Errorf("failed to delete vip %s from load balancers %s: %w", vipEndpoint, lbName, err) } return nil } @@ -215,7 +215,7 @@ func (c *OVNNbClient) SetLoadBalancerAffinityTimeout(lbName string, timeout int) lb.Options = options if err = c.UpdateLoadBalancer(lb, &lb.Options); err != nil { - return fmt.Errorf("failed to set affinity timeout of lb %s to %d: %v", lbName, timeout, err) + return fmt.Errorf("failed to set affinity timeout of lb %s to %d: %w", lbName, timeout, err) } return nil } @@ -235,12 +235,12 @@ func (c *OVNNbClient) DeleteLoadBalancers(filter func(lb *ovnnb.LoadBalancer) bo return true }, ).Delete(); err != nil { - return fmt.Errorf("generate operations for delete load balancers: %v", err) + return fmt.Errorf("generate operations for delete load balancers: %w", err) } if err = c.Transact("lb-del", ops); err != nil { klog.Errorf("failed to del lbs: %v", err) - return fmt.Errorf("delete load balancers : %v", err) + return fmt.Errorf("delete load balancers : %w", err) } return nil } @@ -260,7 +260,7 @@ func (c *OVNNbClient) DeleteLoadBalancer(lbName string) error { if err = c.Transact("lb-del", ops); err != nil { klog.Errorf("failed to del lb: %v", err) - return fmt.Errorf("delete load balancer %s: %v", lbName, err) + return fmt.Errorf("delete load balancer %s: %w", lbName, err) } return nil } @@ -282,7 +282,7 @@ func (c *OVNNbClient) GetLoadBalancer(lbName string, ignoreNotFound bool) (*ovnn return lb.Name == lbName }, ).List(ctx, &lbList); err != nil { - return nil, fmt.Errorf("failed to list load balancer %q: %v", lbName, err) + return nil, fmt.Errorf("failed to list load balancer %q: %w", lbName, err) } switch { @@ -325,7 +325,7 @@ func (c *OVNNbClient) ListLoadBalancers(filter func(lb *ovnnb.LoadBalancer) bool return true }, ).List(ctx, &lbList); err != nil { - return nil, fmt.Errorf("failed to list load balancer: %v", err) + return nil, fmt.Errorf("failed to list load balancer: %w", err) } return lbList, nil } @@ -359,7 +359,7 @@ func (c *OVNNbClient) LoadBalancerOp(lbName string, mutationsFunc ...func(lb *ov if ops, err = c.ovsDbClient.Where(lb).Mutate(lb, mutations...); err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for mutating load balancer %s: %v", lb.Name, err) + return nil, fmt.Errorf("generate operations for mutating load balancer %s: %w", lb.Name, err) } return ops, nil } @@ -411,11 +411,11 @@ func (c *OVNNbClient) LoadBalancerAddIPPortMapping(lbName, vipEndpoint string, m } }, ); err != nil { - return fmt.Errorf("failed to generate operations when adding ip port mapping with vip %v to load balancers %s: %v", vipEndpoint, lbName, err) + return fmt.Errorf("failed to generate operations when adding ip port mapping with vip %v to load balancers %s: %w", vipEndpoint, lbName, err) } if err = c.Transact("lb-add", ops); err != nil { - return fmt.Errorf("failed to add ip port mapping with vip %v to load balancers %s: %v", vipEndpoint, lbName, err) + return fmt.Errorf("failed to add ip port mapping with vip %v to load balancers %s: %w", vipEndpoint, lbName, err) } return nil } @@ -445,7 +445,7 @@ func (c *OVNNbClient) LoadBalancerDeleteIPPortMapping(lbName, vipEndpoint string } if vip, _, err = net.SplitHostPort(vipEndpoint); err != nil { - err := fmt.Errorf("failed to split host port: %v", err) + err := fmt.Errorf("failed to split host port: %w", err) klog.Error(err) return err } @@ -470,13 +470,13 @@ func (c *OVNNbClient) LoadBalancerDeleteIPPortMapping(lbName, vipEndpoint string } }, ); err != nil { - return fmt.Errorf("failed to generate operations when deleting ip port mapping %s from load balancers %s: %v", vipEndpoint, lbName, err) + return fmt.Errorf("failed to generate operations when deleting ip port mapping %s from load balancers %s: %w", vipEndpoint, lbName, err) } if len(ops) == 0 { return nil } if err = c.Transact("lb-del", ops); err != nil { - return fmt.Errorf("failed to delete ip port mappings %s from load balancer %s: %v", vipEndpoint, lbName, err) + return fmt.Errorf("failed to delete ip port mappings %s from load balancer %s: %w", vipEndpoint, lbName, err) } return nil } @@ -497,10 +497,10 @@ func (c *OVNNbClient) LoadBalancerUpdateIPPortMapping(lbName, vipEndpoint string }, ) if err != nil { - return fmt.Errorf("failed to generate operations when adding ip port mapping with vip %v to load balancers %s: %v", vipEndpoint, lbName, err) + return fmt.Errorf("failed to generate operations when adding ip port mapping with vip %v to load balancers %s: %w", vipEndpoint, lbName, err) } if err = c.Transact("lb-add", ops); err != nil { - return fmt.Errorf("failed to add ip port mapping with vip %v to load balancers %s: %v", vipEndpoint, lbName, err) + return fmt.Errorf("failed to add ip port mapping with vip %v to load balancers %s: %w", vipEndpoint, lbName, err) } } return nil @@ -550,13 +550,13 @@ func (c *OVNNbClient) LoadBalancerDeleteHealthCheck(lbName, uuid string) error { }, ) if err != nil { - return fmt.Errorf("failed to generate operations when deleting health check %s from load balancers %s: %v", uuid, lbName, err) + return fmt.Errorf("failed to generate operations when deleting health check %s from load balancers %s: %w", uuid, lbName, err) } if len(ops) == 0 { return nil } if err = c.Transact("lb-hc-del", ops); err != nil { - return fmt.Errorf("failed to delete health check %s from load balancers %s: %v", uuid, lbName, err) + return fmt.Errorf("failed to delete health check %s from load balancers %s: %w", uuid, lbName, err) } } diff --git a/pkg/ovs/ovn-nb-load_balancer_health_check.go b/pkg/ovs/ovn-nb-load_balancer_health_check.go index 15482ece3e30..41a026f7951b 100644 --- a/pkg/ovs/ovn-nb-load_balancer_health_check.go +++ b/pkg/ovs/ovn-nb-load_balancer_health_check.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "slices" @@ -16,7 +17,7 @@ import ( func (c *OVNNbClient) AddLoadBalancerHealthCheck(lbName, vipEndpoint string, externals map[string]string) error { lbhc, err := c.newLoadBalancerHealthCheck(lbName, vipEndpoint, externals) if err != nil { - err := fmt.Errorf("failed to new lb health check: %v", err) + err := fmt.Errorf("failed to new lb health check: %w", err) klog.Error(err) return err } @@ -32,18 +33,18 @@ func (c *OVNNbClient) newLoadBalancerHealthCheck(lbName, vipEndpoint string, ext ) if len(lbName) == 0 { - err = fmt.Errorf("the lb name is required") + err = errors.New("the lb name is required") klog.Error(err) return nil, err } if len(vipEndpoint) == 0 { - err = fmt.Errorf("the vip endpoint is required") + err = errors.New("the vip endpoint is required") klog.Error(err) return nil, err } if exists, err = c.LoadBalancerHealthCheckExists(lbName, vipEndpoint); err != nil { - err := fmt.Errorf("get lb health check %s: %v", vipEndpoint, err) + err := fmt.Errorf("get lb health check %s: %w", vipEndpoint, err) klog.Error(err) return nil, err } @@ -88,19 +89,19 @@ func (c *OVNNbClient) CreateLoadBalancerHealthCheck(lbName, vipEndpoint string, if createLbhcOp, err = c.ovsDbClient.Create(models...); err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating lbhc: %v", err) + return fmt.Errorf("generate operations for creating lbhc: %w", err) } ops = append(ops, createLbhcOp...) if lbHcAddOp, err = c.LoadBalancerUpdateHealthCheckOp(lbName, lbhcUUIDs, ovsdb.MutateOperationInsert); err != nil { - err = fmt.Errorf("generate operations for adding lbhc to lb %s: %v", lbName, err) + err = fmt.Errorf("generate operations for adding lbhc to lb %s: %w", lbName, err) klog.Error(err) return err } ops = append(ops, lbHcAddOp...) if err = c.Transact("lbhc-add", ops); err != nil { - err = fmt.Errorf("failed to create lb health check for lb %s vip %s: %v", lbName, vipEndpoint, err) + err = fmt.Errorf("failed to create lb health check for lb %s vip %s: %w", lbName, vipEndpoint, err) klog.Error(err) return err } @@ -116,11 +117,11 @@ func (c *OVNNbClient) UpdateLoadBalancerHealthCheck(lbhc *ovnnb.LoadBalancerHeal ) if op, err = c.ovsDbClient.Where(lbhc).Update(lbhc, fields...); err != nil { - return fmt.Errorf("generate operations for updating lb health check %s: %v", lbhc.Vip, err) + return fmt.Errorf("generate operations for updating lb health check %s: %w", lbhc.Vip, err) } if err = c.Transact("lbhc-update", op); err != nil { - return fmt.Errorf("update lb health check %s: %v", lbhc.Vip, err) + return fmt.Errorf("update lb health check %s: %w", lbhc.Vip, err) } return nil @@ -137,11 +138,11 @@ func (c *OVNNbClient) DeleteLoadBalancerHealthChecks(filter func(lb *ovnnb.LoadB }, ).Delete() if err != nil { - return fmt.Errorf("generate operations for delete lb health checks: %v", err) + return fmt.Errorf("generate operations for delete lb health checks: %w", err) } if err := c.Transact("lbhc-del", op); err != nil { - return fmt.Errorf("delete lb health checks : %v", err) + return fmt.Errorf("delete lb health checks : %w", err) } return nil @@ -161,7 +162,7 @@ func (c *OVNNbClient) DeleteLoadBalancerHealthCheck(lbName, vip string) error { } if err = c.Transact("lbhc-del", op); err != nil { - return fmt.Errorf("delete lb %s: %v", lbName, err) + return fmt.Errorf("delete lb %s: %w", lbName, err) } return nil @@ -194,7 +195,7 @@ func (c *OVNNbClient) GetLoadBalancerHealthCheck(lbName, vipEndpoint string, ign healthCheck.Vip == vipEndpoint }, ).List(ctx, &healthCheckList); err != nil { - err = fmt.Errorf("failed to list lb health check lb health check by vip %q: %v", vipEndpoint, err) + err = fmt.Errorf("failed to list lb health check lb health check by vip %q: %w", vipEndpoint, err) klog.Error(err) return nil, nil, err } @@ -235,7 +236,7 @@ func (c *OVNNbClient) ListLoadBalancerHealthChecks(filter func(lbhc *ovnnb.LoadB return true }, ).List(ctx, &lbhcList); err != nil { - return nil, fmt.Errorf("list lb health check: %v", err) + return nil, fmt.Errorf("list lb health check: %w", err) } return lbhcList, nil diff --git a/pkg/ovs/ovn-nb-logical_router.go b/pkg/ovs/ovn-nb-logical_router.go index 4506e7212298..e91b89c38846 100644 --- a/pkg/ovs/ovn-nb-logical_router.go +++ b/pkg/ovs/ovn-nb-logical_router.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "slices" "strings" @@ -34,11 +35,11 @@ func (c *OVNNbClient) CreateLogicalRouter(lrName string) error { op, err := c.ovsDbClient.Create(lr) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating logical router %s: %v", lrName, err) + return fmt.Errorf("generate operations for creating logical router %s: %w", lrName, err) } if err := c.Transact("lr-add", op); err != nil { - return fmt.Errorf("create logical router %s: %v", lrName, err) + return fmt.Errorf("create logical router %s: %w", lrName, err) } return nil @@ -53,7 +54,7 @@ func (c *OVNNbClient) UpdateLogicalRouter(lr *ovnnb.LogicalRouter, fields ...int } if err = c.Transact("lr-update", op); err != nil { - return fmt.Errorf("update logical router %s: %v", lr.Name, err) + return fmt.Errorf("update logical router %s: %w", lr.Name, err) } return nil @@ -64,7 +65,7 @@ func (c *OVNNbClient) DeleteLogicalRouter(lrName string) error { lr, err := c.GetLogicalRouter(lrName, true) if err != nil { klog.Error(err) - return fmt.Errorf("get logical router %s when delete: %v", lrName, err) + return fmt.Errorf("get logical router %s when delete: %w", lrName, err) } // not found, skip @@ -79,7 +80,7 @@ func (c *OVNNbClient) DeleteLogicalRouter(lrName string) error { } if err := c.Transact("lr-del", op); err != nil { - return fmt.Errorf("delete logical router %s: %v", lrName, err) + return fmt.Errorf("delete logical router %s: %w", lrName, err) } return nil @@ -95,7 +96,7 @@ func (c *OVNNbClient) GetLogicalRouter(lrName string, ignoreNotFound bool) (*ovn if err := c.ovsDbClient.WhereCache(func(lr *ovnnb.LogicalRouter) bool { return lr.Name == lrName }).List(ctx, &lrList); err != nil { - return nil, fmt.Errorf("list logical router %q: %v", lrName, err) + return nil, fmt.Errorf("list logical router %q: %w", lrName, err) } // not found @@ -137,7 +138,7 @@ func (c *OVNNbClient) ListLogicalRouter(needVendorFilter bool, filter func(lr *o return true }).List(ctx, &lrList); err != nil { - return nil, fmt.Errorf("list logical router: %v", err) + return nil, fmt.Errorf("list logical router: %w", err) } return lrList, nil @@ -177,11 +178,11 @@ func (c *OVNNbClient) LogicalRouterUpdateLoadBalancers(lrName string, op ovsdb.M ops, err := c.LogicalRouterOp(lrName, mutation) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for logical router %s update lbs %v: %v", lrName, lbNames, err) + return fmt.Errorf("generate operations for logical router %s update lbs %v: %w", lrName, lbNames, err) } if err := c.Transact("lr-lb-update", ops); err != nil { - return fmt.Errorf("logical router %s update lbs %v: %v", lrName, lbNames, err) + return fmt.Errorf("logical router %s update lbs %v: %w", lrName, lbNames, err) } return nil @@ -190,13 +191,13 @@ func (c *OVNNbClient) LogicalRouterUpdateLoadBalancers(lrName string, op ovsdb.M // UpdateLogicalRouterOp generate operations which update logical router func (c *OVNNbClient) UpdateLogicalRouterOp(lr *ovnnb.LogicalRouter, fields ...interface{}) ([]ovsdb.Operation, error) { if lr == nil { - return nil, fmt.Errorf("logical_router is nil") + return nil, errors.New("logical_router is nil") } op, err := c.ovsDbClient.Where(lr).Update(lr, fields...) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for updating logical router %s: %v", lr.Name, err) + return nil, fmt.Errorf("generate operations for updating logical router %s: %w", lr.Name, err) } return op, nil @@ -214,7 +215,7 @@ func (c *OVNNbClient) LogicalRouterUpdatePortOp(lrName, lrpUUID string, op ovsdb }) if err != nil { klog.Error(err) - return nil, fmt.Errorf("failed to list LR by LRP UUID %s: %v", lrpUUID, err) + return nil, fmt.Errorf("failed to list LR by LRP UUID %s: %w", lrpUUID, err) } if len(lrList) == 0 { err = fmt.Errorf("no LR found for LRP %s", lrpUUID) @@ -308,7 +309,7 @@ func (c *OVNNbClient) LogicalRouterOp(lrName string, mutationsFunc ...func(lr *o lr, err := c.GetLogicalRouter(lrName, false) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical router %s: %v", lrName, err) + return nil, fmt.Errorf("get logical router %s: %w", lrName, err) } if len(mutationsFunc) == 0 { @@ -328,7 +329,7 @@ func (c *OVNNbClient) LogicalRouterOp(lrName string, mutationsFunc ...func(lr *o ops, err := c.ovsDbClient.Where(lr).Mutate(lr, mutations...) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for mutating logical router %s: %v", lrName, err) + return nil, fmt.Errorf("generate operations for mutating logical router %s: %w", lrName, err) } return ops, nil diff --git a/pkg/ovs/ovn-nb-logical_router_policy.go b/pkg/ovs/ovn-nb-logical_router_policy.go index d8a90412b2d2..58938f292132 100644 --- a/pkg/ovs/ovn-nb-logical_router_policy.go +++ b/pkg/ovs/ovn-nb-logical_router_policy.go @@ -25,7 +25,7 @@ func (c *OVNNbClient) AddLogicalRouterPolicy(lrName string, priority int, match, } policyList, err := c.listLogicalRouterPoliciesByFilter(lrName, fnFilter) if err != nil { - return fmt.Errorf("get policy priority %d match %s in logical router %s: %v", priority, match, lrName, err) + return fmt.Errorf("get policy priority %d match %s in logical router %s: %w", priority, match, lrName, err) } duplicate := make([]string, 0, len(policyList)) @@ -52,20 +52,20 @@ func (c *OVNNbClient) AddLogicalRouterPolicy(lrName string, priority int, match, klog.Infof("creating lr policy with priority = %d, match = %q, action = %q, nextHops = %q", priority, match, action, nextHops) policy := c.newLogicalRouterPolicy(priority, match, action, nextHops, externalIDs) if err := c.CreateLogicalRouterPolicies(lrName, policy); err != nil { - return fmt.Errorf("add policy to logical router %s: %v", lrName, err) + return fmt.Errorf("add policy to logical router %s: %w", lrName, err) } } else if !maps.Equal(policyFound.ExternalIDs, externalIDs) { policy := ptr.To(*policyFound) policy.ExternalIDs = externalIDs ops, err := c.Where(policy).Update(policy, &policy.ExternalIDs) if err != nil { - err := fmt.Errorf("failed to generate operations for updating logical router policy: %v", err) + err := fmt.Errorf("failed to generate operations for updating logical router policy: %w", err) klog.Error(err) return err } if err = c.Transact("lr-policy-update", ops); err != nil { - err := fmt.Errorf("failed to update logical router policy: %v", err) + err := fmt.Errorf("failed to update logical router policy: %w", err) klog.Error(err) return err } @@ -92,13 +92,13 @@ func (c *OVNNbClient) CreateLogicalRouterPolicies(lrName string, policies ...*ov createPoliciesOp, err := c.ovsDbClient.Create(models...) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating policies: %v", err) + return fmt.Errorf("generate operations for creating policies: %w", err) } policyAddOp, err := c.LogicalRouterUpdatePolicyOp(lrName, policyUUIDs, ovsdb.MutateOperationInsert) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for adding policies to logical router %s: %v", lrName, err) + return fmt.Errorf("generate operations for adding policies to logical router %s: %w", lrName, err) } ops := make([]ovsdb.Operation, 0, len(createPoliciesOp)+len(policyAddOp)) @@ -106,7 +106,7 @@ func (c *OVNNbClient) CreateLogicalRouterPolicies(lrName string, policies ...*ov ops = append(ops, policyAddOp...) if err = c.Transact("lr-policies-add", ops); err != nil { - return fmt.Errorf("add policies to %s: %v", lrName, err) + return fmt.Errorf("add policies to %s: %w", lrName, err) } return nil @@ -149,10 +149,10 @@ func (c *OVNNbClient) DeleteLogicalRouterPolicies(lrName string, priority int, e ops, err := c.LogicalRouterUpdatePolicyOp(lrName, policiesUUIDs, ovsdb.MutateOperationDelete) if err != nil { - return fmt.Errorf("generate operations for removing policy %v from logical router %s: %v", policiesUUIDs, lrName, err) + return fmt.Errorf("generate operations for removing policy %v from logical router %s: %w", policiesUUIDs, lrName, err) } if err = c.Transact("lr-policies-del", ops); err != nil { - return fmt.Errorf("delete logical router policy %v from logical router %s: %v", policiesUUIDs, lrName, err) + return fmt.Errorf("delete logical router policy %v from logical router %s: %w", policiesUUIDs, lrName, err) } return nil } @@ -161,10 +161,10 @@ func (c *OVNNbClient) DeleteLogicalRouterPolicyByUUID(lrName, uuid string) error // remove policy from logical router ops, err := c.LogicalRouterUpdatePolicyOp(lrName, []string{uuid}, ovsdb.MutateOperationDelete) if err != nil { - return fmt.Errorf("generate operations for removing policy '%s' from logical router %s: %v", uuid, lrName, err) + return fmt.Errorf("generate operations for removing policy '%s' from logical router %s: %w", uuid, lrName, err) } if err = c.Transact("lr-policy-del", ops); err != nil { - return fmt.Errorf("delete logical router policy '%s' from logical router %s: %v", uuid, lrName, err) + return fmt.Errorf("delete logical router policy '%s' from logical router %s: %w", uuid, lrName, err) } return nil } @@ -192,17 +192,17 @@ func (c *OVNNbClient) DeleteLogicalRouterPolicyByNexthop(lrName string, priority func (c *OVNNbClient) ClearLogicalRouterPolicy(lrName string) error { lr, err := c.GetLogicalRouter(lrName, false) if err != nil { - return fmt.Errorf("get logical router %s: %v", lrName, err) + return fmt.Errorf("get logical router %s: %w", lrName, err) } // clear logical router policy lr.Policies = nil ops, err := c.UpdateLogicalRouterOp(lr, &lr.Policies) if err != nil { - return fmt.Errorf("generate operations for clear logical router %s policy: %v", lrName, err) + return fmt.Errorf("generate operations for clear logical router %s policy: %w", lrName, err) } if err = c.Transact("lr-policy-clear", ops); err != nil { - return fmt.Errorf("clear logical router %s policy: %v", lrName, err) + return fmt.Errorf("clear logical router %s policy: %w", lrName, err) } return nil @@ -213,7 +213,7 @@ func (c *OVNNbClient) ClearLogicalRouterPolicy(lrName string) error { func (c *OVNNbClient) GetLogicalRouterPolicy(lrName string, priority int, match string, ignoreNotFound bool) ([]*ovnnb.LogicalRouterPolicy, error) { // this is necessary because may exist same priority and match policy in different logical router if len(lrName) == 0 { - return nil, fmt.Errorf("the logical router name is required") + return nil, errors.New("the logical router name is required") } fnFilter := func(policy *ovnnb.LogicalRouterPolicy) bool { @@ -221,7 +221,7 @@ func (c *OVNNbClient) GetLogicalRouterPolicy(lrName string, priority int, match } policyList, err := c.listLogicalRouterPoliciesByFilter(lrName, fnFilter) if err != nil { - return nil, fmt.Errorf("get policy priority %d match %s in logical router %s: %v", priority, match, lrName, err) + return nil, fmt.Errorf("get policy priority %d match %s in logical router %s: %w", priority, match, lrName, err) } // not found @@ -317,10 +317,10 @@ func (c *OVNNbClient) DeleteRouterPolicy(lr *ovnnb.LogicalRouter, uuid string) e Value: []string{uuid}, }) if err != nil { - return fmt.Errorf("failed to generate delete operations for router %s: %v", uuid, err) + return fmt.Errorf("failed to generate delete operations for router %s: %w", uuid, err) } if err = c.Transact("lr-policy-delete", ops); err != nil { - return fmt.Errorf("failed to delete route policy %s: %v", uuid, err) + return fmt.Errorf("failed to delete route policy %s: %w", uuid, err) } return nil } diff --git a/pkg/ovs/ovn-nb-logical_router_port.go b/pkg/ovs/ovn-nb-logical_router_port.go index 77fbb73a86b2..0a182b285940 100644 --- a/pkg/ovs/ovn-nb-logical_router_port.go +++ b/pkg/ovs/ovn-nb-logical_router_port.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "strings" @@ -50,7 +51,7 @@ func (c *OVNNbClient) CreatePeerRouterPort(localRouter, remoteRouter, localRoute } if err = c.Transact("lrp-add", ops); err != nil { - err := fmt.Errorf("create peer router port %s for logical router%s: %v", localRouterPort, localRouter, err) + err := fmt.Errorf("create peer router port %s for logical router%s: %w", localRouterPort, localRouter, err) klog.Error(err) return err } @@ -110,18 +111,18 @@ func (c *OVNNbClient) UpdateLogicalRouterPortOptions(lrpName string, options map // UpdateLogicalRouterPort update logical router port func (c *OVNNbClient) UpdateLogicalRouterPort(lrp *ovnnb.LogicalRouterPort, fields ...interface{}) error { if lrp == nil { - return fmt.Errorf("logical_router_port is nil") + return errors.New("logical_router_port is nil") } op, err := c.Where(lrp).Update(lrp, fields...) if err != nil { - err := fmt.Errorf("generate operations for updating logical router port %s: %v", lrp.Name, err) + err := fmt.Errorf("generate operations for updating logical router port %s: %w", lrp.Name, err) klog.Error(err) return err } if err = c.Transact("lrp-update", op); err != nil { - err := fmt.Errorf("update logical router port %s: %v", lrp.Name, err) + err := fmt.Errorf("update logical router port %s: %w", lrp.Name, err) klog.Error(err) return err } @@ -155,13 +156,13 @@ func (c *OVNNbClient) CreateLogicalRouterPort(lrName, lrpName, mac string, netwo op, err := c.CreateLogicalRouterPortOp(lrp, lrName) if err != nil { - err := fmt.Errorf("generate operations for creating logical router port %s: %v", lrp.Name, err) + err := fmt.Errorf("generate operations for creating logical router port %s: %w", lrp.Name, err) klog.Error(err) return err } if err = c.Transact("lrp-add", op); err != nil { - err := fmt.Errorf("create logical router port %s: %v", lrp.Name, err) + err := fmt.Errorf("create logical router port %s: %w", lrp.Name, err) klog.Error(err) return err } @@ -173,7 +174,7 @@ func (c *OVNNbClient) CreateLogicalRouterPort(lrName, lrpName, mac string, netwo func (c *OVNNbClient) DeleteLogicalRouterPorts(externalIDs map[string]string, filter func(lrp *ovnnb.LogicalRouterPort) bool) error { lrpList, err := c.ListLogicalRouterPorts(externalIDs, filter) if err != nil { - err := fmt.Errorf("list logical router ports: %v", err) + err := fmt.Errorf("list logical router ports: %w", err) klog.Error(err) return err } @@ -183,13 +184,13 @@ func (c *OVNNbClient) DeleteLogicalRouterPorts(externalIDs map[string]string, fi op, err := c.DeleteLogicalRouterPortOp(lrp.Name) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for deleting logical router port %s: %v", lrp.Name, err) + return fmt.Errorf("generate operations for deleting logical router port %s: %w", lrp.Name, err) } ops = append(ops, op...) } if err := c.Transact("lrps-del", ops); err != nil { - err := fmt.Errorf("del logical router ports: %v", err) + err := fmt.Errorf("del logical router ports: %w", err) klog.Error(err) return err } @@ -201,7 +202,7 @@ func (c *OVNNbClient) DeleteLogicalRouterPorts(externalIDs map[string]string, fi func (c *OVNNbClient) DeleteLogicalRouterPort(lrpName string) error { ops, err := c.DeleteLogicalRouterPortOp(lrpName) if err != nil { - err := fmt.Errorf("generate operations for deleting logical router port %s: %v", lrpName, err) + err := fmt.Errorf("generate operations for deleting logical router port %s: %w", lrpName, err) klog.Error(err) return err } @@ -222,10 +223,10 @@ func (c *OVNNbClient) GetLogicalRouterPort(lrpName string, ignoreNotFound bool) lrp := &ovnnb.LogicalRouterPort{Name: lrpName} if err := c.Get(ctx, lrp); err != nil { - if ignoreNotFound && err == client.ErrNotFound { + if ignoreNotFound && errors.Is(err, client.ErrNotFound) { return nil, nil } - err = fmt.Errorf("get logical router port %s: %v", lrpName, err) + err = fmt.Errorf("get logical router port %s: %w", lrpName, err) klog.Error(err) return nil, err } @@ -240,7 +241,7 @@ func (c *OVNNbClient) GetLogicalRouterPortByUUID(uuid string) (*ovnnb.LogicalRou lrp := &ovnnb.LogicalRouterPort{UUID: uuid} if err := c.Get(ctx, lrp); err != nil { - err := fmt.Errorf("get logical router port by UUID %s: %v", uuid, err) + err := fmt.Errorf("get logical router port by UUID %s: %w", uuid, err) klog.Error(err) return nil, err } @@ -256,7 +257,7 @@ func (c *OVNNbClient) ListLogicalRouterPorts(externalIDs map[string]string, filt lrpList := make([]ovnnb.LogicalRouterPort, 0) if err := c.WhereCache(logicalRouterPortFilter(externalIDs, filter)).List(ctx, &lrpList); err != nil { - err := fmt.Errorf("list logical router ports: %v", err) + err := fmt.Errorf("list logical router ports: %w", err) klog.Error(err) return nil, err } @@ -267,7 +268,7 @@ func (c *OVNNbClient) ListLogicalRouterPorts(externalIDs map[string]string, filt func (c *OVNNbClient) LogicalRouterPortExists(lrpName string) (bool, error) { lrp, err := c.GetLogicalRouterPort(lrpName, true) if err != nil { - err := fmt.Errorf("get logical router port %s: %v", lrpName, err) + err := fmt.Errorf("get logical router port %s: %w", lrpName, err) klog.Error(err) return false, err } @@ -296,7 +297,7 @@ func (c *OVNNbClient) LogicalRouterPortUpdateGatewayChassisOp(lrpName string, uu // CreateLogicalRouterPortOp create operation which create logical router port func (c *OVNNbClient) CreateLogicalRouterPortOp(lrp *ovnnb.LogicalRouterPort, lrName string) ([]ovsdb.Operation, error) { if lrp == nil { - return nil, fmt.Errorf("logical_router_port is nil") + return nil, errors.New("logical_router_port is nil") } if lrp.ExternalIDs == nil { @@ -310,7 +311,7 @@ func (c *OVNNbClient) CreateLogicalRouterPortOp(lrp *ovnnb.LogicalRouterPort, lr /* create logical router port */ lrpCreateOp, err := c.Create(lrp) if err != nil { - err := fmt.Errorf("generate operations for creating logical router port %s: %v", lrp.Name, err) + err := fmt.Errorf("generate operations for creating logical router port %s: %w", lrp.Name, err) klog.Error(err) return nil, err } @@ -318,7 +319,7 @@ func (c *OVNNbClient) CreateLogicalRouterPortOp(lrp *ovnnb.LogicalRouterPort, lr /* add logical router port to logical router*/ lrpAddOp, err := c.LogicalRouterUpdatePortOp(lrName, lrp.UUID, ovsdb.MutateOperationInsert) if err != nil { - err := fmt.Errorf("generate operations for adding logical router port %s to logical router %s: %v", lrp.Name, lrName, err) + err := fmt.Errorf("generate operations for adding logical router port %s to logical router %s: %w", lrp.Name, lrName, err) klog.Error(err) return nil, err } @@ -334,7 +335,7 @@ func (c *OVNNbClient) CreateLogicalRouterPortOp(lrp *ovnnb.LogicalRouterPort, lr func (c *OVNNbClient) DeleteLogicalRouterPortOp(lrpName string) ([]ovsdb.Operation, error) { lrp, err := c.GetLogicalRouterPort(lrpName, true) if err != nil { - err := fmt.Errorf("get logical router port %s when generate delete operations: %v", lrpName, err) + err := fmt.Errorf("get logical router port %s when generate delete operations: %w", lrpName, err) klog.Error(err) return nil, err } @@ -373,7 +374,7 @@ func (c *OVNNbClient) LogicalRouterPortOp(lrpName string, mutationsFunc ...func( ops, err := c.ovsDbClient.Where(lrp).Mutate(lrp, mutations...) if err != nil { - err := fmt.Errorf("generate operations for mutating logical router port %s: %v", lrpName, err) + err := fmt.Errorf("generate operations for mutating logical router port %s: %w", lrpName, err) klog.Error(err) return nil, err } @@ -459,7 +460,7 @@ func (c *OVNNbClient) AddLogicalRouterPort(lr, name, mac, networks string) error ops = append(ops, mutationOps...) klog.Infof("add vpc lrp %s, networks %s", name, networks) if err := c.Transact("lrp-add", ops); err != nil { - return fmt.Errorf("failed to create logical router port %s: %v", name, err) + return fmt.Errorf("failed to create logical router port %s: %w", name, err) } return nil } diff --git a/pkg/ovs/ovn-nb-logical_router_route.go b/pkg/ovs/ovn-nb-logical_router_route.go index 35ae1ac542a6..5ffc56af46ec 100644 --- a/pkg/ovs/ovn-nb-logical_router_route.go +++ b/pkg/ovs/ovn-nb-logical_router_route.go @@ -47,12 +47,12 @@ func (c *OVNNbClient) CreateLogicalRouterStaticRoutes(lrName string, routes ...* createRoutesOp, err := c.ovsDbClient.Create(models...) if err != nil { - return fmt.Errorf("generate operations for creating static routes: %v", err) + return fmt.Errorf("generate operations for creating static routes: %w", err) } routeAddOp, err := c.LogicalRouterUpdateStaticRouteOp(lrName, routeUUIDs, ovsdb.MutateOperationInsert) if err != nil { - return fmt.Errorf("generate operations for adding static routes to logical router %s: %v", lrName, err) + return fmt.Errorf("generate operations for adding static routes to logical router %s: %w", lrName, err) } ops := make([]ovsdb.Operation, 0, len(createRoutesOp)+len(routeAddOp)) @@ -60,7 +60,7 @@ func (c *OVNNbClient) CreateLogicalRouterStaticRoutes(lrName string, routes ...* ops = append(ops, routeAddOp...) if err = c.Transact("lr-routes-add", ops); err != nil { - return fmt.Errorf("add static routes to %s: %v", lrName, err) + return fmt.Errorf("add static routes to %s: %w", lrName, err) } return nil @@ -105,14 +105,14 @@ func (c *OVNNbClient) AddLogicalRouterStaticRoute(lrName, routeTable, policy, ip ops, err := c.LogicalRouterUpdateStaticRouteOp(lrName, toDel, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for removing static routes from logical router %s: %v", lrName, err) + return fmt.Errorf("generate operations for removing static routes from logical router %s: %w", lrName, err) } if err = c.Transact("lr-route-del", ops); err != nil { klog.Error(err) - return fmt.Errorf("failed to delete static routes from logical router %s: %v", lrName, err) + return fmt.Errorf("failed to delete static routes from logical router %s: %w", lrName, err) } if err = c.CreateLogicalRouterStaticRoutes(lrName, toAdd...); err != nil { - return fmt.Errorf("failed to add static routes to logical router %s: %v", lrName, err) + return fmt.Errorf("failed to add static routes to logical router %s: %w", lrName, err) } return nil } @@ -120,17 +120,17 @@ func (c *OVNNbClient) AddLogicalRouterStaticRoute(lrName, routeTable, policy, ip // UpdateLogicalRouterStaticRoute update logical router static route func (c *OVNNbClient) UpdateLogicalRouterStaticRoute(route *ovnnb.LogicalRouterStaticRoute, fields ...interface{}) error { if route == nil { - return fmt.Errorf("route is nil") + return errors.New("route is nil") } op, err := c.ovsDbClient.Where(route).Update(route, fields...) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for updating logical router static route 'policy %s ip_prefix %s': %v", *route.Policy, route.IPPrefix, err) + return fmt.Errorf("generate operations for updating logical router static route 'policy %s ip_prefix %s': %w", *route.Policy, route.IPPrefix, err) } if err = c.Transact("net-update", op); err != nil { - return fmt.Errorf("update logical router static route 'policy %s ip_prefix %s': %v", *route.Policy, route.IPPrefix, err) + return fmt.Errorf("update logical router static route 'policy %s ip_prefix %s': %w", *route.Policy, route.IPPrefix, err) } return nil @@ -169,11 +169,11 @@ func (c *OVNNbClient) DeleteLogicalRouterStaticRoute(lrName string, routeTable, ops, err := c.LogicalRouterUpdateStaticRouteOp(lrName, uuids, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for removing static routes %v from logical router %s: %v", uuids, lrName, err) + return fmt.Errorf("generate operations for removing static routes %v from logical router %s: %w", uuids, lrName, err) } if err = c.Transact("lr-route-del", ops); err != nil { klog.Error(err) - return fmt.Errorf("delete static routes %v from logical router %s: %v", uuids, lrName, err) + return fmt.Errorf("delete static routes %v from logical router %s: %w", uuids, lrName, err) } return nil @@ -184,7 +184,7 @@ func (c *OVNNbClient) ClearLogicalRouterStaticRoute(lrName string) error { lr, err := c.GetLogicalRouter(lrName, false) if err != nil { klog.Error(err) - return fmt.Errorf("get logical router %s: %v", lrName, err) + return fmt.Errorf("get logical router %s: %w", lrName, err) } // clear static route @@ -192,11 +192,11 @@ func (c *OVNNbClient) ClearLogicalRouterStaticRoute(lrName string) error { ops, err := c.UpdateLogicalRouterOp(lr, &lr.StaticRoutes) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for clear logical router %s static route: %v", lrName, err) + return fmt.Errorf("generate operations for clear logical router %s static route: %w", lrName, err) } if err = c.Transact("lr-route-clear", ops); err != nil { klog.Error(err) - return fmt.Errorf("clear logical router %s static routes: %v", lrName, err) + return fmt.Errorf("clear logical router %s static routes: %w", lrName, err) } return nil @@ -222,7 +222,7 @@ func (c *OVNNbClient) GetLogicalRouterStaticRouteByUUID(uuid string) (*ovnnb.Log func (c *OVNNbClient) GetLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop string, ignoreNotFound bool) (*ovnnb.LogicalRouterStaticRoute, error) { // this is necessary because may exist same static route in different logical router if len(lrName) == 0 { - return nil, fmt.Errorf("the logical router name is required") + return nil, errors.New("the logical router name is required") } fnFilter := func(route *ovnnb.LogicalRouterStaticRoute) bool { @@ -231,7 +231,7 @@ func (c *OVNNbClient) GetLogicalRouterStaticRoute(lrName, routeTable, policy, ip routeList, err := c.listLogicalRouterStaticRoutesByFilter(lrName, fnFilter) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical router %s static route 'policy %s ip_prefix %s nexthop %s': %v", lrName, policy, ipPrefix, nexthop, err) + return nil, fmt.Errorf("get logical router %s static route 'policy %s ip_prefix %s nexthop %s': %w", lrName, policy, ipPrefix, nexthop, err) } // not found @@ -302,7 +302,7 @@ func (c *OVNNbClient) LogicalRouterStaticRouteExists(lrName, routeTable, policy, // newLogicalRouterStaticRoute return logical router static route with basic information func (c *OVNNbClient) newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop string, bfdID *string, options ...func(route *ovnnb.LogicalRouterStaticRoute)) (*ovnnb.LogicalRouterStaticRoute, error) { if len(lrName) == 0 { - return nil, fmt.Errorf("the logical router name is required") + return nil, errors.New("the logical router name is required") } if len(policy) == 0 { @@ -312,7 +312,7 @@ func (c *OVNNbClient) newLogicalRouterStaticRoute(lrName, routeTable, policy, ip exists, err := c.LogicalRouterStaticRouteExists(lrName, routeTable, policy, ipPrefix, nexthop) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical router %s route: %v", lrName, err) + return nil, fmt.Errorf("get logical router %s route: %w", lrName, err) } // found, ignore diff --git a/pkg/ovs/ovn-nb-logical_switch.go b/pkg/ovs/ovn-nb-logical_switch.go index b029f14ff365..df48ce0d15c5 100644 --- a/pkg/ovs/ovn-nb-logical_switch.go +++ b/pkg/ovs/ovn-nb-logical_switch.go @@ -65,7 +65,7 @@ func (c *OVNNbClient) CreateLogicalSwitch(lsName, lrName, cidrBlock, gateway, ga } if err := c.RemoveLogicalPatchPort(lspName, lrpName); err != nil { - return fmt.Errorf("remove router type port %s and %s: %v", lspName, lrpName, err) + return fmt.Errorf("remove router type port %s and %s: %w", lspName, lrpName, err) } } @@ -93,11 +93,11 @@ func (c *OVNNbClient) CreateBareLogicalSwitch(lsName string) error { op, err := c.ovsDbClient.Create(ls) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating logical switch %s: %v", lsName, err) + return fmt.Errorf("generate operations for creating logical switch %s: %w", lsName, err) } if err := c.Transact("ls-add", op); err != nil { - return fmt.Errorf("create logical switch %s: %v", lsName, err) + return fmt.Errorf("create logical switch %s: %w", lsName, err) } return nil @@ -108,18 +108,18 @@ func (c *OVNNbClient) LogicalSwitchAddPort(lsName, lspName string) error { lsp, err := c.GetLogicalSwitchPort(lspName, false) if err != nil { klog.Error(err) - return fmt.Errorf("get logical switch port %s when logical switch add port: %v", lspName, err) + return fmt.Errorf("get logical switch port %s when logical switch add port: %w", lspName, err) } ops, err := c.LogicalSwitchUpdatePortOp(lsName, lsp.UUID, ovsdb.MutateOperationInsert) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for logical switch %s add port %s: %v", lsName, lspName, err) + return fmt.Errorf("generate operations for logical switch %s add port %s: %w", lsName, lspName, err) } if err := c.Transact("lsp-add", ops); err != nil { klog.Error(err) - return fmt.Errorf("add port %s to logical switch %s: %v", lspName, lsName, err) + return fmt.Errorf("add port %s to logical switch %s: %w", lspName, lsName, err) } return nil @@ -130,7 +130,7 @@ func (c *OVNNbClient) LogicalSwitchDelPort(lsName, lspName string) error { lsp, err := c.GetLogicalSwitchPort(lspName, true) if err != nil { klog.Error(err) - return fmt.Errorf("get logical switch port %s when logical switch del port: %v", lspName, err) + return fmt.Errorf("get logical switch port %s when logical switch del port: %w", lspName, err) } if lsp == nil { @@ -140,11 +140,11 @@ func (c *OVNNbClient) LogicalSwitchDelPort(lsName, lspName string) error { ops, err := c.LogicalSwitchUpdatePortOp(lsName, lsp.UUID, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for logical switch %s del port %s: %v", lsName, lspName, err) + return fmt.Errorf("generate operations for logical switch %s del port %s: %w", lsName, lspName, err) } if err := c.Transact("lsp-del", ops); err != nil { - return fmt.Errorf("del port %s from logical switch %s: %v", lspName, lsName, err) + return fmt.Errorf("del port %s from logical switch %s: %w", lspName, lsName, err) } return nil @@ -174,11 +174,11 @@ func (c *OVNNbClient) LogicalSwitchUpdateLoadBalancers(lsName string, op ovsdb.M ops, err := c.LogicalSwitchUpdateLoadBalancerOp(lsName, lbUUIDs, op) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for logical switch %s update lbs %v: %v", lsName, lbNames, err) + return fmt.Errorf("generate operations for logical switch %s update lbs %v: %w", lsName, lbNames, err) } if err := c.Transact("ls-lb-update", ops); err != nil { - return fmt.Errorf("logical switch %s update lbs %v: %v", lsName, lbNames, err) + return fmt.Errorf("logical switch %s update lbs %v: %w", lsName, lbNames, err) } return nil @@ -193,11 +193,11 @@ func (c *OVNNbClient) LogicalSwitchUpdateOtherConfig(lsName string, op ovsdb.Mut ops, err := c.LogicalSwitchUpdateOtherConfigOp(lsName, otherConfig, op) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for logical switch %s update other config %v: %v", lsName, otherConfig, err) + return fmt.Errorf("generate operations for logical switch %s update other config %v: %w", lsName, otherConfig, err) } if err := c.Transact("ls-other-config-update", ops); err != nil { - return fmt.Errorf("logical switch %s update other config %v: %v", lsName, otherConfig, err) + return fmt.Errorf("logical switch %s update other config %v: %w", lsName, otherConfig, err) } return nil @@ -212,7 +212,7 @@ func (c *OVNNbClient) DeleteLogicalSwitch(lsName string) error { } if err := c.Transact("ls-del", op); err != nil { - return fmt.Errorf("delete logical switch %s: %v", lsName, err) + return fmt.Errorf("delete logical switch %s: %w", lsName, err) } return nil @@ -228,7 +228,7 @@ func (c *OVNNbClient) GetLogicalSwitch(lsName string, ignoreNotFound bool) (*ovn if err := c.ovsDbClient.WhereCache(func(ls *ovnnb.LogicalSwitch) bool { return ls.Name == lsName }).List(ctx, &lsList); err != nil { - return nil, fmt.Errorf("list switch switch %q: %v", lsName, err) + return nil, fmt.Errorf("list switch switch %q: %w", lsName, err) } // not found @@ -270,7 +270,7 @@ func (c *OVNNbClient) ListLogicalSwitch(needVendorFilter bool, filter func(ls *o return true }).List(ctx, &lsList); err != nil { - return nil, fmt.Errorf("list logical switch: %v", err) + return nil, fmt.Errorf("list logical switch: %w", err) } return lsList, nil @@ -288,7 +288,7 @@ func (c *OVNNbClient) LogicalSwitchUpdatePortOp(lsName, lspUUID string, op ovsdb }) if err != nil { klog.Error(err) - return nil, fmt.Errorf("failed to list LS by LSP UUID %s: %v", lspUUID, err) + return nil, fmt.Errorf("failed to list LS by LSP UUID %s: %w", lspUUID, err) } if len(lsList) == 0 { err = fmt.Errorf("no LS found for LSP %s", lspUUID) @@ -382,7 +382,7 @@ func (c *OVNNbClient) LogicalSwitchOp(lsName string, mutationsFunc ...func(ls *o ls, err := c.GetLogicalSwitch(lsName, false) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical switch %s when generate mutate operations: %v", lsName, err) + return nil, fmt.Errorf("get logical switch %s when generate mutate operations: %w", lsName, err) } if len(mutationsFunc) == 0 { @@ -402,7 +402,7 @@ func (c *OVNNbClient) LogicalSwitchOp(lsName string, mutationsFunc ...func(ls *o ops, err := c.ovsDbClient.Where(ls).Mutate(ls, mutations...) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for mutating logical switch %s: %v", lsName, err) + return nil, fmt.Errorf("generate operations for mutating logical switch %s: %w", lsName, err) } return ops, nil @@ -413,7 +413,7 @@ func (c *OVNNbClient) DeleteLogicalSwitchOp(lsName string) ([]ovsdb.Operation, e ls, err := c.GetLogicalSwitch(lsName, true) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical switch %s: %v", lsName, err) + return nil, fmt.Errorf("get logical switch %s: %w", lsName, err) } // not found, skip @@ -424,7 +424,7 @@ func (c *OVNNbClient) DeleteLogicalSwitchOp(lsName string) ([]ovsdb.Operation, e op, err := c.Where(ls).Delete() if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for deleting logical switch %s: %v", lsName, err) + return nil, fmt.Errorf("generate operations for deleting logical switch %s: %w", lsName, err) } return op, nil diff --git a/pkg/ovs/ovn-nb-logical_switch_port.go b/pkg/ovs/ovn-nb-logical_switch_port.go index e949f8f06348..32e49e712794 100644 --- a/pkg/ovs/ovn-nb-logical_switch_port.go +++ b/pkg/ovs/ovn-nb-logical_switch_port.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "reflect" "slices" @@ -101,7 +102,7 @@ func (c *OVNNbClient) CreateLogicalSwitchPort(lsName, lspName, ip, mac, podName, if existingLsp.ExternalIDs[logicalSwitchKey] == lsName { if err := c.UpdateLogicalSwitchPort(lsp, &lsp.Addresses, &lsp.Dhcpv4Options, &lsp.Dhcpv6Options, &lsp.PortSecurity, &lsp.ExternalIDs); err != nil { klog.Error(err) - return fmt.Errorf("failed to update logical switch port %s: %v", lspName, err) + return fmt.Errorf("failed to update logical switch port %s: %w", lspName, err) } return nil } @@ -114,11 +115,11 @@ func (c *OVNNbClient) CreateLogicalSwitchPort(lsName, lspName, ip, mac, podName, createLspOps, err := c.CreateLogicalSwitchPortOp(lsp, lsName) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating logical switch port %s: %v", lspName, err) + return fmt.Errorf("generate operations for creating logical switch port %s: %w", lspName, err) } if err = c.Transact("lsp-add", append(ops, createLspOps...)); err != nil { - return fmt.Errorf("create logical switch port %s: %v", lspName, err) + return fmt.Errorf("create logical switch port %s: %w", lspName, err) } return nil @@ -147,7 +148,7 @@ func (c *OVNNbClient) CreateLocalnetLogicalSwitchPort(lsName, lspName, provider, if !reflect.DeepEqual(lsp.ExternalIDs, externalIDs) { lsp.ExternalIDs = externalIDs if err = c.UpdateLogicalSwitchPort(lsp, &lsp.ExternalIDs); err != nil { - return fmt.Errorf("failed to update external-ids of logical switch port %s: %v", lspName, err) + return fmt.Errorf("failed to update external-ids of logical switch port %s: %w", lspName, err) } } @@ -177,7 +178,7 @@ func (c *OVNNbClient) CreateLocalnetLogicalSwitchPort(lsName, lspName, provider, } if err = c.Transact("lsp-add", ops); err != nil { - return fmt.Errorf("create localnet logical switch port %s: %v", lspName, err) + return fmt.Errorf("create localnet logical switch port %s: %w", lspName, err) } return nil @@ -220,7 +221,7 @@ func (c *OVNNbClient) CreateVirtualLogicalSwitchPorts(lsName string, ips ...stri } if err := c.Transact("lsp-add", ops); err != nil { - return fmt.Errorf("create virtual logical switch ports for logical switch %s: %v", lsName, err) + return fmt.Errorf("create virtual logical switch ports for logical switch %s: %w", lsName, err) } return nil @@ -255,7 +256,7 @@ func (c *OVNNbClient) CreateVirtualLogicalSwitchPort(lspName, lsName, ip string) } if err := c.Transact("lsp-add", op); err != nil { - return fmt.Errorf("create virtual logical switch port %s for logical switch %s: %v", lspName, lsName, err) + return fmt.Errorf("create virtual logical switch port %s for logical switch %s: %w", lspName, lsName, err) } return nil @@ -293,7 +294,7 @@ func (c *OVNNbClient) CreateBareLogicalSwitchPort(lsName, lspName, ip, mac strin } if err = c.Transact("lsp-add", ops); err != nil { - return fmt.Errorf("create logical switch port %s: %v", lspName, err) + return fmt.Errorf("create logical switch port %s: %w", lspName, err) } return nil @@ -308,7 +309,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortVirtualParents(lsName, parents string, lsp, err := c.GetLogicalSwitchPort(lspName, true) if err != nil { klog.Error(err) - return fmt.Errorf("get logical switch port %s: %v", lspName, err) + return fmt.Errorf("get logical switch port %s: %w", lspName, err) } lsp.Options["virtual-parents"] = parents @@ -326,7 +327,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortVirtualParents(lsName, parents string, } if err := c.Transact("lsp-update", ops); err != nil { - return fmt.Errorf("set logical switch port virtual-parents %v", err) + return fmt.Errorf("set logical switch port virtual-parents %w", err) } return nil } @@ -336,7 +337,7 @@ func (c *OVNNbClient) SetVirtualLogicalSwitchPortVirtualParents(lspName, parents lsp, err := c.GetLogicalSwitchPort(lspName, true) if err != nil { klog.Error(err) - return fmt.Errorf("get logical switch port %s: %v", lspName, err) + return fmt.Errorf("get logical switch port %s: %w", lspName, err) } lsp.Options["virtual-parents"] = parents @@ -351,7 +352,7 @@ func (c *OVNNbClient) SetVirtualLogicalSwitchPortVirtualParents(lspName, parents } if err := c.Transact("lsp-update", op); err != nil { - return fmt.Errorf("set logical switch port virtual-parents %v", err) + return fmt.Errorf("set logical switch port virtual-parents %w", err) } return nil } @@ -359,7 +360,7 @@ func (c *OVNNbClient) SetVirtualLogicalSwitchPortVirtualParents(lspName, parents func (c *OVNNbClient) SetLogicalSwitchPortArpProxy(lspName string, enableArpProxy bool) error { lsp, err := c.GetLogicalSwitchPort(lspName, false) if err != nil { - return fmt.Errorf("get logical switch port %s: %v", lspName, err) + return fmt.Errorf("get logical switch port %s: %w", lspName, err) } if lsp.Options == nil { lsp.Options = make(map[string]string) @@ -375,7 +376,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortArpProxy(lspName string, enableArpProx return err } if err := c.Transact("lsp-update", op); err != nil { - return fmt.Errorf("failed to set logical switch port option arp_proxy %v", err) + return fmt.Errorf("failed to set logical switch port option arp_proxy %w", err) } return nil } @@ -385,7 +386,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortSecurity(portSecurity bool, lspName, m lsp, err := c.GetLogicalSwitchPort(lspName, false) if err != nil { klog.Error(err) - return fmt.Errorf("get logical switch port %s: %v", lspName, err) + return fmt.Errorf("get logical switch port %s: %w", lspName, err) } lsp.PortSecurity = nil @@ -419,7 +420,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortSecurity(portSecurity bool, lspName, m } if err := c.UpdateLogicalSwitchPort(lsp, &lsp.PortSecurity, &lsp.ExternalIDs); err != nil { - return fmt.Errorf("set logical switch port %s port_security %v: %v", lspName, lsp.PortSecurity, err) + return fmt.Errorf("set logical switch port %s port_security %v: %w", lspName, lsp.PortSecurity, err) } return nil @@ -430,7 +431,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortExternalIDs(lspName string, externalID lsp, err := c.GetLogicalSwitchPort(lspName, false) if err != nil { klog.Error(err) - return fmt.Errorf("get logical switch port %s: %v", lspName, err) + return fmt.Errorf("get logical switch port %s: %w", lspName, err) } if lsp.ExternalIDs == nil { @@ -442,7 +443,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortExternalIDs(lspName string, externalID } if err := c.UpdateLogicalSwitchPort(lsp, &lsp.ExternalIDs); err != nil { - return fmt.Errorf("set logical switch port %s external ids %v: %v", lspName, externalIDs, err) + return fmt.Errorf("set logical switch port %s external ids %v: %w", lspName, externalIDs, err) } return nil @@ -456,7 +457,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortSecurityGroup(lsp *ovnnb.LogicalSwitch } if op != "add" && op != "remove" { - return nil, fmt.Errorf("op must be 'add' or 'remove'") + return nil, errors.New("op must be 'add' or 'remove'") } diffSgs := make([]string, 0, len(sgs)) @@ -489,7 +490,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortSecurityGroup(lsp *ovnnb.LogicalSwitch } if err := c.UpdateLogicalSwitchPort(lsp, &lsp.ExternalIDs); err != nil { - return nil, fmt.Errorf("set logical switch port %s security group %v: %v", lsp.Name, newSgs, err) + return nil, fmt.Errorf("set logical switch port %s security group %v: %w", lsp.Name, newSgs, err) } return diffSgs, nil } @@ -498,7 +499,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortSecurityGroup(lsp *ovnnb.LogicalSwitch // op is 'add' or 'remove' func (c *OVNNbClient) SetLogicalSwitchPortsSecurityGroup(sgName, op string) error { if op != "add" && op != "remove" { - return fmt.Errorf("op must be 'add' or 'remove'") + return errors.New("op must be 'add' or 'remove'") } /* list sg port */ @@ -512,13 +513,13 @@ func (c *OVNNbClient) SetLogicalSwitchPortsSecurityGroup(sgName, op string) erro lsps, err := c.ListNormalLogicalSwitchPorts(true, externalIDs) if err != nil { klog.Error(err) - return fmt.Errorf("list logical switch ports with external_ids %v: %v", externalIDs, err) + return fmt.Errorf("list logical switch ports with external_ids %v: %w", externalIDs, err) } /* add to or remove from sgs form port external_ids */ for _, lsp := range lsps { if _, err := c.SetLogicalSwitchPortSecurityGroup(&lsp, op, sgName); err != nil { - return fmt.Errorf("set logical switch port %s security group %s: %v", lsp.Name, sgName, err) + return fmt.Errorf("set logical switch port %s security group %s: %w", lsp.Name, sgName, err) } } @@ -530,7 +531,7 @@ func (c *OVNNbClient) EnablePortLayer2forward(lspName string) error { lsp, err := c.GetLogicalSwitchPort(lspName, false) if err != nil { klog.Error(err) - return fmt.Errorf("get logical switch port %s: %v", lspName, err) + return fmt.Errorf("get logical switch port %s: %w", lspName, err) } if slices.Contains(lsp.Addresses, "unknown") { @@ -539,7 +540,7 @@ func (c *OVNNbClient) EnablePortLayer2forward(lspName string) error { lsp.Addresses = append(lsp.Addresses, "unknown") if err := c.UpdateLogicalSwitchPort(lsp, &lsp.Addresses); err != nil { - return fmt.Errorf("set logical switch port %s addressed=unknown: %v", lspName, err) + return fmt.Errorf("set logical switch port %s addressed=unknown: %w", lspName, err) } return nil @@ -554,7 +555,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortVlanTag(lspName string, vlanID int) er lsp, err := c.GetLogicalSwitchPort(lspName, false) if err != nil { klog.Error(err) - return fmt.Errorf("get logical switch port %s: %v", lspName, err) + return fmt.Errorf("get logical switch port %s: %w", lspName, err) } // no need update vlan id when vlan id is the same @@ -568,7 +569,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortVlanTag(lspName string, vlanID int) er } if err := c.UpdateLogicalSwitchPort(lsp, &lsp.Tag); err != nil { - return fmt.Errorf("set logical switch port %s tag %d: %v", lspName, vlanID, err) + return fmt.Errorf("set logical switch port %s tag %d: %w", lspName, vlanID, err) } return nil @@ -577,7 +578,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortVlanTag(lspName string, vlanID int) er // UpdateLogicalSwitchPort update logical switch port func (c *OVNNbClient) UpdateLogicalSwitchPort(lsp *ovnnb.LogicalSwitchPort, fields ...interface{}) error { if lsp == nil { - err := fmt.Errorf("logical switch port is nil") + err := errors.New("logical switch port is nil") klog.Error(err) return err } @@ -585,12 +586,12 @@ func (c *OVNNbClient) UpdateLogicalSwitchPort(lsp *ovnnb.LogicalSwitchPort, fiel op, err := c.Where(lsp).Update(lsp, fields...) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for updating logical switch port %s: %v", lsp.Name, err) + return fmt.Errorf("generate operations for updating logical switch port %s: %w", lsp.Name, err) } if err = c.Transact("lsp-update", op); err != nil { klog.Error(err) - return fmt.Errorf("update logical switch port %s: %v", lsp.Name, err) + return fmt.Errorf("update logical switch port %s: %w", lsp.Name, err) } return nil @@ -625,7 +626,7 @@ func (c *OVNNbClient) DeleteLogicalSwitchPorts(externalIDs map[string]string, fi lspList, err := c.ListLogicalSwitchPorts(false, externalIDs, filter) if err != nil { klog.Error(err) - return fmt.Errorf("list switch ports: %v", err) + return fmt.Errorf("list switch ports: %w", err) } ops := make([]ovsdb.Operation, 0, len(lspList)) @@ -633,13 +634,13 @@ func (c *OVNNbClient) DeleteLogicalSwitchPorts(externalIDs map[string]string, fi op, err := c.DeleteLogicalSwitchPortOp(lsp.Name) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for deleting logical switch port %s: %v", lsp.Name, err) + return fmt.Errorf("generate operations for deleting logical switch port %s: %w", lsp.Name, err) } ops = append(ops, op...) } if err := c.Transact("lsps-del", ops); err != nil { - return fmt.Errorf("del logical switch ports: %v", err) + return fmt.Errorf("del logical switch ports: %w", err) } return nil @@ -651,10 +652,10 @@ func (c *OVNNbClient) GetLogicalSwitchPort(lspName string, ignoreNotFound bool) defer cancel() lsp := &ovnnb.LogicalSwitchPort{Name: lspName} if err := c.Get(ctx, lsp); err != nil { - if ignoreNotFound && err == client.ErrNotFound { + if ignoreNotFound && errors.Is(err, client.ErrNotFound) { return nil, nil } - return nil, fmt.Errorf("get logical switch port %s: %v", lspName, err) + return nil, fmt.Errorf("get logical switch port %s: %w", lspName, err) } return lsp, nil @@ -667,7 +668,7 @@ func (c *OVNNbClient) ListNormalLogicalSwitchPorts(needVendorFilter bool, extern }) if err != nil { klog.Error(err) - return nil, fmt.Errorf("list logical switch ports: %v", err) + return nil, fmt.Errorf("list logical switch ports: %w", err) } return lsps, nil @@ -682,7 +683,7 @@ func (c *OVNNbClient) ListLogicalSwitchPortsWithLegacyExternalIDs() ([]ovnnb.Log if err := c.WhereCache(func(lsp *ovnnb.LogicalSwitchPort) bool { return len(lsp.ExternalIDs) == 0 || lsp.ExternalIDs[logicalSwitchKey] == "" || lsp.ExternalIDs["vendor"] == "" }).List(ctx, &lspList); err != nil { - return nil, fmt.Errorf("failed to list logical switch ports with legacy external-ids: %v", err) + return nil, fmt.Errorf("failed to list logical switch ports with legacy external-ids: %w", err) } return lspList, nil @@ -696,7 +697,7 @@ func (c *OVNNbClient) ListLogicalSwitchPorts(needVendorFilter bool, externalIDs lspList := make([]ovnnb.LogicalSwitchPort, 0) if err := c.WhereCache(logicalSwitchPortFilter(needVendorFilter, externalIDs, filter)).List(ctx, &lspList); err != nil { - return nil, fmt.Errorf("list logical switch ports: %v", err) + return nil, fmt.Errorf("list logical switch ports: %w", err) } return lspList, nil @@ -710,7 +711,7 @@ func (c *OVNNbClient) LogicalSwitchPortExists(name string) (bool, error) { // CreateLogicalSwitchPortOp create operations which create logical switch port func (c *OVNNbClient) CreateLogicalSwitchPortOp(lsp *ovnnb.LogicalSwitchPort, lsName string) ([]ovsdb.Operation, error) { if lsp == nil { - return nil, fmt.Errorf("logical_switch_port is nil") + return nil, errors.New("logical_switch_port is nil") } if lsp.ExternalIDs == nil { @@ -726,7 +727,7 @@ func (c *OVNNbClient) CreateLogicalSwitchPortOp(lsp *ovnnb.LogicalSwitchPort, ls lspCreateOp, err := c.Create(lsp) if err != nil { klog.Error(err) - return nil, fmt.Errorf("generate operations for creating logical switch port %s: %v", lsp.Name, err) + return nil, fmt.Errorf("generate operations for creating logical switch port %s: %w", lsp.Name, err) } /* add logical switch port to logical switch*/ @@ -748,7 +749,7 @@ func (c *OVNNbClient) DeleteLogicalSwitchPortOp(lspName string) ([]ovsdb.Operati lsp, err := c.GetLogicalSwitchPort(lspName, true) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical switch port %s when generate delete operations: %v", lspName, err) + return nil, fmt.Errorf("get logical switch port %s when generate delete operations: %w", lspName, err) } // not found, skip @@ -772,7 +773,7 @@ func (c *OVNNbClient) DeleteLogicalSwitchPortOp(lspName string) ([]ovsdb.Operati klog.Infof("delete logical switch port %s with id %s from logical switch %s", lspName, lsp.UUID, lsName) ops, err := c.LogicalSwitchUpdatePortOp(lsName, lsp.UUID, ovsdb.MutateOperationDelete) if err != nil { - return nil, fmt.Errorf("generate operations for removing port %s from logical switch %s: %v", lspName, lsName, err) + return nil, fmt.Errorf("generate operations for removing port %s from logical switch %s: %w", lspName, lsName, err) } return ops, nil } @@ -786,7 +787,7 @@ func (c *OVNNbClient) UpdateLogicalSwitchPortOp(lsp *ovnnb.LogicalSwitchPort, fi op, err := c.Where(lsp).Update(lsp, fields...) if err != nil { - return nil, fmt.Errorf("generate operations for updating logical switch port %s: %v", lsp.Name, err) + return nil, fmt.Errorf("generate operations for updating logical switch port %s: %w", lsp.Name, err) } return op, nil @@ -840,6 +841,37 @@ func getLogicalSwitchPortSgs(lsp *ovnnb.LogicalSwitchPort) *strset.Set { return sgs } +// SetLogicalSwitchPortActivationStrategy sets activation-strategy to rarp for the logical switch port +func (c *OVNNbClient) SetLogicalSwitchPortActivationStrategy(lspName, chassis string) error { + lsp, err := c.GetLogicalSwitchPort(lspName, false) + if err != nil { + klog.Errorf("failed to get logical switch port %s: %v", lspName, err) + return err + } + + if lsp.Options != nil && lsp.Options["requested-chassis"] != "" { + delete(lsp.Options, "requested-chassis") + delete(lsp.Options, "activation-strategy") + if err = c.UpdateLogicalSwitchPort(lsp, &lsp.Options); err != nil { + klog.Errorf("failed to clear activation strategy for the logical switch port %s: %v", lspName, err) + return err + } + } + + requestedChassis := fmt.Sprintf("%s,%s", chassis, chassis) + if lsp.Options == nil { + lsp.Options = make(map[string]string, 2) + } + lsp.Options["requested-chassis"] = requestedChassis + lsp.Options["activation-strategy"] = "rarp" + if err = c.UpdateLogicalSwitchPort(lsp, &lsp.Options); err != nil { + klog.Errorf("failed to set activation strategy to rarp for the logical switch port %s: %v", lspName, err) + return err + } + + return nil +} + // SetLogicalSwitchPortMigrateOptions set logical switch port options of migrate func (c *OVNNbClient) SetLogicalSwitchPortMigrateOptions(lspName, srcNodeName, targetNodeName string) error { // to facilitate the migration of the VM: ovn-nbctl lsp-set-options migrator requested-chassis=src,target activation-strategy=rarp @@ -873,13 +905,13 @@ func (c *OVNNbClient) SetLogicalSwitchPortMigrateOptions(lspName, srcNodeName, t requestedChassis := fmt.Sprintf("%s,%s", srcNodeName, targetNodeName) if lsp.Options == nil { - lsp.Options = make(map[string]string) + lsp.Options = make(map[string]string, 2) } lsp.Options["requested-chassis"] = requestedChassis lsp.Options["activation-strategy"] = "rarp" klog.Infof("set migrator logical switch port %s options: %v", lspName, lsp.Options) if err := c.UpdateLogicalSwitchPort(lsp, &lsp.Options); err != nil { - err = fmt.Errorf("failed to set migrator logical switch port %s options requested chassis %s: %v", lspName, requestedChassis, err) + err = fmt.Errorf("failed to set migrator logical switch port %s options requested chassis %s: %w", lspName, requestedChassis, err) klog.Error(err) return err } @@ -890,7 +922,7 @@ func (c *OVNNbClient) SetLogicalSwitchPortMigrateOptions(lspName, srcNodeName, t func (c *OVNNbClient) GetLogicalSwitchPortMigrateOptions(lspName string) (*ovnnb.LogicalSwitchPort, string, string, error) { lsp, err := c.GetLogicalSwitchPort(lspName, false) if err != nil { - err = fmt.Errorf("failed to get migrator logical switch port %s: %v", lspName, err) + err = fmt.Errorf("failed to get migrator logical switch port %s: %w", lspName, err) klog.Error(err) return nil, "", "", err } @@ -911,7 +943,7 @@ func (c *OVNNbClient) GetLogicalSwitchPortMigrateOptions(lspName string) (*ovnnb func (c *OVNNbClient) ResetLogicalSwitchPortMigrateOptions(lspName, srcNodeName, targetNodeName string, migratedFail bool) error { lsp, err := c.GetLogicalSwitchPort(lspName, false) if err != nil { - err = fmt.Errorf("failed to get migrator logical switch port %s: %v", lspName, err) + err = fmt.Errorf("failed to get migrator logical switch port %s: %w", lspName, err) klog.Error(err) return err } @@ -933,7 +965,7 @@ func (c *OVNNbClient) ResetLogicalSwitchPortMigrateOptions(lspName, srcNodeName, } delete(lsp.Options, "activation-strategy") if err := c.UpdateLogicalSwitchPort(lsp, &lsp.Options); err != nil { - err = fmt.Errorf("failed to reset options for migrator logical switch port %s: %v", lspName, err) + err = fmt.Errorf("failed to reset options for migrator logical switch port %s: %w", lspName, err) klog.Error(err) return err } @@ -944,7 +976,7 @@ func (c *OVNNbClient) ResetLogicalSwitchPortMigrateOptions(lspName, srcNodeName, func (c *OVNNbClient) CleanLogicalSwitchPortMigrateOptions(lspName string) error { lsp, err := c.GetLogicalSwitchPort(lspName, true) if err != nil { - err = fmt.Errorf("failed to get migrator logical switch port %s: %v", lspName, err) + err = fmt.Errorf("failed to get migrator logical switch port %s: %w", lspName, err) klog.Error(err) return err } @@ -962,7 +994,7 @@ func (c *OVNNbClient) CleanLogicalSwitchPortMigrateOptions(lspName string) error delete(lsp.Options, "requested-chassis") klog.Infof("cleaned migrator logical switch port %s options: %v", lspName, lsp.Options) if err := c.UpdateLogicalSwitchPort(lsp, &lsp.Options); err != nil { - err = fmt.Errorf("failed to clean options for migrator logical switch port %s: %v", lspName, err) + err = fmt.Errorf("failed to clean options for migrator logical switch port %s: %w", lspName, err) klog.Error(err) return err } diff --git a/pkg/ovs/ovn-nb-nat.go b/pkg/ovs/ovn-nb-nat.go index 967c1e6d0700..e82ce59162c4 100644 --- a/pkg/ovs/ovn-nb-nat.go +++ b/pkg/ovs/ovn-nb-nat.go @@ -64,13 +64,13 @@ func (c *OVNNbClient) CreateNats(lrName string, nats ...*ovnnb.NAT) error { createNatsOp, err := c.ovsDbClient.Create(models...) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for creating nats: %v", err) + return fmt.Errorf("generate operations for creating nats: %w", err) } natAddOp, err := c.LogicalRouterUpdateNatOp(lrName, natUUIDs, ovsdb.MutateOperationInsert) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for adding nats to logical router %s: %v", lrName, err) + return fmt.Errorf("generate operations for adding nats to logical router %s: %w", lrName, err) } ops := make([]ovsdb.Operation, 0, len(createNatsOp)+len(natAddOp)) @@ -78,7 +78,7 @@ func (c *OVNNbClient) CreateNats(lrName string, nats ...*ovnnb.NAT) error { ops = append(ops, natAddOp...) if err = c.Transact("lr-nats-add", ops); err != nil { - return fmt.Errorf("add nats to %s: %v", lrName, err) + return fmt.Errorf("add nats to %s: %w", lrName, err) } return nil @@ -103,12 +103,12 @@ func (c *OVNNbClient) UpdateSnat(lrName, externalIP, logicalIP string) error { /* create nat */ if nat, err = c.newNat(lrName, natType, externalIP, logicalIP, "", ""); err != nil { klog.Error(err) - return fmt.Errorf("new logical router %s nat 'type %s external ip %s logical ip %s': %v", lrName, natType, externalIP, logicalIP, err) + return fmt.Errorf("new logical router %s nat 'type %s external ip %s logical ip %s': %w", lrName, natType, externalIP, logicalIP, err) } if err := c.CreateNats(lrName, nat); err != nil { klog.Error(err) - return fmt.Errorf("add nat 'type %s external ip %s logical ip %s' to logical router %s: %v", natType, externalIP, logicalIP, lrName, err) + return fmt.Errorf("add nat 'type %s external ip %s logical ip %s' to logical router %s: %w", natType, externalIP, logicalIP, lrName, err) } return nil @@ -150,12 +150,12 @@ func (c *OVNNbClient) UpdateDnatAndSnat(lrName, externalIP, logicalIP, lspName, /* create nat */ if nat, err = c.newNat(lrName, natType, externalIP, logicalIP, "", "", options); err != nil { klog.Error(err) - return fmt.Errorf("new logical router %s nat 'type %s external ip %s logical ip %s logical port %s external mac %s': %v", lrName, natType, externalIP, logicalIP, lspName, externalMac, err) + return fmt.Errorf("new logical router %s nat 'type %s external ip %s logical ip %s logical port %s external mac %s': %w", lrName, natType, externalIP, logicalIP, lspName, externalMac, err) } if err := c.CreateNats(lrName, nat); err != nil { klog.Error(err) - return fmt.Errorf("add nat 'type %s external ip %s logical ip %s logical port %s external mac %s' to logical router %s: %v", natType, externalIP, logicalIP, lspName, externalMac, lrName, err) + return fmt.Errorf("add nat 'type %s external ip %s logical ip %s logical port %s external mac %s' to logical router %s: %w", natType, externalIP, logicalIP, lspName, externalMac, lrName, err) } return nil @@ -164,18 +164,18 @@ func (c *OVNNbClient) UpdateDnatAndSnat(lrName, externalIP, logicalIP, lspName, // UpdateNat update nat func (c *OVNNbClient) UpdateNat(nat *ovnnb.NAT, fields ...interface{}) error { if nat == nil { - return fmt.Errorf("nat is nil") + return errors.New("nat is nil") } op, err := c.ovsDbClient.Where(nat).Update(nat, fields...) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for updating nat 'type %s external ip %s logical ip %s': %v", nat.Type, nat.ExternalIP, nat.LogicalIP, err) + return fmt.Errorf("generate operations for updating nat 'type %s external ip %s logical ip %s': %w", nat.Type, nat.ExternalIP, nat.LogicalIP, err) } if err = c.Transact("net-update", op); err != nil { klog.Error(err) - return fmt.Errorf("update nat 'type %s external ip %s logical ip %s': %v", nat.Type, nat.ExternalIP, nat.LogicalIP, err) + return fmt.Errorf("update nat 'type %s external ip %s logical ip %s': %w", nat.Type, nat.ExternalIP, nat.LogicalIP, err) } return nil @@ -187,7 +187,7 @@ func (c *OVNNbClient) DeleteNats(lrName, natType, logicalIP string) error { nats, err := c.ListNats(lrName, natType, logicalIP, nil) if err != nil { klog.Error(err) - return fmt.Errorf("list logical router %s nats 'type %s logical ip %s': %v", lrName, natType, logicalIP, err) + return fmt.Errorf("list logical router %s nats 'type %s logical ip %s': %w", lrName, natType, logicalIP, err) } natsUUIDs := make([]string, 0, len(nats)) @@ -198,10 +198,10 @@ func (c *OVNNbClient) DeleteNats(lrName, natType, logicalIP string) error { ops, err := c.LogicalRouterUpdateNatOp(lrName, natsUUIDs, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for deleting nats from logical router %s: %v", lrName, err) + return fmt.Errorf("generate operations for deleting nats from logical router %s: %w", lrName, err) } if err = c.Transact("nats-del", ops); err != nil { - return fmt.Errorf("del nats from logical router %s: %v", lrName, err) + return fmt.Errorf("del nats from logical router %s: %w", lrName, err) } return nil @@ -219,10 +219,10 @@ func (c *OVNNbClient) DeleteNat(lrName, natType, externalIP, logicalIP string) e ops, err := c.LogicalRouterUpdateNatOp(lrName, []string{nat.UUID}, ovsdb.MutateOperationDelete) if err != nil { klog.Error(err) - return fmt.Errorf("generate operations for deleting nat from logical router %s: %v", lrName, err) + return fmt.Errorf("generate operations for deleting nat from logical router %s: %w", lrName, err) } if err = c.Transact("lr-nat-del", ops); err != nil { - return fmt.Errorf("del nat from logical router %s: %v", lrName, err) + return fmt.Errorf("del nat from logical router %s: %w", lrName, err) } return nil @@ -247,18 +247,18 @@ func (c *OVNNbClient) GetNATByUUID(uuid string) (*ovnnb.NAT, error) { func (c *OVNNbClient) GetNat(lrName, natType, externalIP, logicalIP string, ignoreNotFound bool) (*ovnnb.NAT, error) { // this is necessary because may exist same nat rule in different logical router if len(lrName) == 0 { - err := fmt.Errorf("the logical router name is required") + err := errors.New("the logical router name is required") klog.Error(err) return nil, err } if natType == ovnnb.NATTypeDNAT { - err := fmt.Errorf("does not support dnat for now") + err := errors.New("does not support dnat for now") klog.Error(err) return nil, err } if natType != ovnnb.NATTypeSNAT && natType != ovnnb.NATTypeDNATAndSNAT { - err := fmt.Errorf("nat type must one of [ snat, dnat_and_snat ]") + err := errors.New("nat type must one of [ snat, dnat_and_snat ]") klog.Error(err) return nil, err } @@ -290,7 +290,7 @@ func (c *OVNNbClient) GetNat(lrName, natType, externalIP, logicalIP string, igno natList, err := c.listLogicalRouterNatByFilter(lrName, fnFilter) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical router %s nat 'type %s external ip %s logical ip %s': %v", lrName, natType, externalIP, logicalIP, err) + return nil, fmt.Errorf("get logical router %s nat 'type %s external ip %s logical ip %s': %w", lrName, natType, externalIP, logicalIP, err) } // not found @@ -327,19 +327,19 @@ func (c *OVNNbClient) NatExists(lrName, natType, externalIP, logicalIP string) ( // a nat rule is uniquely identified by router(lrName), type(natType) and external_ip when dnat_and_snat func (c *OVNNbClient) newNat(lrName, natType, externalIP, logicalIP, logicalMac, port string, options ...func(nat *ovnnb.NAT)) (*ovnnb.NAT, error) { if len(lrName) == 0 { - err := fmt.Errorf("the logical router name is required") + err := errors.New("the logical router name is required") klog.Error(err) return nil, err } if natType == ovnnb.NATTypeDNAT { - err := fmt.Errorf("does not support dnat for now") + err := errors.New("does not support dnat for now") klog.Error(err) return nil, err } if natType != ovnnb.NATTypeSNAT && natType != ovnnb.NATTypeDNATAndSNAT { - err := fmt.Errorf("nat type must one of [ snat, dnat_and_snat ]") + err := errors.New("nat type must one of [ snat, dnat_and_snat ]") klog.Error(err) return nil, err } @@ -362,7 +362,7 @@ func (c *OVNNbClient) newNat(lrName, natType, externalIP, logicalIP, logicalMac, exists, err := c.NatExists(lrName, natType, externalIP, logicalIP) if err != nil { klog.Error(err) - return nil, fmt.Errorf("get logical router %s nat: %v", lrName, err) + return nil, fmt.Errorf("get logical router %s nat: %w", lrName, err) } // found, ignore diff --git a/pkg/ovs/ovn-nb-port_group.go b/pkg/ovs/ovn-nb-port_group.go index 73b1af6d60a6..b08af2456f9b 100644 --- a/pkg/ovs/ovn-nb-port_group.go +++ b/pkg/ovs/ovn-nb-port_group.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "github.com/ovn-org/libovsdb/client" @@ -20,7 +21,7 @@ func (c *OVNNbClient) CreatePortGroup(pgName string, externalIDs map[string]stri return err } - // ingnore + // ignore if exist { return nil } @@ -32,11 +33,11 @@ func (c *OVNNbClient) CreatePortGroup(pgName string, externalIDs map[string]stri ops, err := c.ovsDbClient.Create(pg) if err != nil { - return fmt.Errorf("generate operations for creating port group %s: %v", pgName, err) + return fmt.Errorf("generate operations for creating port group %s: %w", pgName, err) } if err = c.Transact("pg-add", ops); err != nil { - return fmt.Errorf("create port group %s: %v", pgName, err) + return fmt.Errorf("create port group %s: %w", pgName, err) } return nil @@ -54,12 +55,12 @@ func (c *OVNNbClient) PortGroupRemovePorts(pgName string, lspNames ...string) er func (c *OVNNbClient) PortGroupSetPorts(pgName string, ports []string) error { if pgName == "" { - return fmt.Errorf("port group name is empty") + return errors.New("port group name is empty") } pg, err := c.GetPortGroup(pgName, false) if err != nil { - return fmt.Errorf("get port group %s: %v", pgName, err) + return fmt.Errorf("get port group %s: %w", pgName, err) } expected := strset.NewWithSize(len(ports)) @@ -80,15 +81,15 @@ func (c *OVNNbClient) PortGroupSetPorts(pgName string, ports []string) error { insertOps, err := c.portGroupUpdatePortOp(pgName, toAdd, ovsdb.MutateOperationInsert) if err != nil { - return fmt.Errorf("failed generate operations for adding ports %v to port group %s: %v", toAdd, pgName, err) + return fmt.Errorf("failed generate operations for adding ports %v to port group %s: %w", toAdd, pgName, err) } deleteOps, err := c.portGroupUpdatePortOp(pgName, toDel, ovsdb.MutateOperationDelete) if err != nil { - return fmt.Errorf("failed generate operations for deleting ports %v from port group %s: %v", toDel, pgName, err) + return fmt.Errorf("failed generate operations for deleting ports %v from port group %s: %w", toDel, pgName, err) } if err = c.Transact("pg-ports-update", append(insertOps, deleteOps...)); err != nil { - return fmt.Errorf("port group %s set ports %v: %v", pgName, ports, err) + return fmt.Errorf("port group %s set ports %v: %w", pgName, ports, err) } return nil @@ -98,11 +99,11 @@ func (c *OVNNbClient) PortGroupSetPorts(pgName string, ports []string) error { func (c *OVNNbClient) UpdatePortGroup(pg *ovnnb.PortGroup, fields ...interface{}) error { op, err := c.Where(pg).Update(pg, fields...) if err != nil { - return fmt.Errorf("generate operations for updating port group %s: %v", pg.Name, err) + return fmt.Errorf("generate operations for updating port group %s: %w", pg.Name, err) } if err = c.Transact("pg-update", op); err != nil { - return fmt.Errorf("update port group %s: %v", pg.Name, err) + return fmt.Errorf("update port group %s: %w", pg.Name, err) } return nil @@ -131,11 +132,11 @@ func (c *OVNNbClient) PortGroupUpdatePorts(pgName string, op ovsdb.Mutator, lspN ops, err := c.portGroupUpdatePortOp(pgName, lspUUIDs, op) if err != nil { - return fmt.Errorf("generate operations for port group %s update ports %v: %v", pgName, lspNames, err) + return fmt.Errorf("generate operations for port group %s update ports %v: %w", pgName, lspNames, err) } if err := c.Transact("pg-ports-update", ops); err != nil { - return fmt.Errorf("port group %s update ports %v: %v", pgName, lspNames, err) + return fmt.Errorf("port group %s update ports %v: %w", pgName, lspNames, err) } return nil @@ -144,7 +145,7 @@ func (c *OVNNbClient) PortGroupUpdatePorts(pgName string, op ovsdb.Mutator, lspN func (c *OVNNbClient) DeletePortGroup(pgName string) error { pg, err := c.GetPortGroup(pgName, true) if err != nil { - return fmt.Errorf("get port group %s when delete: %v", pgName, err) + return fmt.Errorf("get port group %s when delete: %w", pgName, err) } // not found, skip @@ -159,7 +160,7 @@ func (c *OVNNbClient) DeletePortGroup(pgName string) error { } if err := c.Transact("pg-del", op); err != nil { - return fmt.Errorf("delete port group %s: %v", pgName, err) + return fmt.Errorf("delete port group %s: %w", pgName, err) } return nil @@ -172,10 +173,10 @@ func (c *OVNNbClient) GetPortGroup(pgName string, ignoreNotFound bool) (*ovnnb.P pg := &ovnnb.PortGroup{Name: pgName} if err := c.ovsDbClient.Get(ctx, pg); err != nil { - if ignoreNotFound && err == client.ErrNotFound { + if ignoreNotFound && errors.Is(err, client.ErrNotFound) { return nil, nil } - return nil, fmt.Errorf("get port group %s: %v", pgName, err) + return nil, fmt.Errorf("get port group %s: %w", pgName, err) } return pg, nil @@ -267,7 +268,7 @@ func (c *OVNNbClient) portGroupUpdateACLOp(pgName string, aclUUIDs []string, op func (c *OVNNbClient) portGroupOp(pgName string, mutationsFunc ...func(pg *ovnnb.PortGroup) *model.Mutation) ([]ovsdb.Operation, error) { pg, err := c.GetPortGroup(pgName, false) if err != nil { - return nil, fmt.Errorf("get port group %s: %v", pgName, err) + return nil, fmt.Errorf("get port group %s: %w", pgName, err) } if len(mutationsFunc) == 0 { @@ -286,7 +287,7 @@ func (c *OVNNbClient) portGroupOp(pgName string, mutationsFunc ...func(pg *ovnnb ops, err := c.ovsDbClient.Where(pg).Mutate(pg, mutations...) if err != nil { - return nil, fmt.Errorf("generate operations for mutating port group %s: %v", pgName, err) + return nil, fmt.Errorf("generate operations for mutating port group %s: %w", pgName, err) } return ops, nil diff --git a/pkg/ovs/ovn-nb.go b/pkg/ovs/ovn-nb.go index ec5b11ca826e..73bf284cfcb4 100644 --- a/pkg/ovs/ovn-nb.go +++ b/pkg/ovs/ovn-nb.go @@ -30,16 +30,16 @@ func (c *OVNNbClient) CreateGatewayLogicalSwitch(lsName, lrName, provider, ip, m // delete old localnet lsp when upgrade before v1.12 oldLocalnetLspName := fmt.Sprintf("ln-%s", lsName) if err := c.DeleteLogicalSwitchPort(oldLocalnetLspName); err != nil { - return fmt.Errorf("failed to delete old localnet %s: %v", oldLocalnetLspName, err) + return fmt.Errorf("failed to delete old localnet %s: %w", oldLocalnetLspName, err) } localnetLspName := GetLocalnetName(lsName) if err := c.CreateBareLogicalSwitch(lsName); err != nil { - return fmt.Errorf("create logical switch %s: %v", lsName, err) + return fmt.Errorf("create logical switch %s: %w", lsName, err) } if err := c.CreateLocalnetLogicalSwitchPort(lsName, localnetLspName, provider, "", vlanID); err != nil { - return fmt.Errorf("create localnet logical switch port %s: %v", localnetLspName, err) + return fmt.Errorf("create localnet logical switch port %s: %w", localnetLspName, err) } return c.CreateLogicalPatchPort(lsName, lrName, lspName, lrpName, ip, mac, chassises...) @@ -50,7 +50,7 @@ func (c *OVNNbClient) CreateLogicalPatchPort(lsName, lrName, lspName, lrpName, i if len(ip) != 0 { // check ip format: 192.168.231.1/24,fc00::0af4:01/112 if err := util.CheckCidrs(ip); err != nil { - err := fmt.Errorf("invalid ip %s: %v", ip, err) + err := fmt.Errorf("invalid ip %s: %w", ip, err) klog.Error(err) return err } @@ -62,20 +62,20 @@ func (c *OVNNbClient) CreateLogicalPatchPort(lsName, lrName, lspName, lrpName, i /* create router port */ ops, err := c.CreateRouterPortOp(lsName, lrName, lspName, lrpName, ip, mac) if err != nil { - err := fmt.Errorf("generate operations for creating patch port: %v", err) + err := fmt.Errorf("generate operations for creating patch port: %w", err) klog.Error(err) return err } if err = c.Transact("lrp-lsp-add", ops); err != nil { - err := fmt.Errorf("create logical patch port %s and %s: %v", lspName, lrpName, err) + err := fmt.Errorf("create logical patch port %s and %s: %w", lspName, lrpName, err) klog.Error(err) return err } /* create gateway chassises for logical router port */ if err := c.CreateGatewayChassises(lrpName, chassises...); err != nil { - err := fmt.Errorf("create gateway chassises for logical router port %s: %v", lrpName, err) + err := fmt.Errorf("create gateway chassises for logical router port %s: %w", lrpName, err) klog.Error(err) return err } @@ -89,12 +89,12 @@ func (c *OVNNbClient) DeleteLogicalGatewaySwitch(lsName, lrName string) error { // all corresponding logical switch port(e.g. localnet port and normal port) will be deleted when delete logical switch lsDelOp, err := c.DeleteLogicalSwitchOp(lsName) if err != nil { - return fmt.Errorf("generate operations for deleting gateway switch %s: %v", lsName, err) + return fmt.Errorf("generate operations for deleting gateway switch %s: %w", lsName, err) } lrpDelOp, err := c.DeleteLogicalRouterPortOp(lrpName) if err != nil { - return fmt.Errorf("generate operations for deleting gateway router port %s: %v", lrpName, err) + return fmt.Errorf("generate operations for deleting gateway router port %s: %w", lrpName, err) } ops := make([]ovsdb.Operation, 0, len(lsDelOp)+len(lrpDelOp)) @@ -102,7 +102,7 @@ func (c *OVNNbClient) DeleteLogicalGatewaySwitch(lsName, lrName string) error { ops = append(ops, lrpDelOp...) if err = c.Transact("gw-ls-del", ops); err != nil { - return fmt.Errorf("delete gateway switch %s: %v", lsName, err) + return fmt.Errorf("delete gateway switch %s: %w", lsName, err) } return nil @@ -113,7 +113,7 @@ func (c *OVNNbClient) DeleteSecurityGroup(sgName string) error { // clear acl if err := c.DeleteAcls(pgName, portGroupKey, "", nil); err != nil { - return fmt.Errorf("delete acls from port group %s: %v", pgName, err) + return fmt.Errorf("delete acls from port group %s: %w", pgName, err) } // clear address_set @@ -123,7 +123,7 @@ func (c *OVNNbClient) DeleteSecurityGroup(sgName string) error { if sgName == util.DefaultSecurityGroupName { if err := c.SetLogicalSwitchPortsSecurityGroup(sgName, "remove"); err != nil { - return fmt.Errorf("clear default security group %s from logical switch ports: %v", sgName, err) + return fmt.Errorf("clear default security group %s from logical switch ports: %w", sgName, err) } } @@ -198,7 +198,7 @@ func (c *OVNNbClient) RemoveLogicalPatchPort(lspName, lrpName string) error { ops = append(ops, lrpDelOp...) if err = c.Transact("lrp-lsp-del", ops); err != nil { - return fmt.Errorf("delete logical switch port %s and delete logical router port %s: %v", lspName, lrpName, err) + return fmt.Errorf("delete logical switch port %s and delete logical router port %s: %w", lspName, lrpName, err) } return nil diff --git a/pkg/ovs/ovn-nb_global.go b/pkg/ovs/ovn-nb_global.go index c7aae0beae34..6201c9982be2 100644 --- a/pkg/ovs/ovn-nb_global.go +++ b/pkg/ovs/ovn-nb_global.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "reflect" "strings" @@ -15,7 +16,7 @@ func (c *OVNNbClient) CreateNbGlobal(nbGlobal *ovnnb.NBGlobal) error { op, err := c.ovsDbClient.Create(nbGlobal) if err != nil { klog.Error(err) - return fmt.Errorf("failed to generate operations for creating nb global: %v", err) + return fmt.Errorf("failed to generate operations for creating nb global: %w", err) } return c.Transact("nb-global-create", op) @@ -49,11 +50,11 @@ func (c *OVNNbClient) GetNbGlobal() (*ovnnb.NBGlobal, error) { }).List(ctx, &nbGlobalList) if err != nil { klog.Error(err) - return nil, fmt.Errorf("failed to list NB_Global: %v", err) + return nil, fmt.Errorf("failed to list NB_Global: %w", err) } if len(nbGlobalList) == 0 { - return nil, fmt.Errorf("not found nb_global") + return nil, errors.New("not found nb_global") } return &nbGlobalList[0], nil @@ -63,12 +64,12 @@ func (c *OVNNbClient) UpdateNbGlobal(nbGlobal *ovnnb.NBGlobal, fields ...interfa op, err := c.Where(nbGlobal).Update(nbGlobal, fields...) if err != nil { klog.Error(err) - return fmt.Errorf("failed to generate operations for updating nb global: %v", err) + return fmt.Errorf("failed to generate operations for updating nb global: %w", err) } if err := c.Transact("nb-global-update", op); err != nil { klog.Error(err) - return fmt.Errorf("failed to update NB_Global: %v", err) + return fmt.Errorf("failed to update NB_Global: %w", err) } return nil @@ -78,7 +79,7 @@ func (c *OVNNbClient) SetAzName(azName string) error { nbGlobal, err := c.GetNbGlobal() if err != nil { klog.Error(err) - return fmt.Errorf("failed to get nb global: %v", err) + return fmt.Errorf("failed to get nb global: %w", err) } if azName == nbGlobal.Name { return nil // no need to update @@ -87,7 +88,7 @@ func (c *OVNNbClient) SetAzName(azName string) error { nbGlobal.Name = azName if err := c.UpdateNbGlobal(nbGlobal, &nbGlobal.Name); err != nil { klog.Error(err) - return fmt.Errorf("set nb_global az name %s: %v", azName, err) + return fmt.Errorf("set nb_global az name %s: %w", azName, err) } return nil @@ -97,7 +98,7 @@ func (c *OVNNbClient) SetNbGlobalOptions(key string, value interface{}) error { nbGlobal, err := c.GetNbGlobal() if err != nil { klog.Error(err) - return fmt.Errorf("failed to get nb global: %v", err) + return fmt.Errorf("failed to get nb global: %w", err) } v := fmt.Sprintf("%v", value) @@ -112,7 +113,7 @@ func (c *OVNNbClient) SetNbGlobalOptions(key string, value interface{}) error { if err := c.UpdateNbGlobal(nbGlobal, &nbGlobal.Options); err != nil { klog.Error(err) - return fmt.Errorf("failed to set nb global option %s to %v: %v", key, value, err) + return fmt.Errorf("failed to set nb global option %s to %v: %w", key, value, err) } return nil @@ -126,7 +127,7 @@ func (c *OVNNbClient) SetICAutoRoute(enable bool, blackList []string) error { nbGlobal, err := c.GetNbGlobal() if err != nil { klog.Error(err) - return fmt.Errorf("failed to get nb global: %v", err) + return fmt.Errorf("failed to get nb global: %w", err) } options := make(map[string]string, len(nbGlobal.Options)+3) @@ -150,7 +151,7 @@ func (c *OVNNbClient) SetICAutoRoute(enable bool, blackList []string) error { nbGlobal.Options = options if err := c.UpdateNbGlobal(nbGlobal, &nbGlobal.Options); err != nil { klog.Error(err) - return fmt.Errorf("failed to enable ovn-ic auto route, %v", err) + return fmt.Errorf("failed to enable ovn-ic auto route, %w", err) } return nil } @@ -175,7 +176,7 @@ func (c *OVNNbClient) SetNodeLocalDNSIP(nodeLocalDNSIP string) error { nbGlobal, err := c.GetNbGlobal() if err != nil { klog.Error(err) - return fmt.Errorf("failed to get nb global: %v", err) + return fmt.Errorf("failed to get nb global: %w", err) } options := make(map[string]string, len(nbGlobal.Options)) @@ -188,7 +189,7 @@ func (c *OVNNbClient) SetNodeLocalDNSIP(nodeLocalDNSIP string) error { nbGlobal.Options = options if err := c.UpdateNbGlobal(nbGlobal, &nbGlobal.Options); err != nil { klog.Error(err) - return fmt.Errorf("failed to remove NB_Global option node_local_dns_ip, %v", err) + return fmt.Errorf("failed to remove NB_Global option node_local_dns_ip, %w", err) } return nil diff --git a/pkg/ovs/ovn-nb_test.go b/pkg/ovs/ovn-nb_test.go index 6f55aafdb35c..3426afb1654a 100644 --- a/pkg/ovs/ovn-nb_test.go +++ b/pkg/ovs/ovn-nb_test.go @@ -175,7 +175,7 @@ func (suite *OvnClientTestSuite) testDeleteSecurityGroup() { }) require.NoError(t, err) - acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated) + acl, err := ovnClient.newACL(pgName, ovnnb.ACLDirectionToLport, priority, match, ovnnb.ACLActionAllowRelated, util.NetpolACLTier) require.NoError(t, err) err = ovnClient.CreateAcls(pgName, portGroupKey, acl) diff --git a/pkg/ovs/ovn-sb-chassis.go b/pkg/ovs/ovn-sb-chassis.go index dde299d4dd27..b7569f9853b1 100644 --- a/pkg/ovs/ovn-sb-chassis.go +++ b/pkg/ovs/ovn-sb-chassis.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "github.com/ovn-org/libovsdb/client" @@ -14,12 +15,12 @@ import ( func (c *OVNSbClient) UpdateChassis(chassis *ovnsb.Chassis, fields ...interface{}) error { op, err := c.ovsDbClient.Where(chassis).Update(chassis, fields...) if err != nil { - err := fmt.Errorf("failed to generate update operations for chassis: %v", err) + err := fmt.Errorf("failed to generate update operations for chassis: %w", err) klog.Error(err) return err } if err = c.Transact("chassis-update", op); err != nil { - err := fmt.Errorf("failed to update chassis %s: %v", chassis.Name, err) + err := fmt.Errorf("failed to update chassis %s: %w", chassis.Name, err) klog.Error(err) return err } @@ -38,10 +39,10 @@ func (c *OVNSbClient) DeleteChassis(chassisName string) error { } ops, err := c.ovsDbClient.Where(chassis).Delete() if err != nil { - return fmt.Errorf("failed to generate delete chassis operations for node %s: %v", chassis.Hostname, err) + return fmt.Errorf("failed to generate delete chassis operations for node %s: %w", chassis.Hostname, err) } if err = c.Transact("chassis-del", ops); err != nil { - return fmt.Errorf("failed to delete chassis for node %s: %v", chassis.Hostname, err) + return fmt.Errorf("failed to delete chassis for node %s: %w", chassis.Hostname, err) } return nil } @@ -51,16 +52,16 @@ func (c *OVNSbClient) GetChassis(chassisName string, ignoreNotFound bool) (*ovns ctx, cancel := context.WithTimeout(context.Background(), c.Timeout) defer cancel() if chassisName == "" { - err := fmt.Errorf("chassis name is empty") + err := errors.New("chassis name is empty") klog.Error(err) return nil, err } chassis := &ovnsb.Chassis{Name: chassisName} if err := c.ovsDbClient.Get(ctx, chassis); err != nil { - if ignoreNotFound && err == client.ErrNotFound { + if ignoreNotFound && errors.Is(err, client.ErrNotFound) { return nil, nil } - return nil, fmt.Errorf("failed to get chassis %s: %v", chassisName, err) + return nil, fmt.Errorf("failed to get chassis %s: %w", chassisName, err) } klog.V(3).Infof("get chassis: %+v", chassis) return chassis, nil @@ -73,7 +74,7 @@ func (c *OVNSbClient) ListChassis() (*[]ovnsb.Chassis, error) { css := []ovnsb.Chassis{} if err := c.ovsDbClient.List(ctx, &css); err != nil { - return nil, fmt.Errorf("failed to list Chassis: %v", err) + return nil, fmt.Errorf("failed to list Chassis: %w", err) } return &css, nil } @@ -86,7 +87,7 @@ func (c *OVNSbClient) GetAllChassisByHost(nodeName string) (*[]ovnsb.Chassis, er if err := c.ovsDbClient.WhereCache(func(chassis *ovnsb.Chassis) bool { return chassis.Hostname == nodeName }).List(ctx, &chassisList); err != nil { - return nil, fmt.Errorf("failed to list Chassis with host name=%s: %v", nodeName, err) + return nil, fmt.Errorf("failed to list Chassis with host name=%s: %w", nodeName, err) } if len(chassisList) == 0 { err := fmt.Errorf("failed to get Chassis with with host name=%s", nodeName) @@ -109,7 +110,7 @@ func (c *OVNSbClient) GetChassisByHost(nodeName string) (*ovnsb.Chassis, error) if err := c.ovsDbClient.WhereCache(func(chassis *ovnsb.Chassis) bool { return chassis.Hostname == nodeName }).List(ctx, &chassisList); err != nil { - return nil, fmt.Errorf("failed to list Chassis with host name=%s: %v", nodeName, err) + return nil, fmt.Errorf("failed to list Chassis with host name=%s: %w", nodeName, err) } if len(chassisList) == 0 { err := fmt.Errorf("failed to get Chassis with with host name=%s", nodeName) @@ -135,13 +136,13 @@ func (c *OVNSbClient) DeleteChassisByHost(nodeName string) error { if err := c.ovsDbClient.WhereCache(func(chassis *ovnsb.Chassis) bool { return chassis.Hostname == nodeName || (chassis.ExternalIDs != nil && chassis.ExternalIDs["node"] == nodeName) }).List(ctx, &chassisList); err != nil { - return fmt.Errorf("failed to list Chassis with host name=%s: %v", nodeName, err) + return fmt.Errorf("failed to list Chassis with host name=%s: %w", nodeName, err) } for _, chassis := range chassisList { klog.Infof("delete chassis: %+v", chassis) if err := c.DeleteChassis(chassis.Name); err != nil { - err := fmt.Errorf("failed to delete chassis %s, %v", chassis.Name, err) + err := fmt.Errorf("failed to delete chassis %s, %w", chassis.Name, err) klog.Error(err) return err } @@ -156,7 +157,7 @@ func (c *OVNSbClient) UpdateChassisTag(chassisName, nodeName string) error { return err } if chassis == nil { - err := fmt.Errorf("faile to get chassis by name=%s", chassisName) + err := fmt.Errorf("fail to get chassis by name=%s", chassisName) // restart kube-ovn-cni, chassis will be created klog.Error(err) return err @@ -171,7 +172,7 @@ func (c *OVNSbClient) UpdateChassisTag(chassisName, nodeName string) error { // not need filter chassis by node name if we use libovsdb chassis.ExternalIDs = externalIDs if err := c.UpdateChassis(chassis, &chassis.ExternalIDs); err != nil { - return fmt.Errorf("failed to init chassis node %s: %v", nodeName, err) + return fmt.Errorf("failed to init chassis node %s: %w", nodeName, err) } } return nil @@ -189,7 +190,7 @@ func (c *OVNSbClient) GetKubeOvnChassisses() (*[]ovnsb.Chassis, error) { } return false }).List(ctx, &chassisList); err != nil { - return nil, fmt.Errorf("failed to list Chassis with vendor=%s: %v", util.CniTypeName, err) + return nil, fmt.Errorf("failed to list Chassis with vendor=%s: %w", util.CniTypeName, err) } return &chassisList, nil } diff --git a/pkg/ovs/ovn.go b/pkg/ovs/ovn.go index 0dda7a70bb5e..fd6e209e64f9 100644 --- a/pkg/ovs/ovn.go +++ b/pkg/ovs/ovn.go @@ -2,7 +2,7 @@ package ovs import ( "context" - "fmt" + "errors" "reflect" "time" @@ -229,7 +229,7 @@ func (c *ovsDbClient) GetEntityInfo(entity interface{}) error { entityPtr := reflect.ValueOf(entity) if entityPtr.Kind() != reflect.Pointer { - return fmt.Errorf("entity must be pointer") + return errors.New("entity must be pointer") } err := c.Get(ctx, entity) diff --git a/pkg/ovs/ovs-vsctl.go b/pkg/ovs/ovs-vsctl.go index a5ff137add5e..3ebcd2ba16df 100644 --- a/pkg/ovs/ovs-vsctl.go +++ b/pkg/ovs/ovs-vsctl.go @@ -73,7 +73,7 @@ func Exec(args ...string) (string, error) { if err != nil { code = "1" klog.Warningf("ovs-vsctl command error: %s %s in %vms", OvsVsCtl, strings.Join(args, " "), elapsed) - return "", fmt.Errorf("failed to run '%s %s': %v\n %q", OvsVsCtl, strings.Join(args, " "), err, output) + return "", fmt.Errorf("failed to run '%s %s': %w\n %q", OvsVsCtl, strings.Join(args, " "), err, output) } else if elapsed > 500 { klog.Warningf("ovs-vsctl command took too long: %s %s in %vms", OvsVsCtl, strings.Join(args, " "), elapsed) } @@ -332,7 +332,7 @@ func ConfigInterfaceMirror(globalMirror bool, open, iface string) error { return err } if len(portUUIDs) != 1 { - return fmt.Errorf(fmt.Sprintf("find port failed, portName=%s", ifName)) + return fmt.Errorf("find port failed, portName=%s", ifName) } portID := portUUIDs[0] if open == "true" { @@ -349,10 +349,10 @@ func ConfigInterfaceMirror(globalMirror bool, open, iface string) error { return err } if len(mirrorPorts) == 0 { - return fmt.Errorf("find mirror failed, mirror name=" + util.MirrorDefaultName) + return fmt.Errorf("find mirror failed, mirror name=%s", util.MirrorDefaultName) } if len(mirrorPorts) > 1 { - return fmt.Errorf("repeated mirror data, mirror name=" + util.MirrorDefaultName) + return fmt.Errorf("repeated mirror data, mirror name=%s", util.MirrorDefaultName) } for _, mirrorPortIDs := range mirrorPorts { if strings.Contains(mirrorPortIDs, portID) { diff --git a/pkg/ovs/ovs-vsctl_linux.go b/pkg/ovs/ovs-vsctl_linux.go index cebf91d20836..be4e76a262e3 100644 --- a/pkg/ovs/ovs-vsctl_linux.go +++ b/pkg/ovs/ovs-vsctl_linux.go @@ -71,7 +71,7 @@ func SetInterfaceBandwidth(podName, podNamespace, iface, ingress, egress string) } if _, err := Exec("remove", "queue", queueID, "other_config", "max-rate"); err != nil { - return fmt.Errorf("failed to remove rate limit for queue in pod %v/%v, %v", podNamespace, podName, err) + return fmt.Errorf("failed to remove rate limit for queue in pod %v/%v, %w", podNamespace, podName, err) } } } diff --git a/pkg/ovs/util.go b/pkg/ovs/util.go index 00d52e35e539..15f21ab18618 100644 --- a/pkg/ovs/util.go +++ b/pkg/ovs/util.go @@ -2,6 +2,7 @@ package ovs import ( "context" + "errors" "fmt" "regexp" "strings" @@ -146,7 +147,7 @@ func (m AndACLMatch) Match() (string, error) { for _, r := range m.matches { match, err := r.Match() if err != nil { - return "", fmt.Errorf("generate match %s: %v", match, err) + return "", fmt.Errorf("generate match %s: %w", match, err) } matches = append(matches, match) } @@ -175,7 +176,7 @@ func (m OrACLMatch) Match() (string, error) { for _, specification := range m.matches { match, err := specification.Match() if err != nil { - return "", fmt.Errorf("generate match %s: %v", match, err) + return "", fmt.Errorf("generate match %s: %w", match, err) } // has more then one rule @@ -219,7 +220,7 @@ func NewACLMatch(key, effect, value, maxValue string) ACLMatch { func (m aclMatch) Match() (string, error) { // key must exist at least if len(m.key) == 0 { - return "", fmt.Errorf("acl rule key is required") + return "", errors.New("acl rule key is required") } // like 'ip' @@ -262,7 +263,7 @@ func (l *Limiter) Wait(ctx context.Context) error { for { select { case <-ctx.Done(): - return fmt.Errorf("context canceled by timeout") + return errors.New("context canceled by timeout") default: if l.limit == 0 { atomic.AddInt32(&l.current, 1) diff --git a/pkg/ovsdb/client/client.go b/pkg/ovsdb/client/client.go index 008bc6764228..bd493ab1e944 100644 --- a/pkg/ovsdb/client/client.go +++ b/pkg/ovsdb/client/client.go @@ -75,12 +75,12 @@ func NewOvsDbClient( cert, err := tls.LoadX509KeyPair("/var/run/tls/cert", "/var/run/tls/key") if err != nil { klog.Error(err) - return nil, fmt.Errorf("failed to load x509 cert key pair: %v", err) + return nil, fmt.Errorf("failed to load x509 cert key pair: %w", err) } caCert, err := os.ReadFile("/var/run/tls/cacert") if err != nil { klog.Error(err) - return nil, fmt.Errorf("failed to read ca cert: %v", err) + return nil, fmt.Errorf("failed to read ca cert: %w", err) } certPool := x509.NewCertPool() certPool.AppendCertsFromPEM(caCert) diff --git a/pkg/ovsdb/ovnnb/acl.go b/pkg/ovsdb/ovnnb/acl.go index 86cb2fee096f..869e9410de8d 100644 --- a/pkg/ovsdb/ovnnb/acl.go +++ b/pkg/ovsdb/ovnnb/acl.go @@ -16,8 +16,8 @@ var ( ACLActionAllowRelated ACLAction = "allow-related" ACLActionAllowStateless ACLAction = "allow-stateless" ACLActionDrop ACLAction = "drop" - ACLActionReject ACLAction = "reject" ACLActionPass ACLAction = "pass" + ACLActionReject ACLAction = "reject" ACLDirectionFromLport ACLDirection = "from-lport" ACLDirectionToLport ACLDirection = "to-lport" ACLSeverityAlert ACLSeverity = "alert" diff --git a/pkg/pinger/metrics.go b/pkg/pinger/metrics.go index eef0fe1be6f8..da36519a389a 100644 --- a/pkg/pinger/metrics.go +++ b/pkg/pinger/metrics.go @@ -1,6 +1,9 @@ package pinger -import "github.com/prometheus/client_golang/prometheus" +import ( + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) var ( ovsUpGauge = prometheus.NewGaugeVec( @@ -639,73 +642,73 @@ var ( ) func InitPingerMetrics() { - prometheus.MustRegister(ovsUpGauge) - prometheus.MustRegister(ovsDownGauge) - prometheus.MustRegister(ovnControllerUpGauge) - prometheus.MustRegister(ovnControllerDownGauge) - prometheus.MustRegister(inconsistentPortBindingGauge) - prometheus.MustRegister(apiserverHealthyGauge) - prometheus.MustRegister(apiserverUnhealthyGauge) - prometheus.MustRegister(apiserverRequestLatencyHistogram) - prometheus.MustRegister(internalDNSHealthyGauge) - prometheus.MustRegister(internalDNSUnhealthyGauge) - prometheus.MustRegister(internalDNSRequestLatencyHistogram) - prometheus.MustRegister(externalDNSHealthyGauge) - prometheus.MustRegister(externalDNSUnhealthyGauge) - prometheus.MustRegister(externalDNSRequestLatencyHistogram) - prometheus.MustRegister(podPingLatencyHistogram) - prometheus.MustRegister(podPingLostCounter) - prometheus.MustRegister(podPingTotalCounter) - prometheus.MustRegister(nodePingLatencyHistogram) - prometheus.MustRegister(nodePingLostCounter) - prometheus.MustRegister(nodePingTotalCounter) - prometheus.MustRegister(externalPingLatencyHistogram) - prometheus.MustRegister(externalPingLostCounter) + metrics.Registry.MustRegister(ovsUpGauge) + metrics.Registry.MustRegister(ovsDownGauge) + metrics.Registry.MustRegister(ovnControllerUpGauge) + metrics.Registry.MustRegister(ovnControllerDownGauge) + metrics.Registry.MustRegister(inconsistentPortBindingGauge) + metrics.Registry.MustRegister(apiserverHealthyGauge) + metrics.Registry.MustRegister(apiserverUnhealthyGauge) + metrics.Registry.MustRegister(apiserverRequestLatencyHistogram) + metrics.Registry.MustRegister(internalDNSHealthyGauge) + metrics.Registry.MustRegister(internalDNSUnhealthyGauge) + metrics.Registry.MustRegister(internalDNSRequestLatencyHistogram) + metrics.Registry.MustRegister(externalDNSHealthyGauge) + metrics.Registry.MustRegister(externalDNSUnhealthyGauge) + metrics.Registry.MustRegister(externalDNSRequestLatencyHistogram) + metrics.Registry.MustRegister(podPingLatencyHistogram) + metrics.Registry.MustRegister(podPingLostCounter) + metrics.Registry.MustRegister(podPingTotalCounter) + metrics.Registry.MustRegister(nodePingLatencyHistogram) + metrics.Registry.MustRegister(nodePingLostCounter) + metrics.Registry.MustRegister(nodePingTotalCounter) + metrics.Registry.MustRegister(externalPingLatencyHistogram) + metrics.Registry.MustRegister(externalPingLostCounter) // ovs status metrics - prometheus.MustRegister(metricOvsHealthyStatus) - prometheus.MustRegister(metricOvsInfo) - prometheus.MustRegister(metricRequestErrorNums) - prometheus.MustRegister(metricLogFileSize) - prometheus.MustRegister(metricDbFileSize) + metrics.Registry.MustRegister(metricOvsHealthyStatus) + metrics.Registry.MustRegister(metricOvsInfo) + metrics.Registry.MustRegister(metricRequestErrorNums) + metrics.Registry.MustRegister(metricLogFileSize) + metrics.Registry.MustRegister(metricDbFileSize) // ovs datapath metrics - prometheus.MustRegister(metricOvsDp) - prometheus.MustRegister(metricOvsDpTotal) - prometheus.MustRegister(metricOvsDpIf) - prometheus.MustRegister(metricOvsDpIfTotal) - prometheus.MustRegister(metricOvsDpFlowsTotal) - prometheus.MustRegister(metricOvsDpFlowsLookupHit) - prometheus.MustRegister(metricOvsDpFlowsLookupMissed) - prometheus.MustRegister(metricOvsDpFlowsLookupLost) - prometheus.MustRegister(metricOvsDpMasksHit) - prometheus.MustRegister(metricOvsDpMasksTotal) - prometheus.MustRegister(metricOvsDpMasksHitRatio) + metrics.Registry.MustRegister(metricOvsDp) + metrics.Registry.MustRegister(metricOvsDpTotal) + metrics.Registry.MustRegister(metricOvsDpIf) + metrics.Registry.MustRegister(metricOvsDpIfTotal) + metrics.Registry.MustRegister(metricOvsDpFlowsTotal) + metrics.Registry.MustRegister(metricOvsDpFlowsLookupHit) + metrics.Registry.MustRegister(metricOvsDpFlowsLookupMissed) + metrics.Registry.MustRegister(metricOvsDpFlowsLookupLost) + metrics.Registry.MustRegister(metricOvsDpMasksHit) + metrics.Registry.MustRegister(metricOvsDpMasksTotal) + metrics.Registry.MustRegister(metricOvsDpMasksHitRatio) // ovs Interface basic info metrics - prometheus.MustRegister(interfaceMain) - prometheus.MustRegister(interfaceAdminState) - prometheus.MustRegister(interfaceLinkState) - prometheus.MustRegister(interfaceMacInUse) - prometheus.MustRegister(interfaceMtu) - prometheus.MustRegister(interfaceOfPort) - prometheus.MustRegister(interfaceIfIndex) + metrics.Registry.MustRegister(interfaceMain) + metrics.Registry.MustRegister(interfaceAdminState) + metrics.Registry.MustRegister(interfaceLinkState) + metrics.Registry.MustRegister(interfaceMacInUse) + metrics.Registry.MustRegister(interfaceMtu) + metrics.Registry.MustRegister(interfaceOfPort) + metrics.Registry.MustRegister(interfaceIfIndex) // ovs Interface statistics metrics - prometheus.MustRegister(interfaceStatTxPackets) - prometheus.MustRegister(interfaceStatTxBytes) - prometheus.MustRegister(interfaceStatRxPackets) - prometheus.MustRegister(interfaceStatRxBytes) - prometheus.MustRegister(interfaceStatRxCrcError) - prometheus.MustRegister(interfaceStatRxDropped) - prometheus.MustRegister(interfaceStatRxErrorsTotal) - prometheus.MustRegister(interfaceStatRxFrameError) - prometheus.MustRegister(interfaceStatRxMissedError) - prometheus.MustRegister(interfaceStatRxOverrunError) - prometheus.MustRegister(interfaceStatTxDropped) - prometheus.MustRegister(interfaceStatTxErrorsTotal) - prometheus.MustRegister(interfaceStatCollisions) - prometheus.MustRegister(interfaceStatRxMulticastPackets) + metrics.Registry.MustRegister(interfaceStatTxPackets) + metrics.Registry.MustRegister(interfaceStatTxBytes) + metrics.Registry.MustRegister(interfaceStatRxPackets) + metrics.Registry.MustRegister(interfaceStatRxBytes) + metrics.Registry.MustRegister(interfaceStatRxCrcError) + metrics.Registry.MustRegister(interfaceStatRxDropped) + metrics.Registry.MustRegister(interfaceStatRxErrorsTotal) + metrics.Registry.MustRegister(interfaceStatRxFrameError) + metrics.Registry.MustRegister(interfaceStatRxMissedError) + metrics.Registry.MustRegister(interfaceStatRxOverrunError) + metrics.Registry.MustRegister(interfaceStatTxDropped) + metrics.Registry.MustRegister(interfaceStatTxErrorsTotal) + metrics.Registry.MustRegister(interfaceStatCollisions) + metrics.Registry.MustRegister(interfaceStatRxMulticastPackets) } func SetOvsUpMetrics(nodeName string) { diff --git a/pkg/pinger/ovn.go b/pkg/pinger/ovn.go index 94eebc2bef5c..d6958e571a24 100644 --- a/pkg/pinger/ovn.go +++ b/pkg/pinger/ovn.go @@ -177,7 +177,7 @@ func getLogicalPort(chassis string) ([]string, error) { } output, err := exec.Command("ovsdb-client", command...).CombinedOutput() // #nosec G204 if err != nil { - return nil, fmt.Errorf("Failed to query OVSDB: %v, %s", err, output) + return nil, fmt.Errorf("Failed to query OVSDB: %w, %s", err, output) } // Parse the JSON output. diff --git a/pkg/pinger/ping.go b/pkg/pinger/ping.go index eee78ba3805d..d423c727e8b5 100644 --- a/pkg/pinger/ping.go +++ b/pkg/pinger/ping.go @@ -2,6 +2,7 @@ package pinger import ( "context" + "errors" "fmt" "math" "net" @@ -20,10 +21,14 @@ import ( "github.com/kubeovn/kube-ovn/pkg/util" ) -func StartPinger(config *Configuration) { +func StartPinger(config *Configuration, stopCh <-chan struct{}) { errHappens := false var exporter *Exporter withMetrics := config.Mode == "server" && config.EnableMetrics + internval := time.Duration(config.Interval) * time.Second + timer := time.NewTimer(internval) + timer.Stop() +LOOP: for { if config.NetworkMode == "kube-ovn" { if checkOvs(config, withMetrics) != nil { @@ -48,8 +53,15 @@ func StartPinger(config *Configuration) { if config.Mode != "server" { break } - time.Sleep(time.Duration(config.Interval) * time.Second) + + timer.Reset(internval) + select { + case <-stopCh: + break LOOP + case <-timer.C: + } } + timer.Stop() if errHappens && config.ExitCode != 0 { os.Exit(config.ExitCode) } @@ -88,7 +100,7 @@ func ping(config *Configuration, withMetrics bool) error { } } if errHappens { - return fmt.Errorf("ping failed") + return errors.New("ping failed") } return nil } @@ -107,13 +119,13 @@ func pingNodes(config *Configuration, setMetrics bool) error { if addr.Type == v1.NodeInternalIP && slices.Contains(config.PodProtocols, util.CheckProtocol(addr.Address)) { func(nodeIP, nodeName string) { if config.EnableVerboseConnCheck { - if err := util.TCPConnectivityCheck(fmt.Sprintf("%s:%d", nodeIP, config.TCPConnCheckPort)); err != nil { + if err := util.TCPConnectivityCheck(util.JoinHostPort(nodeIP, config.TCPConnCheckPort)); err != nil { klog.Infof("TCP connectivity to node %s %s failed", nodeName, nodeIP) pingErr = err } else { klog.Infof("TCP connectivity to node %s %s success", nodeName, nodeIP) } - if err := util.UDPConnectivityCheck(fmt.Sprintf("%s:%d", nodeIP, config.UDPConnCheckPort)); err != nil { + if err := util.UDPConnectivityCheck(util.JoinHostPort(nodeIP, config.UDPConnCheckPort)); err != nil { klog.Infof("UDP connectivity to node %s %s failed", nodeName, nodeIP) pingErr = err } else { @@ -142,7 +154,7 @@ func pingNodes(config *Configuration, setMetrics bool) error { klog.Infof("ping node: %s %s, count: %d, loss count %d, average rtt %.2fms", nodeName, nodeIP, pinger.Count, int(math.Abs(float64(stats.PacketsSent-stats.PacketsRecv))), float64(stats.AvgRtt)/float64(time.Millisecond)) if int(math.Abs(float64(stats.PacketsSent-stats.PacketsRecv))) != 0 { - pingErr = fmt.Errorf("ping failed") + pingErr = errors.New("ping failed") } if setMetrics { SetNodePingMetrics( @@ -180,14 +192,14 @@ func pingPods(config *Configuration, setMetrics bool) error { if slices.Contains(config.PodProtocols, util.CheckProtocol(podIP.IP)) { func(podIP, podName, nodeIP, nodeName string) { if config.EnableVerboseConnCheck { - if err := util.TCPConnectivityCheck(fmt.Sprintf("%s:%d", podIP, config.TCPConnCheckPort)); err != nil { + if err := util.TCPConnectivityCheck(util.JoinHostPort(podIP, config.TCPConnCheckPort)); err != nil { klog.Infof("TCP connectivity to pod %s %s failed", podName, podIP) pingErr = err } else { klog.Infof("TCP connectivity to pod %s %s success", podName, podIP) } - if err := util.UDPConnectivityCheck(fmt.Sprintf("%s:%d", podIP, config.UDPConnCheckPort)); err != nil { + if err := util.UDPConnectivityCheck(util.JoinHostPort(podIP, config.UDPConnCheckPort)); err != nil { klog.Infof("UDP connectivity to pod %s %s failed", podName, podIP) pingErr = err } else { @@ -216,7 +228,7 @@ func pingPods(config *Configuration, setMetrics bool) error { klog.Infof("ping pod: %s %s, count: %d, loss count %d, average rtt %.2fms", podName, podIP, pinger.Count, int(math.Abs(float64(stats.PacketsSent-stats.PacketsRecv))), float64(stats.AvgRtt)/float64(time.Millisecond)) if int(math.Abs(float64(stats.PacketsSent-stats.PacketsRecv))) != 0 { - pingErr = fmt.Errorf("ping failed") + pingErr = errors.New("ping failed") } if setMetrics { SetPodPingMetrics( @@ -276,7 +288,7 @@ func pingExternal(config *Configuration, setMetrics bool) error { int(math.Abs(float64(stats.PacketsSent-stats.PacketsRecv)))) } if int(math.Abs(float64(stats.PacketsSent-stats.PacketsRecv))) != 0 { - return fmt.Errorf("ping failed") + return errors.New("ping failed") } } diff --git a/pkg/pinger/util.go b/pkg/pinger/util.go index d38ae4c651f3..748928fabaca 100644 --- a/pkg/pinger/util.go +++ b/pkg/pinger/util.go @@ -44,7 +44,7 @@ func (e *Exporter) getOvsDatapath() ([]string, error) { cmd := exec.Command("sh", "-c", cmdstr) // #nosec G204 output, err := cmd.CombinedOutput() if err != nil { - return nil, fmt.Errorf("failed to get output of dpctl/dump-dps: %v", err) + return nil, fmt.Errorf("failed to get output of dpctl/dump-dps: %w", err) } for _, kvPair := range strings.Split(string(output), "\n") { @@ -70,7 +70,7 @@ func (e *Exporter) setOvsDpIfMetric(datapathName string) error { cmd := exec.Command("sh", "-c", cmdstr) // #nosec G204 output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("failed to get output of dpctl/show %s: %v", datapathName, err) + return fmt.Errorf("failed to get output of dpctl/show %s: %w", datapathName, err) } var datapathPortCount float64 diff --git a/pkg/request/cniserver.go b/pkg/request/cniserver.go index 75431dba6d1b..d605f6b010fd 100644 --- a/pkg/request/cniserver.go +++ b/pkg/request/cniserver.go @@ -2,6 +2,7 @@ package request import ( "fmt" + "net/http" "github.com/containernetworking/cni/pkg/types" "github.com/parnurzeal/gorequest" @@ -60,7 +61,7 @@ func (csc CniServerClient) Add(podRequest CniRequest) (*CniResponse, error) { if len(errors) != 0 { return nil, errors[0] } - if res.StatusCode != 200 { + if res.StatusCode != http.StatusOK { return nil, fmt.Errorf("request ip return %d %s", res.StatusCode, resp.Err) } return &resp, nil @@ -72,7 +73,7 @@ func (csc CniServerClient) Del(podRequest CniRequest) error { if len(errors) != 0 { return errors[0] } - if res.StatusCode != 204 { + if res.StatusCode != http.StatusNoContent { return fmt.Errorf("delete ip return %d %s", res.StatusCode, body) } return nil diff --git a/pkg/server/server.go b/pkg/server/server.go new file mode 100644 index 000000000000..e30416939746 --- /dev/null +++ b/pkg/server/server.go @@ -0,0 +1,101 @@ +package server + +import ( + "fmt" + "net" + "net/http" + "os" + "strconv" + "strings" + + "k8s.io/apiserver/pkg/endpoints/filters" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/server" + "k8s.io/apiserver/pkg/server/options" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" + + "github.com/kubeovn/kube-ovn/pkg/client/clientset/versioned/scheme" +) + +func SecureServing(addr, svcName string, handler http.Handler) (<-chan struct{}, error) { + host, port, err := net.SplitHostPort(addr) + if err != nil { + klog.Error(err) + return nil, fmt.Errorf("invalid listen address %q: %w", addr, err) + } + + namespace := os.Getenv("POD_NAMESPACE") + podName := os.Getenv("POD_NAME") + podIPs := os.Getenv("POD_IPS") + alternateDNS := []string{podName, svcName, fmt.Sprintf("%s.%s", svcName, namespace), fmt.Sprintf("%s.%s.svc", svcName, namespace)} + alternateIPs := []net.IP{net.ParseIP("127.0.0.1"), net.IPv6loopback} + for _, podIP := range strings.Split(podIPs, ",") { + if ip := net.ParseIP(podIP); ip != nil { + alternateIPs = append(alternateIPs, ip) + } + } + + var clientConfig *rest.Config + opt := options.NewSecureServingOptions().WithLoopback() + authnOpt := options.NewDelegatingAuthenticationOptions() + authzOpt := options.NewDelegatingAuthorizationOptions() + opt.ServerCert.PairName = svcName + opt.ServerCert.CertDirectory = "" + authnOpt.RemoteKubeConfigFileOptional = true + authzOpt.RemoteKubeConfigFileOptional = true + + if host != "" { + ip := net.ParseIP(host) + if ip == nil { + err = fmt.Errorf("invalid listen address: %q", addr) + klog.Error(err) + return nil, err + } + opt.BindAddress = ip + p, err := strconv.Atoi(port) + if err != nil { + klog.Error(err) + return nil, fmt.Errorf("invalid listen address %q: %w", addr, err) + } + opt.BindPort = p + } + + if err = opt.MaybeDefaultWithSelfSignedCerts("localhost", alternateDNS, alternateIPs); err != nil { + klog.Error(err) + return nil, fmt.Errorf("failed to generate self signed certificates: %w", err) + } + + var serving *server.SecureServingInfo + var authn server.AuthenticationInfo + var authz server.AuthorizationInfo + if err = opt.ApplyTo(&serving, &clientConfig); err != nil { + klog.Error(err) + return nil, fmt.Errorf("failed to apply secure serving options to secure serving info: %w", err) + } + if err = authnOpt.ApplyTo(&authn, serving, nil); err != nil { + klog.Error(err) + return nil, fmt.Errorf("failed to apply authn options to authn info: %w", err) + } + if err = authzOpt.ApplyTo(&authz); err != nil { + klog.Error(err) + return nil, fmt.Errorf("failed to apply authz options to authz info: %w", err) + } + + handler = filters.WithAuthorization(handler, authz.Authorizer, scheme.Codecs) + handler = filters.WithAuthentication(handler, authn.Authenticator, filters.Unauthorized(scheme.Codecs), nil, nil) + + requestInfoResolver := &request.RequestInfoFactory{} + handler = filters.WithRequestInfo(handler, requestInfoResolver) + handler = filters.WithCacheControl(handler) + server.AuthorizeClientBearerToken(clientConfig, &authn, &authz) + + stopCh := make(chan struct{}, 1) + _, listenerStoppedCh, err := serving.Serve(handler, 0, stopCh) + if err != nil { + klog.Error(err) + return nil, fmt.Errorf("failed to serve on %s: %w", addr, err) + } + + return listenerStoppedCh, nil +} diff --git a/pkg/speaker/config.go b/pkg/speaker/config.go index 3127e57c7cac..42df76fe0a8c 100644 --- a/pkg/speaker/config.go +++ b/pkg/speaker/config.go @@ -179,11 +179,11 @@ func ParseFlags() (*Configuration, error) { } if err := config.initKubeClient(); err != nil { - return nil, fmt.Errorf("failed to init kube client, %v", err) + return nil, fmt.Errorf("failed to init kube client, %w", err) } if err := config.initBgpServer(); err != nil { - return nil, fmt.Errorf("failed to init bgp server, %v", err) + return nil, fmt.Errorf("failed to init bgp server, %w", err) } return config, nil diff --git a/pkg/speaker/subnet.go b/pkg/speaker/subnet.go index 75478e987329..47e8178f4050 100644 --- a/pkg/speaker/subnet.go +++ b/pkg/speaker/subnet.go @@ -213,7 +213,6 @@ func (c *Controller) syncSubnetRoutes() { klog.Error(err) } } - } } diff --git a/pkg/tproxy/tproxy_tcp_linux.go b/pkg/tproxy/tproxy_tcp_linux.go index c231e785cf6f..90cd54e786f6 100644 --- a/pkg/tproxy/tproxy_tcp_linux.go +++ b/pkg/tproxy/tproxy_tcp_linux.go @@ -3,6 +3,7 @@ package tproxy import ( + "errors" "fmt" "net" "os" @@ -71,7 +72,7 @@ func listenTCP(device, network string, laddr *net.TCPAddr) (net.Listener, error) fileDescriptorSource, err := listener.File() if err != nil { - return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("get file descriptor: %s", err)} + return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("get file descriptor: %w", err)} } defer func() { @@ -82,12 +83,12 @@ func listenTCP(device, network string, laddr *net.TCPAddr) (net.Listener, error) if device != "" { if err = syscall.BindToDevice(int(fileDescriptorSource.Fd()), device); err != nil { - return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("set socket option: SO_BINDTODEVICE(%s): %s", device, err)} + return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("set socket option: SO_BINDTODEVICE(%s): %w", device, err)} } } if err = syscall.SetsockoptInt(int(fileDescriptorSource.Fd()), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil { - return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %s", err)} + return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %w", err)} } return &Listener{listener}, nil @@ -150,31 +151,31 @@ func DialTCP(laddr, raddr *net.TCPAddr, isnonblocking bool) (*net.TCPConn, error func dialTCP(device string, laddr, raddr *net.TCPAddr, dontAssumeRemote, isnonblocking bool) (*net.TCPConn, error) { if laddr == nil || raddr == nil { - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("empty local address or remote address")} + return nil, &net.OpError{Op: "dial", Err: errors.New("empty local address or remote address")} } remoteSocketAddress, err := tcpAddrToSocketAddr(raddr) if err != nil { klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("build destination socket address: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("build destination socket address: %w", err)} } localSocketAddress, err := tcpAddrToSocketAddr(laddr) if err != nil { klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("build local socket address: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("build local socket address: %w", err)} } fileDescriptor, err := syscall.Socket(tcpAddrFamily("tcp", raddr, laddr), syscall.SOCK_STREAM, syscall.IPPROTO_TCP) if err != nil { klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket open: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket open: %w", err)} } if device != "" { if err = syscall.BindToDevice(fileDescriptor, device); err != nil { klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_BINDTODEVICE(%s): %s", device, err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_BINDTODEVICE(%s): %w", device, err)} } } @@ -183,7 +184,7 @@ func dialTCP(device string, laddr, raddr *net.TCPAddr, dontAssumeRemote, isnonbl klog.Errorf("fileDescriptor %v Close err: %v", fileDescriptor, err) } klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_REUSEADDR: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_REUSEADDR: %w", err)} } if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil { @@ -191,7 +192,7 @@ func dialTCP(device string, laddr, raddr *net.TCPAddr, dontAssumeRemote, isnonbl klog.Errorf("fileDescriptor %v Close err: %v", fileDescriptor, err) } klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %w", err)} } if err = syscall.SetNonblock(fileDescriptor, isnonblocking); err != nil { @@ -199,7 +200,7 @@ func dialTCP(device string, laddr, raddr *net.TCPAddr, dontAssumeRemote, isnonbl klog.Errorf("fileDescriptor %v Close err: %v", fileDescriptor, err) } klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_NONBLOCK: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("set socket option: SO_NONBLOCK: %w", err)} } if !dontAssumeRemote { @@ -208,7 +209,7 @@ func dialTCP(device string, laddr, raddr *net.TCPAddr, dontAssumeRemote, isnonbl klog.Errorf("fileDescriptor %v Close err: %v", fileDescriptor, err) } klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket bind: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket bind: %w", err)} } } @@ -217,7 +218,7 @@ func dialTCP(device string, laddr, raddr *net.TCPAddr, dontAssumeRemote, isnonbl klog.Errorf("fileDescriptor %v Close err: %v", fileDescriptor, err) } klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket connect: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("socket connect: %w", err)} } fdFile := os.NewFile(uintptr(fileDescriptor), fmt.Sprintf("net-tcp-dial-%s", raddr.String())) @@ -233,7 +234,7 @@ func dialTCP(device string, laddr, raddr *net.TCPAddr, dontAssumeRemote, isnonbl klog.Errorf("fileDescriptor %v Close err: %v", fileDescriptor, err) } klog.Error(err) - return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("convert file descriptor to connection: %s", err)} + return nil, &net.OpError{Op: "dial", Err: fmt.Errorf("convert file descriptor to connection: %w", err)} } return remoteConn.(*net.TCPConn), nil diff --git a/pkg/util/arp.go b/pkg/util/arp.go index 009c934453cc..7f7483ba57ae 100644 --- a/pkg/util/arp.go +++ b/pkg/util/arp.go @@ -18,7 +18,7 @@ import ( func ArpResolve(nic, dstIP string, timeout time.Duration, maxRetry int, done chan struct{}) (net.HardwareAddr, int, error) { target, err := netip.ParseAddr(dstIP) if err != nil { - return nil, 0, fmt.Errorf("failed to parse target address %s: %v", dstIP, err) + return nil, 0, fmt.Errorf("failed to parse target address %s: %w", dstIP, err) } if done != nil { @@ -47,7 +47,7 @@ func ArpResolve(nic, dstIP string, timeout time.Duration, maxRetry int, done cha } } if err != nil { - return nil, count, fmt.Errorf("failed to get interface %s: %v", nic, err) + return nil, count, fmt.Errorf("failed to get interface %s: %w", nic, err) } var client *arp.Client @@ -65,7 +65,7 @@ func ArpResolve(nic, dstIP string, timeout time.Duration, maxRetry int, done cha } } if err != nil { - return nil, count, fmt.Errorf("failed to set up ARP client: %v", err) + return nil, count, fmt.Errorf("failed to set up ARP client: %w", err) } var mac net.HardwareAddr @@ -85,7 +85,7 @@ func ArpResolve(nic, dstIP string, timeout time.Duration, maxRetry int, done cha } } - return nil, count, fmt.Errorf("resolve MAC address of %s timeout: %v", dstIP, err) + return nil, count, fmt.Errorf("resolve MAC address of %s timeout: %w", dstIP, err) } func macEqual(a, b net.HardwareAddr) bool { @@ -115,7 +115,7 @@ func ArpDetectIPConflict(nic, ip string, mac net.HardwareAddr) (net.HardwareAddr tpa, err := netip.ParseAddr(ip) if err != nil { - return nil, fmt.Errorf("failed to parse IP address %s: %v", ip, err) + return nil, fmt.Errorf("failed to parse IP address %s: %w", ip, err) } ip = tpa.String() diff --git a/pkg/util/const.go b/pkg/util/const.go index 364755f5e6cf..b0d7006b6098 100644 --- a/pkg/util/const.go +++ b/pkg/util/const.go @@ -6,38 +6,40 @@ const ( DepreciatedFinalizerName = "kube-ovn-controller" KubeOVNControllerFinalizer = "kubeovn.io/kube-ovn-controller" - AllocatedAnnotation = "ovn.kubernetes.io/allocated" - RoutedAnnotation = "ovn.kubernetes.io/routed" - RoutesAnnotation = "ovn.kubernetes.io/routes" - MacAddressAnnotation = "ovn.kubernetes.io/mac_address" - IPAddressAnnotation = "ovn.kubernetes.io/ip_address" - CidrAnnotation = "ovn.kubernetes.io/cidr" - GatewayAnnotation = "ovn.kubernetes.io/gateway" - IPPoolAnnotation = "ovn.kubernetes.io/ip_pool" - BgpAnnotation = "ovn.kubernetes.io/bgp" - SnatAnnotation = "ovn.kubernetes.io/snat" - EipAnnotation = "ovn.kubernetes.io/eip" - FipFinalizer = "ovn.kubernetes.io/fip" - VipAnnotation = "ovn.kubernetes.io/vip" - AAPsAnnotation = "ovn.kubernetes.io/aaps" - ChassisAnnotation = "ovn.kubernetes.io/chassis" - VMAnnotation = "ovn.kubernetes.io/virtualmachine" - - VpcNatGatewayAnnotation = "ovn.kubernetes.io/vpc_nat_gw" - VpcNatGatewayInitAnnotation = "ovn.kubernetes.io/vpc_nat_gw_init" - VpcEipsAnnotation = "ovn.kubernetes.io/vpc_eips" - VpcFloatingIPMd5Annotation = "ovn.kubernetes.io/vpc_floating_ips" - VpcDnatMd5Annotation = "ovn.kubernetes.io/vpc_dnat_md5" - VpcSnatMd5Annotation = "ovn.kubernetes.io/vpc_snat_md5" - VpcCIDRsAnnotation = "ovn.kubernetes.io/vpc_cidrs" - VpcLbAnnotation = "ovn.kubernetes.io/vpc_lb" - VpcExternalLabel = "ovn.kubernetes.io/vpc_external" - VpcEipAnnotation = "ovn.kubernetes.io/vpc_eip" - VpcDnatEPortLabel = "ovn.kubernetes.io/vpc_dnat_eport" - VpcNatAnnotation = "ovn.kubernetes.io/vpc_nat" - OvnEipTypeLabel = "ovn.kubernetes.io/ovn_eip_type" - EipV4IpLabel = "ovn.kubernetes.io/eip_v4_ip" - EipV6IpLabel = "ovn.kubernetes.io/eip_v6_ip" + AllocatedAnnotation = "ovn.kubernetes.io/allocated" + RoutedAnnotation = "ovn.kubernetes.io/routed" + RoutesAnnotation = "ovn.kubernetes.io/routes" + MacAddressAnnotation = "ovn.kubernetes.io/mac_address" + IPAddressAnnotation = "ovn.kubernetes.io/ip_address" + CidrAnnotation = "ovn.kubernetes.io/cidr" + GatewayAnnotation = "ovn.kubernetes.io/gateway" + IPPoolAnnotation = "ovn.kubernetes.io/ip_pool" + BgpAnnotation = "ovn.kubernetes.io/bgp" + SnatAnnotation = "ovn.kubernetes.io/snat" + EipAnnotation = "ovn.kubernetes.io/eip" + FipFinalizer = "ovn.kubernetes.io/fip" + VipAnnotation = "ovn.kubernetes.io/vip" + AAPsAnnotation = "ovn.kubernetes.io/aaps" + ChassisAnnotation = "ovn.kubernetes.io/chassis" + VMAnnotation = "ovn.kubernetes.io/virtualmachine" + ActivationStrategyAnnotation = "ovn.kubernetes.io/activation_strategy" + + VpcNatGatewayAnnotation = "ovn.kubernetes.io/vpc_nat_gw" + VpcNatGatewayInitAnnotation = "ovn.kubernetes.io/vpc_nat_gw_init" + VpcNatGatewayActivatedAnnotation = "ovn.kubernetes.io/vpc_nat_gw_activated" + VpcEipsAnnotation = "ovn.kubernetes.io/vpc_eips" + VpcFloatingIPMd5Annotation = "ovn.kubernetes.io/vpc_floating_ips" + VpcDnatMd5Annotation = "ovn.kubernetes.io/vpc_dnat_md5" + VpcSnatMd5Annotation = "ovn.kubernetes.io/vpc_snat_md5" + VpcCIDRsAnnotation = "ovn.kubernetes.io/vpc_cidrs" + VpcLbAnnotation = "ovn.kubernetes.io/vpc_lb" + VpcExternalLabel = "ovn.kubernetes.io/vpc_external" + VpcEipAnnotation = "ovn.kubernetes.io/vpc_eip" + VpcDnatEPortLabel = "ovn.kubernetes.io/vpc_dnat_eport" + VpcNatAnnotation = "ovn.kubernetes.io/vpc_nat" + OvnEipTypeLabel = "ovn.kubernetes.io/ovn_eip_type" + EipV4IpLabel = "ovn.kubernetes.io/eip_v4_ip" + EipV6IpLabel = "ovn.kubernetes.io/eip_v6_ip" SwitchLBRuleVipsAnnotation = "ovn.kubernetes.io/switch_lb_vip" SwitchLBRuleVip = "switch_lb_vip" @@ -70,6 +72,7 @@ const ( DefaultRouteAnnotationTemplate = "%s.kubernetes.io/default_route" VfRepresentorNameTemplate = "%s.kubernetes.io/vf_representor" VfNameTemplate = "%s.kubernetes.io/vf" + ActivationStrategyTemplate = "%s.kubernetes.io/activation_strategy" ProviderNetworkTemplate = "%s.kubernetes.io/provider_network" ProviderNetworkErrMessageTemplate = "%s.provider-network.kubernetes.io/err_mesg" @@ -146,9 +149,15 @@ const ( DefaultDropPriority = "1000" GwChassisMaxPriority = 100 - - DefaultMTU = 1500 - + AnpMaxRules = 100 + AnpMaxPriority = 99 + AnpACLMaxPriority = 30000 + BanpACLMaxPriority = 1800 + AnpACLTier = 1 + NetpolACLTier = 2 + BanpACLTier = 3 + + DefaultMTU = 1500 GeneveHeaderLength = 100 VxlanHeaderLength = 50 SttHeaderLength = 72 @@ -192,12 +201,13 @@ const ( OvnFip = "ovn" IptablesFip = "iptables" - U2OSubnetPolicyPriority = 29400 - GatewayRouterPolicyPriority = 29000 - OvnICPolicyPriority = 29500 - NodeRouterPolicyPriority = 30000 - NodeLocalDNSPolicyPriority = 30100 - SubnetRouterPolicyPriority = 31000 + U2OSubnetPolicyPriority = 29400 + GatewayRouterPolicyPriority = 29000 + NorthGatewayRoutePolicyPriority = 29250 + OvnICPolicyPriority = 29500 + NodeRouterPolicyPriority = 30000 + NodeLocalDNSPolicyPriority = 30100 + SubnetRouterPolicyPriority = 31000 OffloadType = "offload-port" InternalType = "internal-port" diff --git a/pkg/util/k8s.go b/pkg/util/k8s.go index 1ade1cc1bdc8..70ffa9687358 100644 --- a/pkg/util/k8s.go +++ b/pkg/util/k8s.go @@ -2,6 +2,7 @@ package util import ( "context" + "crypto/tls" "encoding/json" "fmt" "net" @@ -18,24 +19,46 @@ import ( "k8s.io/klog/v2" ) -func DialAPIServer(host string) error { +func DialTCP(host string, timeout time.Duration, verbose bool) error { u, err := url.Parse(host) if err != nil { - return fmt.Errorf("failed to parse host %q: %v", host, err) + return fmt.Errorf("failed to parse host %q: %w", host, err) } + var conn net.Conn address := net.JoinHostPort(u.Hostname(), u.Port()) - timer := time.NewTimer(3 * time.Second) + switch u.Scheme { + case "tcp", "http": + conn, err = net.DialTimeout("tcp", address, timeout) + case "tls", "https": + config := &tls.Config{InsecureSkipVerify: true} // #nosec G402 + conn, err = tls.DialWithDialer(&net.Dialer{Timeout: timeout}, "tcp", address, config) + default: + return fmt.Errorf("unsupported scheme %q", u.Scheme) + } + + if err == nil { + if verbose { + klog.Infof("succeeded to dial host %q", host) + } + _ = conn.Close() + return nil + } + + return fmt.Errorf("timed out dialing host %q", host) +} + +func DialAPIServer(host string) error { + interval := 3 * time.Second + timer := time.NewTimer(interval) for i := 0; i < 10; i++ { - conn, err := net.DialTimeout("tcp", address, 3*time.Second) + err := DialTCP(host, interval, true) if err == nil { - klog.Infof("succeeded to dial apiserver %q", address) - _ = conn.Close() return nil } - klog.Warningf("failed to dial apiserver %q: %v", address, err) + klog.Warningf("failed to dial apiserver %q: %v", host, err) <-timer.C - timer.Reset(3 * time.Second) + timer.Reset(interval) } return fmt.Errorf("timed out dialing apiserver %q", host) diff --git a/pkg/util/link.go b/pkg/util/link.go index 5eed6bc66ff9..0de470ab3c6e 100644 --- a/pkg/util/link.go +++ b/pkg/util/link.go @@ -13,10 +13,10 @@ import ( func SetLinkUp(name string) error { link, err := netlink.LinkByName(name) if err != nil { - return fmt.Errorf("failed to get link %s: %v", name, err) + return fmt.Errorf("failed to get link %s: %w", name, err) } if err = netlink.LinkSetUp(link); err != nil { - return fmt.Errorf("failed to set link %s up: %v", name, err) + return fmt.Errorf("failed to set link %s up: %w", name, err) } return nil diff --git a/pkg/util/net.go b/pkg/util/net.go index 14685cb5973e..e1e9680e3c9b 100644 --- a/pkg/util/net.go +++ b/pkg/util/net.go @@ -570,7 +570,7 @@ func TCPConnectivityCheck(address string) error { func TCPConnectivityListen(address string) error { listener, err := net.Listen("tcp", address) if err != nil { - return fmt.Errorf("listen failed with err %v", err) + return fmt.Errorf("listen failed with err %w", err) } go func() { @@ -589,7 +589,7 @@ func TCPConnectivityListen(address string) error { func UDPConnectivityCheck(address string) error { udpAddr, err := net.ResolveUDPAddr("udp", address) if err != nil { - return fmt.Errorf("resolve udp addr failed with err %v", err) + return fmt.Errorf("resolve udp addr failed with err %w", err) } conn, err := net.DialUDP("udp", nil, udpAddr) @@ -606,13 +606,13 @@ func UDPConnectivityCheck(address string) error { _, err = conn.Write([]byte("health check")) if err != nil { - return fmt.Errorf("send udp packet failed with err %v", err) + return fmt.Errorf("send udp packet failed with err %w", err) } buffer := make([]byte, 1024) _, err = conn.Read(buffer) if err != nil { - return fmt.Errorf("read udp packet from remote failed %v", err) + return fmt.Errorf("read udp packet from remote failed %w", err) } return nil @@ -621,12 +621,12 @@ func UDPConnectivityCheck(address string) error { func UDPConnectivityListen(address string) error { listenAddr, err := net.ResolveUDPAddr("udp", address) if err != nil { - return fmt.Errorf("resolve udp addr failed with err %v", err) + return fmt.Errorf("resolve udp addr failed with err %w", err) } conn, err := net.ListenUDP("udp", listenAddr) if err != nil { - return fmt.Errorf("listen udp address failed with %v", err) + return fmt.Errorf("listen udp address failed with %w", err) } buffer := make([]byte, 1024) @@ -649,18 +649,10 @@ func UDPConnectivityListen(address string) error { } func GetDefaultListenAddr() string { - addr := "0.0.0.0" if os.Getenv("ENABLE_BIND_LOCAL_IP") == "true" { - podIpsEnv := os.Getenv("POD_IPS") - podIps := strings.Split(podIpsEnv, ",") - // when pod in dual mode, golang can't support bind v4 and v6 address in the same time, - // so not support bind local ip when in dual mode - if len(podIps) == 1 { - addr = podIps[0] - if CheckProtocol(podIps[0]) == kubeovnv1.ProtocolIPv6 { - addr = fmt.Sprintf("[%s]", podIps[0]) - } + if ips := strings.Split(os.Getenv("POD_IPS"), ","); len(ips) == 1 { + return ips[0] } } - return addr + return "0.0.0.0" } diff --git a/pkg/util/net_test.go b/pkg/util/net_test.go index 3c8930c0feab..c7580ce4cc2c 100644 --- a/pkg/util/net_test.go +++ b/pkg/util/net_test.go @@ -434,7 +434,6 @@ func TestGenerateRandomV4IP(t *testing.T) { t.Errorf("%v expected %v, but %v got", c.cidr, c.want, ans) } - } else { ans := GenerateRandomV4IP(c.cidr) if IPNets.Contains(net.ParseIP(GenerateRandomV4IP(c.cidr))) { diff --git a/pkg/util/network_attachment.go b/pkg/util/network_attachment.go index c3dacfe9a459..7c352222b560 100644 --- a/pkg/util/network_attachment.go +++ b/pkg/util/network_attachment.go @@ -2,6 +2,7 @@ package util import ( "encoding/json" + "errors" "fmt" "net" "regexp" @@ -28,7 +29,7 @@ func parsePodNetworkObjectName(podNetwork string) (string, string, string, error networkName = slashItems[0] default: klog.Errorf("parsePodNetworkObjectName: Invalid network object (failed at '/')") - return "", "", "", fmt.Errorf("parsePodNetworkObjectName: Invalid network object (failed at '/')") + return "", "", "", errors.New("parsePodNetworkObjectName: Invalid network object (failed at '/')") } atItems := strings.Split(networkName, "@") @@ -37,7 +38,7 @@ func parsePodNetworkObjectName(podNetwork string) (string, string, string, error netIfName = strings.TrimSpace(atItems[1]) } else if len(atItems) != 1 { klog.Errorf("parsePodNetworkObjectName: Invalid network object (failed at '@')") - return "", "", "", fmt.Errorf("parsePodNetworkObjectName: Invalid network object (failed at '@')") + return "", "", "", errors.New("parsePodNetworkObjectName: Invalid network object (failed at '@')") } // Check and see if each item matches the specification for valid attachment name. @@ -51,9 +52,9 @@ func parsePodNetworkObjectName(podNetwork string) (string, string, string, error klog.Errorf(fmt.Sprintf("parsePodNetworkObjectName: Failed to parse: "+ "one or more items did not match comma-delimited format (must consist of lower case alphanumeric characters). "+ "Must start and end with an alphanumeric character), mismatch @ '%v'", allItems[i])) - return "", "", "", fmt.Errorf(fmt.Sprintf("parsePodNetworkObjectName: Failed to parse: "+ + return "", "", "", fmt.Errorf("parsePodNetworkObjectName: Failed to parse: "+ "one or more items did not match comma-delimited format (must consist of lower case alphanumeric characters). "+ - "Must start and end with an alphanumeric character), mismatch @ '%v'", allItems[i])) + "Must start and end with an alphanumeric character), mismatch @ '%v'", allItems[i]) } } @@ -72,7 +73,7 @@ func ParsePodNetworkAnnotation(podNetworks, defaultNamespace string) ([]*types.N if strings.ContainsAny(podNetworks, "[{\"") { if err := json.Unmarshal([]byte(podNetworks), &networks); err != nil { klog.Errorf("parsePodNetworkAnnotation: failed to parse pod Network Attachment Selection Annotation JSON format: %v", err) - return nil, fmt.Errorf("parsePodNetworkAnnotation: failed to parse pod Network Attachment Selection Annotation JSON format: %v", err) + return nil, fmt.Errorf("parsePodNetworkAnnotation: failed to parse pod Network Attachment Selection Annotation JSON format: %w", err) } } else { // Comma-delimited list of network attachment object names @@ -84,7 +85,7 @@ func ParsePodNetworkAnnotation(podNetworks, defaultNamespace string) ([]*types.N netNsName, networkName, netIfName, err := parsePodNetworkObjectName(item) if err != nil { klog.Errorf("parsePodNetworkAnnotation: %v", err) - return nil, fmt.Errorf("parsePodNetworkAnnotation: %v", err) + return nil, fmt.Errorf("parsePodNetworkAnnotation: %w", err) } networks = append(networks, &types.NetworkSelectionElement{ @@ -103,7 +104,7 @@ func ParsePodNetworkAnnotation(podNetworks, defaultNamespace string) ([]*types.N // validate MAC address if _, err := net.ParseMAC(n.MacRequest); err != nil { klog.Errorf("parsePodNetworkAnnotation: failed to mac: %v", err) - return nil, fmt.Errorf("parsePodNetworkAnnotation: failed to mac: %v", err) + return nil, fmt.Errorf("parsePodNetworkAnnotation: failed to mac: %w", err) } } if n.IPRequest != nil { @@ -112,7 +113,7 @@ func ParsePodNetworkAnnotation(podNetworks, defaultNamespace string) ([]*types.N if strings.Contains(ip, "/") { if _, _, err := net.ParseCIDR(ip); err != nil { klog.Errorf("failed to parse CIDR %q: %v", ip, err) - return nil, fmt.Errorf("failed to parse CIDR %q: %v", ip, err) + return nil, fmt.Errorf("failed to parse CIDR %q: %w", ip, err) } } else if net.ParseIP(ip) == nil { klog.Errorf("failed to parse IP address %q", ip) diff --git a/pkg/util/validator.go b/pkg/util/validator.go index 438c2225da66..911b874e996a 100644 --- a/pkg/util/validator.go +++ b/pkg/util/validator.go @@ -1,6 +1,7 @@ package util import ( + "errors" "fmt" "net" "os" @@ -18,7 +19,7 @@ func ValidateSubnet(subnet kubeovnv1.Subnet) error { return fmt.Errorf("gateway %s is not in cidr %s", subnet.Spec.Gateway, subnet.Spec.CIDRBlock) } if err := ValidateNetworkBroadcast(subnet.Spec.CIDRBlock, subnet.Spec.Gateway); err != nil { - return fmt.Errorf("validate gateway %s for cidr %s failed: %v", subnet.Spec.Gateway, subnet.Spec.CIDRBlock, err) + return fmt.Errorf("validate gateway %s for cidr %s failed: %w", subnet.Spec.Gateway, subnet.Spec.CIDRBlock, err) } } @@ -87,11 +88,11 @@ func ValidateSubnet(subnet kubeovnv1.Subnet) error { if egw := subnet.Spec.ExternalEgressGateway; egw != "" { if subnet.Spec.NatOutgoing { - return fmt.Errorf("conflict configuration: natOutgoing and externalEgressGateway") + return errors.New("conflict configuration: natOutgoing and externalEgressGateway") } ips := strings.Split(egw, ",") if len(ips) > 2 { - return fmt.Errorf("invalid external egress gateway configuration") + return errors.New("invalid external egress gateway configuration") } for _, ip := range ips { if net.ParseIP(ip) == nil { @@ -100,7 +101,7 @@ func ValidateSubnet(subnet kubeovnv1.Subnet) error { } egwProtocol, cidrProtocol := CheckProtocol(egw), CheckProtocol(subnet.Spec.CIDRBlock) if egwProtocol != cidrProtocol && cidrProtocol != kubeovnv1.ProtocolDual { - return fmt.Errorf("invalid external egress gateway configuration: address family is conflict with CIDR") + return errors.New("invalid external egress gateway configuration: address family is conflict with CIDR") } } @@ -113,7 +114,7 @@ func ValidateSubnet(subnet kubeovnv1.Subnet) error { } if subnet.Spec.LogicalGateway && subnet.Spec.U2OInterconnection { - return fmt.Errorf("logicalGateway and u2oInterconnection can't be opened at the same time") + return errors.New("logicalGateway and u2oInterconnection can't be opened at the same time") } if len(subnet.Spec.NatOutgoingPolicyRules) != 0 { @@ -140,12 +141,12 @@ func validateNatOutgoingPolicyRules(subnet kubeovnv1.Subnet) error { if rule.Match.SrcIPs != "" { if srcProtocol, err = validateNatOutGoingPolicyRuleIPs(rule.Match.SrcIPs); err != nil { - return fmt.Errorf("validate nat policy rules src ips %s failed with err %v", rule.Match.SrcIPs, err) + return fmt.Errorf("validate nat policy rules src ips %s failed with err %w", rule.Match.SrcIPs, err) } } if rule.Match.DstIPs != "" { if dstProtocol, err = validateNatOutGoingPolicyRuleIPs(rule.Match.DstIPs); err != nil { - return fmt.Errorf("validate nat policy rules dst ips %s failed with err %v", rule.Match.DstIPs, err) + return fmt.Errorf("validate nat policy rules dst ips %s failed with err %w", rule.Match.DstIPs, err) } } @@ -159,7 +160,7 @@ func validateNatOutgoingPolicyRules(subnet kubeovnv1.Subnet) error { func validateNatOutGoingPolicyRuleIPs(matchIPStr string) (string, error) { ipItems := strings.Split(matchIPStr, ",") if len(ipItems) == 0 { - return "", fmt.Errorf("MatchIPStr format error") + return "", errors.New("MatchIPStr format error") } lastProtocol := "" checkProtocolConsistent := func(ipCidr string) bool { diff --git a/pkg/webhook/ip.go b/pkg/webhook/ip.go index 9b585359ee2b..b658340bc328 100644 --- a/pkg/webhook/ip.go +++ b/pkg/webhook/ip.go @@ -2,6 +2,7 @@ package webhook import ( "context" + "errors" "fmt" "net" "net/http" @@ -78,8 +79,7 @@ func (v *ValidatingHook) IPUpdateHook(ctx context.Context, req admission.Request func (v *ValidatingHook) ValidateIP(ctx context.Context, ip *ovnv1.IP) error { if ip.Spec.Subnet == "" { - err := fmt.Errorf("subnet parameter cannot be empty") - return err + return errors.New("subnet parameter cannot be empty") } subnet := &ovnv1.Subnet{} @@ -115,13 +115,11 @@ func (v *ValidatingHook) ValidateIP(ctx context.Context, ip *ovnv1.IP) error { } if ip.Spec.Subnet == "" { - err := fmt.Errorf("subnet parameter cannot be empty") - return err + return errors.New("subnet parameter cannot be empty") } if ip.Spec.PodType != "" && ip.Spec.PodType != util.VM && ip.Spec.PodType != util.StatefulSet { - err := fmt.Errorf("podType %s is not supported", ip.Spec.PodType) - return err + return fmt.Errorf("podType %s is not supported", ip.Spec.PodType) } return nil diff --git a/pkg/webhook/ovn_nat_gateway.go b/pkg/webhook/ovn_nat_gateway.go index 712aae28aebe..b9eb490f0b11 100644 --- a/pkg/webhook/ovn_nat_gateway.go +++ b/pkg/webhook/ovn_nat_gateway.go @@ -2,6 +2,7 @@ package webhook import ( "context" + "errors" "fmt" "net" "net/http" @@ -52,7 +53,7 @@ func (v *ValidatingHook) ovnEipUpdateHook(ctx context.Context, req admission.Req if eipOld.Spec != eipNew.Spec { if eipOld.Status.Ready { - err := fmt.Errorf("OvnEip not support change") + err := errors.New("OvnEip not support change") return ctrlwebhook.Errored(http.StatusBadRequest, err) } if err := v.ValidateOvnEip(ctx, &eipNew); err != nil { @@ -142,7 +143,7 @@ func (v *ValidatingHook) ovnDnatUpdateHook(ctx context.Context, req admission.Re if dnatOld.Spec != dnatNew.Spec { if dnatOld.Status.Ready { - err := fmt.Errorf("OvnDnat not support change") + err := errors.New("OvnDnat not support change") return ctrlwebhook.Errored(http.StatusBadRequest, err) } if err := v.ValidateOvnDnat(ctx, &dnatNew); err != nil { @@ -179,7 +180,7 @@ func (v *ValidatingHook) ovnSnatUpdateHook(ctx context.Context, req admission.Re if snatOld.Spec != snatNew.Spec { if snatOld.Status.Ready { - err := fmt.Errorf("OvnSnat not support change") + err := errors.New("OvnSnat not support change") return ctrlwebhook.Errored(http.StatusBadRequest, err) } if err := v.ValidateOvnSnat(ctx, &snatNew); err != nil { @@ -216,7 +217,7 @@ func (v *ValidatingHook) ovnFipUpdateHook(ctx context.Context, req admission.Req if fipNew.Spec != fipOld.Spec { if fipOld.Status.Ready { - err := fmt.Errorf("OvnFip not support change") + err := errors.New("OvnFip not support change") return ctrlwebhook.Errored(http.StatusBadRequest, err) } if err := v.ValidateOvnFip(ctx, &fipNew); err != nil { @@ -265,11 +266,11 @@ func (v *ValidatingHook) ValidateOvnEip(ctx context.Context, eip *ovnv1.OvnEip) func (v *ValidatingHook) ValidateOvnDnat(ctx context.Context, dnat *ovnv1.OvnDnatRule) error { if dnat.Spec.OvnEip == "" { - err := fmt.Errorf("should set spec ovnEip") + err := errors.New("should set spec ovnEip") return err } if dnat.Spec.IPName == "" && dnat.Spec.V4Ip == "" && dnat.Spec.V6Ip == "" { - err := fmt.Errorf("should set spec ipName or v4 or v6 Ip") + err := errors.New("should set spec ipName or v4 or v6 Ip") return err } eip := &ovnv1.OvnEip{} @@ -279,17 +280,17 @@ func (v *ValidatingHook) ValidateOvnDnat(ctx context.Context, dnat *ovnv1.OvnDna } if dnat.Spec.ExternalPort == "" { - err := fmt.Errorf("should set spec externalPort") + err := errors.New("should set spec externalPort") return err } if dnat.Spec.InternalPort == "" { - err := fmt.Errorf("should set spec internalPort") + err := errors.New("should set spec internalPort") return err } if port, err := strconv.Atoi(dnat.Spec.ExternalPort); err != nil { - errMsg := fmt.Errorf("failed to parse spec externalPort %s: %v", dnat.Spec.ExternalPort, err) + errMsg := fmt.Errorf("failed to parse spec externalPort %s: %w", dnat.Spec.ExternalPort, err) return errMsg } else if port < 0 || port > 65535 { err := fmt.Errorf("spec externalPort %s is not a valid port", dnat.Spec.ExternalPort) @@ -297,7 +298,7 @@ func (v *ValidatingHook) ValidateOvnDnat(ctx context.Context, dnat *ovnv1.OvnDna } if port, err := strconv.Atoi(dnat.Spec.InternalPort); err != nil { - errMsg := fmt.Errorf("failed to parse spec internalIP %s: %v", dnat.Spec.InternalPort, err) + errMsg := fmt.Errorf("failed to parse spec internalIP %s: %w", dnat.Spec.InternalPort, err) return errMsg } else if port < 0 || port > 65535 { err := fmt.Errorf("spec internalIP %s is not a valid port", dnat.Spec.InternalPort) @@ -306,7 +307,7 @@ func (v *ValidatingHook) ValidateOvnDnat(ctx context.Context, dnat *ovnv1.OvnDna if !strings.EqualFold(dnat.Spec.Protocol, "tcp") && !strings.EqualFold(dnat.Spec.Protocol, "udp") { - err := fmt.Errorf("invaild dnat protocol: %s, support tcp or udp", dnat.Spec.Protocol) + err := fmt.Errorf("invalid dnat protocol: %s, support tcp or udp", dnat.Spec.Protocol) return err } @@ -315,28 +316,23 @@ func (v *ValidatingHook) ValidateOvnDnat(ctx context.Context, dnat *ovnv1.OvnDna func (v *ValidatingHook) ValidateOvnSnat(ctx context.Context, snat *ovnv1.OvnSnatRule) error { if snat.Spec.OvnEip == "" { - err := fmt.Errorf("should set spec OvnEip") - return err + return errors.New("should set spec OvnEip") } if snat.Spec.VpcSubnet != "" && snat.Spec.IPName != "" { - err := fmt.Errorf("should not set spec vpcSubnet and ipName at the same time") - return err + return errors.New("should not set spec vpcSubnet and ipName at the same time") } if snat.Spec.Vpc != "" && snat.Spec.V4IpCidr == "" && snat.Spec.V6IpCidr == "" { - err := fmt.Errorf("should set spec v4 or v6 IpCidr (subnet cidr or ip address) when spec vpc is set") - return err + return errors.New("should set spec v4 or v6 IpCidr (subnet cidr or ip address) when spec vpc is set") } if snat.Spec.Vpc == "" && snat.Spec.V4IpCidr != "" && snat.Spec.V6IpCidr != "" { - err := fmt.Errorf("should set spec vpc while spec v4 or v6 IpCidr is not set") - return err + return errors.New("should set spec vpc while spec v4 or v6 IpCidr is not set") } if snat.Spec.VpcSubnet == "" && snat.Spec.IPName == "" && snat.Spec.Vpc == "" && snat.Spec.V4IpCidr == "" && snat.Spec.V6IpCidr == "" { - err := fmt.Errorf("should set spec vpcSubnet or ipName or vpc and v4 and v6 IpCidr at least") - return err + return errors.New("should set spec vpcSubnet or ipName or vpc and v4 and v6 IpCidr at least") } eip := &ovnv1.OvnEip{} @@ -346,11 +342,11 @@ func (v *ValidatingHook) ValidateOvnSnat(ctx context.Context, snat *ovnv1.OvnSna func (v *ValidatingHook) ValidateOvnFip(ctx context.Context, fip *ovnv1.OvnFip) error { if fip.Spec.OvnEip == "" { - err := fmt.Errorf("should set spec ovnEip") + err := errors.New("should set spec ovnEip") return err } if fip.Spec.IPName == "" && fip.Spec.V4Ip == "" && fip.Spec.V6Ip == "" { - err := fmt.Errorf("should set spec ipName or ip") + err := errors.New("should set spec ipName or ip") return err } eip := &ovnv1.OvnEip{} diff --git a/pkg/webhook/subnet.go b/pkg/webhook/subnet.go index 365fb6405503..dd8367562f17 100644 --- a/pkg/webhook/subnet.go +++ b/pkg/webhook/subnet.go @@ -2,6 +2,7 @@ package webhook import ( "context" + "errors" "fmt" "net/http" "slices" @@ -37,7 +38,7 @@ func (v *ValidatingHook) SubnetCreateHook(ctx context.Context, req admission.Req } for _, item := range vpcList.Items { if item.Name == o.Name { - err := fmt.Errorf("vpc and subnet cannot have the same name") + err := errors.New("vpc and subnet cannot have the same name") return ctrlwebhook.Errored(http.StatusBadRequest, err) } @@ -65,8 +66,7 @@ func (v *ValidatingHook) SubnetUpdateHook(ctx context.Context, req admission.Req return ctrlwebhook.Errored(http.StatusBadRequest, err) } if (o.Spec.Gateway != oldSubnet.Spec.Gateway) && (o.Status.V4UsingIPs != 0 || o.Status.V6UsingIPs != 0) { - err := fmt.Errorf("can't update gateway of cidr when any IPs in Using") - return ctrlwebhook.Denied(err.Error()) + return ctrlwebhook.Denied("can't update gateway of cidr when any IPs in Using") } if err := util.ValidateSubnet(o); err != nil { @@ -90,8 +90,7 @@ func (v *ValidatingHook) SubnetDeleteHook(_ context.Context, req admission.Reque return ctrlwebhook.Errored(http.StatusBadRequest, err) } if subnet.Status.V4UsingIPs != 0 || subnet.Status.V6UsingIPs != 0 { - err := fmt.Errorf("can't delete subnet when any IPs in Using") - return ctrlwebhook.Denied(err.Error()) + return ctrlwebhook.Denied("can't delete subnet when any IPs in Using") } return ctrlwebhook.Allowed("by pass") } diff --git a/pkg/webhook/vip.go b/pkg/webhook/vip.go index 4ea188e527d9..836b5154d54e 100644 --- a/pkg/webhook/vip.go +++ b/pkg/webhook/vip.go @@ -2,6 +2,7 @@ package webhook import ( "context" + "errors" "fmt" "net" "net/http" @@ -47,7 +48,7 @@ func (v *ValidatingHook) VipUpdateHook(ctx context.Context, req admission.Reques return ctrlwebhook.Errored(http.StatusBadRequest, err) } } else { - err := fmt.Errorf("vip has been assigned, not support change") + err := errors.New("vip has been assigned, not support change") return ctrlwebhook.Errored(http.StatusBadRequest, err) } } @@ -56,8 +57,7 @@ func (v *ValidatingHook) VipUpdateHook(ctx context.Context, req admission.Reques func (v *ValidatingHook) ValidateVip(ctx context.Context, vip *ovnv1.Vip) error { if vip.Spec.Subnet == "" { - err := fmt.Errorf("subnet parameter cannot be empty") - return err + return errors.New("subnet parameter cannot be empty") } subnet := &ovnv1.Subnet{} diff --git a/pkg/webhook/vpc.go b/pkg/webhook/vpc.go index f58a0d467831..655a7aeecdfe 100644 --- a/pkg/webhook/vpc.go +++ b/pkg/webhook/vpc.go @@ -2,7 +2,7 @@ package webhook import ( "context" - "fmt" + "errors" "net/http" ctrlwebhook "sigs.k8s.io/controller-runtime/pkg/webhook" @@ -24,7 +24,7 @@ func (v *ValidatingHook) VpcCreateHook(ctx context.Context, req admission.Reques } for _, item := range subnetList.Items { if item.Name == vpc.Name { - err := fmt.Errorf("vpc and subnet cannot have the same name") + err := errors.New("vpc and subnet cannot have the same name") return ctrlwebhook.Errored(http.StatusBadRequest, err) } } @@ -55,8 +55,7 @@ func (v *ValidatingHook) VpcDeleteHook(_ context.Context, req admission.Request) return ctrlwebhook.Errored(http.StatusBadRequest, err) } if len(vpc.Status.Subnets) != 0 { - err := fmt.Errorf("can't delete vpc when any subnet in the vpc") - return ctrlwebhook.Denied(err.Error()) + return ctrlwebhook.Denied("can't delete vpc when any subnet in the vpc") } return ctrlwebhook.Allowed("by pass") } diff --git a/pkg/webhook/vpc_nat_gateway.go b/pkg/webhook/vpc_nat_gateway.go index 91c8042ef764..f31f199bf573 100644 --- a/pkg/webhook/vpc_nat_gateway.go +++ b/pkg/webhook/vpc_nat_gateway.go @@ -2,6 +2,7 @@ package webhook import ( "context" + "errors" "fmt" "net" "net/http" @@ -320,8 +321,7 @@ func (v *ValidatingHook) iptablesFipUpdateHook(ctx context.Context, req admissio func (v *ValidatingHook) ValidateVpcNatGW(ctx context.Context, gw *ovnv1.VpcNatGateway) error { if gw.Spec.Vpc == "" { - err := fmt.Errorf("parameter \"vpc\" cannot be empty") - return err + return errors.New("parameter \"vpc\" cannot be empty") } vpc := &ovnv1.Vpc{} key := types.NamespacedName{Name: gw.Spec.Vpc} @@ -330,8 +330,7 @@ func (v *ValidatingHook) ValidateVpcNatGW(ctx context.Context, gw *ovnv1.VpcNatG } if gw.Spec.Subnet == "" { - err := fmt.Errorf("parameter \"subnet\" cannot be empty") - return err + return errors.New("parameter \"subnet\" cannot be empty") } subnet := &ovnv1.Subnet{} @@ -354,14 +353,14 @@ func (v *ValidatingHook) ValidateVpcNatGW(ctx context.Context, gw *ovnv1.VpcNatG for _, t := range gw.Spec.Tolerations { if t.Operator != corev1.TolerationOpExists && t.Operator != corev1.TolerationOpEqual { - err := fmt.Errorf("invaild taint operator: %s, supported params: \"Equal\", \"Exists\"", t.Operator) + err := fmt.Errorf("invalid taint operator: %s, supported params: \"Equal\", \"Exists\"", t.Operator) return err } if t.Effect != corev1.TaintEffectNoSchedule && t.Effect != corev1.TaintEffectNoExecute && t.Effect != corev1.TaintEffectPreferNoSchedule { - err := fmt.Errorf("invaild taint effect: %s, supported params: \"NoSchedule\", \"PreferNoSchedule\", \"NoExecute\"", t.Effect) + err := fmt.Errorf("invalid taint effect: %s, supported params: \"NoSchedule\", \"PreferNoSchedule\", \"NoExecute\"", t.Effect) return err } } @@ -397,8 +396,7 @@ func (v *ValidatingHook) ValidateVpcNatGatewayConfig(ctx context.Context) error func (v *ValidatingHook) ValidateIptablesEIP(ctx context.Context, eip *ovnv1.IptablesEIP) error { if eip.Spec.NatGwDp == "" { - err := fmt.Errorf("parameter \"natGwDp\" cannot be empty") - return err + return errors.New("parameter \"natGwDp\" cannot be empty") } subnet := &ovnv1.Subnet{} @@ -410,8 +408,7 @@ func (v *ValidatingHook) ValidateIptablesEIP(ctx context.Context, eip *ovnv1.Ipt if eip.Spec.V4ip != "" { if net.ParseIP(eip.Spec.V4ip) == nil { - err := fmt.Errorf("v4ip %s is not a valid", eip.Spec.V4ip) - return err + return fmt.Errorf("v4ip %s is not a valid", eip.Spec.V4ip) } if !util.CIDRContainIP(subnet.Spec.CIDRBlock, eip.Spec.V4ip) { @@ -439,8 +436,7 @@ func (v *ValidatingHook) ValidateIptablesEIP(ctx context.Context, eip *ovnv1.Ipt func (v *ValidatingHook) ValidateIptablesDnat(ctx context.Context, dnat *ovnv1.IptablesDnatRule) error { if dnat.Spec.EIP == "" { - err := fmt.Errorf("parameter \"eip\" cannot be empty") - return err + return errors.New("parameter \"eip\" cannot be empty") } eip := &ovnv1.IptablesEIP{} key := types.NamespacedName{Name: dnat.Spec.EIP} @@ -449,17 +445,15 @@ func (v *ValidatingHook) ValidateIptablesDnat(ctx context.Context, dnat *ovnv1.I } if dnat.Spec.ExternalPort == "" { - err := fmt.Errorf("parameter \"externalPort\" cannot be empty") - return err + return errors.New("parameter \"externalPort\" cannot be empty") } if dnat.Spec.InternalPort == "" { - err := fmt.Errorf("parameter \"internalPort\" cannot be empty") - return err + return errors.New("parameter \"internalPort\" cannot be empty") } if port, err := strconv.Atoi(dnat.Spec.ExternalPort); err != nil { - errMsg := fmt.Errorf("failed to parse externalPort %s: %v", dnat.Spec.ExternalPort, err) + errMsg := fmt.Errorf("failed to parse externalPort %s: %w", dnat.Spec.ExternalPort, err) return errMsg } else if port < 0 || port > 65535 { err := fmt.Errorf("externalPort %s is not a valid port", dnat.Spec.ExternalPort) @@ -467,7 +461,7 @@ func (v *ValidatingHook) ValidateIptablesDnat(ctx context.Context, dnat *ovnv1.I } if port, err := strconv.Atoi(dnat.Spec.InternalPort); err != nil { - errMsg := fmt.Errorf("failed to parse internalIP %s: %v", dnat.Spec.InternalPort, err) + errMsg := fmt.Errorf("failed to parse internalIP %s: %w", dnat.Spec.InternalPort, err) return errMsg } else if port < 0 || port > 65535 { err := fmt.Errorf("internalIP %s is not a valid port", dnat.Spec.InternalPort) @@ -481,7 +475,7 @@ func (v *ValidatingHook) ValidateIptablesDnat(ctx context.Context, dnat *ovnv1.I if !strings.EqualFold(dnat.Spec.Protocol, "tcp") && !strings.EqualFold(dnat.Spec.Protocol, "udp") { - err := fmt.Errorf("invaild iptable protocol: %s,supported params: \"tcp\", \"udp\"", dnat.Spec.Protocol) + err := fmt.Errorf("invalid iptable protocol: %s,supported params: \"tcp\", \"udp\"", dnat.Spec.Protocol) return err } @@ -490,8 +484,7 @@ func (v *ValidatingHook) ValidateIptablesDnat(ctx context.Context, dnat *ovnv1.I func (v *ValidatingHook) ValidateIptablesSnat(ctx context.Context, snat *ovnv1.IptablesSnatRule) error { if snat.Spec.EIP == "" { - err := fmt.Errorf("parameter \"eip\" cannot be empty") - return err + return errors.New("parameter \"eip\" cannot be empty") } eip := &ovnv1.IptablesEIP{} key := types.NamespacedName{Name: snat.Spec.EIP} @@ -508,7 +501,7 @@ func (v *ValidatingHook) ValidateIptablesSnat(ctx context.Context, snat *ovnv1.I func (v *ValidatingHook) ValidateIptablesFip(ctx context.Context, fip *ovnv1.IptablesFIPRule) error { if fip.Spec.EIP == "" { - err := fmt.Errorf("parameter \"eip\" cannot be empty") + err := errors.New("parameter \"eip\" cannot be empty") return err } eip := &ovnv1.IptablesEIP{} diff --git a/test/e2e/framework/deployment.go b/test/e2e/framework/deployment.go index c6392a6ea588..1a04b0c786f8 100644 --- a/test/e2e/framework/deployment.go +++ b/test/e2e/framework/deployment.go @@ -180,7 +180,7 @@ func (c *DeploymentClient) SetScale(deployment string, replicas int32) { scale, err := c.GetScale(context.Background(), deployment, metav1.GetOptions{}) framework.ExpectNoError(err) if scale.Spec.Replicas == replicas { - Logf("repliacs of deployment %s/%s has already been set to %d", c.namespace, deployment, replicas) + Logf("replicas of deployment %s/%s has already been set to %d", c.namespace, deployment, replicas) return } diff --git a/test/e2e/framework/endpoints.go b/test/e2e/framework/endpoints.go index 6a06e548867b..af2dca93a16a 100644 --- a/test/e2e/framework/endpoints.go +++ b/test/e2e/framework/endpoints.go @@ -123,7 +123,7 @@ func (c *EndpointsClient) WaitUntil(name string, cond func(s *corev1.Endpoints) endpoints = c.Get(name).DeepCopy() met, err := cond(endpoints) if err != nil { - return false, fmt.Errorf("failed to check condition for endpoints %s: %v", name, err) + return false, fmt.Errorf("failed to check condition for endpoints %s: %w", name, err) } if met { Logf("endpoints %s met condition %q", name, condDesc) diff --git a/test/e2e/framework/ippool.go b/test/e2e/framework/ippool.go index bf6f463d12ee..d7f523fd8e63 100644 --- a/test/e2e/framework/ippool.go +++ b/test/e2e/framework/ippool.go @@ -228,7 +228,7 @@ func (c *IPPoolClient) WaitUntil(name string, cond func(s *apiv1.IPPool) (bool, ippool = c.Get(name).DeepCopy() met, err := cond(ippool) if err != nil { - return false, fmt.Errorf("failed to check condition for ippool %s: %v", name, err) + return false, fmt.Errorf("failed to check condition for ippool %s: %w", name, err) } return met, nil }) diff --git a/test/e2e/framework/iproute/iproute.go b/test/e2e/framework/iproute/iproute.go index 7ac28c5d564c..ccab6c1097a2 100644 --- a/test/e2e/framework/iproute/iproute.go +++ b/test/e2e/framework/iproute/iproute.go @@ -98,12 +98,12 @@ func (e *execer) exec(cmd string, result interface{}) error { return nil } } - return fmt.Errorf("failed to exec cmd %q: %v\nstdout:\n%s\nstderr:\n%s", cmd, err, stdout, stderr) + return fmt.Errorf("failed to exec cmd %q: %w\nstdout:\n%s\nstderr:\n%s", cmd, err, stdout, stderr) } if result != nil { if err = json.Unmarshal(stdout, result); err != nil { - return fmt.Errorf("failed to decode json %q: %v", string(stdout), err) + return fmt.Errorf("failed to decode json %q: %w", string(stdout), err) } } diff --git a/test/e2e/framework/kubectl.go b/test/e2e/framework/kubectl.go index 111e1d4b416d..979a8facd0af 100644 --- a/test/e2e/framework/kubectl.go +++ b/test/e2e/framework/kubectl.go @@ -11,7 +11,7 @@ func KubectlExec(namespace, name string, cmd ...string) (stdout, stderr []byte, c := strings.Join(cmd, " ") outStr, errStr, err := e2epodoutput.RunHostCmdWithFullOutput(namespace, name, c) if err != nil { - return nil, nil, fmt.Errorf("failed to exec cmd %q in %s of namespace %s: %v\nstderr:\n%s", c, name, namespace, err, errStr) + return nil, nil, fmt.Errorf("failed to exec cmd %q in %s of namespace %s: %w\nstderr:\n%s", c, name, namespace, err, errStr) } return []byte(outStr), []byte(errStr), nil @@ -21,7 +21,7 @@ func ovnExecSvc(db string, cmd ...string) (stdout, stderr []byte, err error) { c := strings.Join(cmd, " ") outStr, errStr, err := e2epodoutput.RunHostCmdWithFullOutput(KubeOvnNamespace, "svc/ovn-"+db, c) if err != nil { - return nil, nil, fmt.Errorf("failed to exec ovn %s cmd %q: %v\nstderr:\n%s", db, c, err, errStr) + return nil, nil, fmt.Errorf("failed to exec ovn %s cmd %q: %w\nstderr:\n%s", db, c, err, errStr) } return []byte(outStr), []byte(errStr), nil diff --git a/test/e2e/framework/qos-policy.go b/test/e2e/framework/qos-policy.go index 6dd9dcbf5e31..5cb2696e0ab4 100644 --- a/test/e2e/framework/qos-policy.go +++ b/test/e2e/framework/qos-policy.go @@ -228,7 +228,7 @@ func (c *QoSPolicyClient) WaitUntil(name string, cond func(s *apiv1.QoSPolicy) ( qosPolicy = c.Get(name).DeepCopy() met, err := cond(qosPolicy) if err != nil { - return false, fmt.Errorf("failed to check condition for qosPolicy %s: %v", name, err) + return false, fmt.Errorf("failed to check condition for qosPolicy %s: %w", name, err) } return met, nil }) diff --git a/test/e2e/framework/service.go b/test/e2e/framework/service.go index 16986706444f..b0ade5ee136f 100644 --- a/test/e2e/framework/service.go +++ b/test/e2e/framework/service.go @@ -122,7 +122,7 @@ func (c *ServiceClient) WaitUntil(name string, cond func(s *corev1.Service) (boo service = c.Get(name).DeepCopy() met, err := cond(service) if err != nil { - return false, fmt.Errorf("failed to check condition for service %s: %v", name, err) + return false, fmt.Errorf("failed to check condition for service %s: %w", name, err) } if met { Logf("service %s met condition %q", name, condDesc) diff --git a/test/e2e/framework/subnet.go b/test/e2e/framework/subnet.go index 96fc06d4b299..8c52202f9448 100644 --- a/test/e2e/framework/subnet.go +++ b/test/e2e/framework/subnet.go @@ -229,7 +229,7 @@ func (c *SubnetClient) WaitUntil(name string, cond func(s *apiv1.Subnet) (bool, subnet = c.Get(name).DeepCopy() met, err := cond(subnet) if err != nil { - return false, fmt.Errorf("failed to check condition for subnet %s: %v", name, err) + return false, fmt.Errorf("failed to check condition for subnet %s: %w", name, err) } return met, nil }) diff --git a/test/e2e/framework/switch-lb-rule.go b/test/e2e/framework/switch-lb-rule.go index 68dad61fbc60..699172a7356e 100644 --- a/test/e2e/framework/switch-lb-rule.go +++ b/test/e2e/framework/switch-lb-rule.go @@ -124,7 +124,7 @@ func (c *SwitchLBRuleClient) WaitUntil(name string, cond func(s *apiv1.SwitchLBR rules = c.Get(name).DeepCopy() met, err := cond(rules) if err != nil { - return false, fmt.Errorf("failed to check condition for switch-lb-rule %s: %v", name, err) + return false, fmt.Errorf("failed to check condition for switch-lb-rule %s: %w", name, err) } if met { Logf("switch-lb-rule %s met condition %q", name, condDesc) @@ -160,7 +160,7 @@ func (c *SwitchLBRuleClient) WaitToDisappear(name string, _, timeout time.Durati return nil } -func MakeSwitchLBRule(name, namespace, vip string, sessionAffinity corev1.ServiceAffinity, annotations map[string]string, slector, endpoints []string, ports []apiv1.SlrPort) *apiv1.SwitchLBRule { +func MakeSwitchLBRule(name, namespace, vip string, sessionAffinity corev1.ServiceAffinity, annotations map[string]string, selector, endpoints []string, ports []apiv1.SlrPort) *apiv1.SwitchLBRule { return &apiv1.SwitchLBRule{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -170,7 +170,7 @@ func MakeSwitchLBRule(name, namespace, vip string, sessionAffinity corev1.Servic Spec: apiv1.SwitchLBRuleSpec{ Vip: vip, Namespace: namespace, - Selector: slector, + Selector: selector, Endpoints: endpoints, SessionAffinity: string(sessionAffinity), Ports: ports, diff --git a/test/e2e/framework/virtual-machine.go b/test/e2e/framework/virtual-machine.go index c62a370d4220..fa302f3b1997 100644 --- a/test/e2e/framework/virtual-machine.go +++ b/test/e2e/framework/virtual-machine.go @@ -37,7 +37,7 @@ func (f *Framework) VMClientNS(namespace string) *VMClient { func (c *VMClient) Get(name string) *v1.VirtualMachine { ginkgo.GinkgoHelper() - vm, err := c.VirtualMachineInterface.Get(context.TODO(), name, &metav1.GetOptions{}) + vm, err := c.VirtualMachineInterface.Get(context.TODO(), name, metav1.GetOptions{}) ExpectNoError(err) return vm } @@ -45,7 +45,7 @@ func (c *VMClient) Get(name string) *v1.VirtualMachine { // Create creates a new vm according to the framework specifications func (c *VMClient) Create(vm *v1.VirtualMachine) *v1.VirtualMachine { ginkgo.GinkgoHelper() - v, err := c.VirtualMachineInterface.Create(context.TODO(), vm) + v, err := c.VirtualMachineInterface.Create(context.TODO(), vm, metav1.CreateOptions{}) ExpectNoError(err, "failed to create vm %s", v.Name) return c.Get(v.Name) } @@ -72,7 +72,7 @@ func (c *VMClient) Start(name string) *v1.VirtualMachine { running := true vm.Spec.Running = &running - _, err := c.VirtualMachineInterface.Update(context.TODO(), vm) + _, err := c.VirtualMachineInterface.Update(context.TODO(), vm, metav1.UpdateOptions{}) ExpectNoError(err, "failed to update vm %s", name) return c.Get(name) } @@ -97,7 +97,7 @@ func (c *VMClient) Stop(name string) *v1.VirtualMachine { running := false vm.Spec.Running = &running - _, err := c.VirtualMachineInterface.Update(context.TODO(), vm) + _, err := c.VirtualMachineInterface.Update(context.TODO(), vm, metav1.UpdateOptions{}) ExpectNoError(err, "failed to update vm %s", name) return c.Get(name) } @@ -113,7 +113,7 @@ func (c *VMClient) StopSync(name string) *v1.VirtualMachine { // Delete deletes a vm if the vm exists func (c *VMClient) Delete(name string) { ginkgo.GinkgoHelper() - err := c.VirtualMachineInterface.Delete(context.TODO(), name, &metav1.DeleteOptions{}) + err := c.VirtualMachineInterface.Delete(context.TODO(), name, metav1.DeleteOptions{}) ExpectNoError(err, "failed to delete vm %s", name) } @@ -128,7 +128,7 @@ func (c *VMClient) DeleteSync(name string) { // WaitToDisappear waits the given timeout duration for the specified vm to be ready. func (c *VMClient) WaitToBeReady(name string, timeout time.Duration) error { err := k8sframework.Gomega().Eventually(context.TODO(), k8sframework.RetryNotFound(func(ctx context.Context) (*v1.VirtualMachine, error) { - return c.VirtualMachineInterface.Get(ctx, name, &metav1.GetOptions{}) + return c.VirtualMachineInterface.Get(ctx, name, metav1.GetOptions{}) })).WithTimeout(timeout).Should( k8sframework.MakeMatcher(func(vm *v1.VirtualMachine) (func() string, error) { if vm.Status.Ready { @@ -147,7 +147,7 @@ func (c *VMClient) WaitToBeReady(name string, timeout time.Duration) error { // WaitToDisappear waits the given timeout duration for the specified vm to be stopped. func (c *VMClient) WaitToBeStopped(name string, timeout time.Duration) error { err := k8sframework.Gomega().Eventually(context.TODO(), k8sframework.RetryNotFound(func(ctx context.Context) (*v1.VirtualMachine, error) { - return c.VirtualMachineInterface.Get(ctx, name, &metav1.GetOptions{}) + return c.VirtualMachineInterface.Get(ctx, name, metav1.GetOptions{}) })).WithTimeout(timeout).Should( k8sframework.MakeMatcher(func(vm *v1.VirtualMachine) (func() string, error) { if !vm.Status.Created { @@ -166,7 +166,7 @@ func (c *VMClient) WaitToBeStopped(name string, timeout time.Duration) error { // WaitToDisappear waits the given timeout duration for the specified vm to disappear. func (c *VMClient) WaitToDisappear(name string, _, timeout time.Duration) error { err := k8sframework.Gomega().Eventually(context.Background(), k8sframework.HandleRetry(func(ctx context.Context) (*v1.VirtualMachine, error) { - vm, err := c.VirtualMachineInterface.Get(ctx, name, &metav1.GetOptions{}) + vm, err := c.VirtualMachineInterface.Get(ctx, name, metav1.GetOptions{}) if apierrors.IsNotFound(err) { return nil, nil } diff --git a/test/e2e/framework/wait.go b/test/e2e/framework/wait.go index b71dd08bb038..cf445c7564d4 100644 --- a/test/e2e/framework/wait.go +++ b/test/e2e/framework/wait.go @@ -28,9 +28,9 @@ import ( "github.com/onsi/ginkgo/v2" ) -// handleWaitingAPIErrror handles an error from an API request in the context of a Wait function. +// handleWaitingAPIError handles an error from an API request in the context of a Wait function. // If the error is retryable, sleep the recommended delay and ignore the error. -// If the erorr is terminal, return it. +// If the error is terminal, return it. func handleWaitingAPIError(err error, retryNotFound bool, taskFormat string, taskArgs ...interface{}) (bool, error) { taskDescription := fmt.Sprintf(taskFormat, taskArgs...) if retryNotFound && apierrors.IsNotFound(err) { diff --git a/test/e2e/ha/ha_test.go b/test/e2e/ha/ha_test.go index 0ec5032bc3ab..8edf62deda9d 100644 --- a/test/e2e/ha/ha_test.go +++ b/test/e2e/ha/ha_test.go @@ -75,7 +75,7 @@ var _ = framework.Describe("[group:ha]", func() { }, "") db := "/etc/ovn/ovnnb_db.db" - checkCmd := fmt.Sprintf("ovsdb-tool check-cluster " + db) + checkCmd := fmt.Sprintf("ovsdb-tool check-cluster %s", db) corruptCmd := fmt.Sprintf(`bash -c 'dd if=/dev/zero of="%s" bs=1 count=$((10+$RANDOM%%10)) seek=$(stat -c %%s "%s")'`, db, db) for _, node := range nodes { ginkgo.By("Getting ovs-ovn pod running on node " + node) diff --git a/test/e2e/iptables-vpc-nat-gw/e2e_test.go b/test/e2e/iptables-vpc-nat-gw/e2e_test.go index d22a96c5c627..960c65eaf80e 100644 --- a/test/e2e/iptables-vpc-nat-gw/e2e_test.go +++ b/test/e2e/iptables-vpc-nat-gw/e2e_test.go @@ -681,16 +681,16 @@ func getNicDefaultQoSPolicy(limit int) apiv1.QoSPolicyBandwidthLimitRules { &apiv1.QoSPolicyBandwidthLimitRule{ Name: "net1-ingress", Interface: "net1", - RateMax: fmt.Sprint(limit), - BurstMax: fmt.Sprint(limit), + RateMax: strconv.Itoa(limit), + BurstMax: strconv.Itoa(limit), Priority: 3, Direction: apiv1.DirectionIngress, }, &apiv1.QoSPolicyBandwidthLimitRule{ Name: "net1-egress", Interface: "net1", - RateMax: fmt.Sprint(limit), - BurstMax: fmt.Sprint(limit), + RateMax: strconv.Itoa(limit), + BurstMax: strconv.Itoa(limit), Priority: 3, Direction: apiv1.DirectionEgress, }, @@ -701,15 +701,15 @@ func getEIPQoSRule(limit int) apiv1.QoSPolicyBandwidthLimitRules { return apiv1.QoSPolicyBandwidthLimitRules{ &apiv1.QoSPolicyBandwidthLimitRule{ Name: "eip-ingress", - RateMax: fmt.Sprint(limit), - BurstMax: fmt.Sprint(limit), + RateMax: strconv.Itoa(limit), + BurstMax: strconv.Itoa(limit), Priority: 1, Direction: apiv1.DirectionIngress, }, &apiv1.QoSPolicyBandwidthLimitRule{ Name: "eip-egress", - RateMax: fmt.Sprint(limit), - BurstMax: fmt.Sprint(limit), + RateMax: strconv.Itoa(limit), + BurstMax: strconv.Itoa(limit), Priority: 1, Direction: apiv1.DirectionEgress, }, @@ -721,8 +721,8 @@ func getSpecialQoSRule(limit int, ip string) apiv1.QoSPolicyBandwidthLimitRules &apiv1.QoSPolicyBandwidthLimitRule{ Name: "net1-extip-ingress", Interface: "net1", - RateMax: fmt.Sprint(limit), - BurstMax: fmt.Sprint(limit), + RateMax: strconv.Itoa(limit), + BurstMax: strconv.Itoa(limit), Priority: 2, Direction: apiv1.DirectionIngress, MatchType: apiv1.MatchTypeIP, @@ -731,8 +731,8 @@ func getSpecialQoSRule(limit int, ip string) apiv1.QoSPolicyBandwidthLimitRules &apiv1.QoSPolicyBandwidthLimitRule{ Name: "net1-extip-egress", Interface: "net1", - RateMax: fmt.Sprint(limit), - BurstMax: fmt.Sprint(limit), + RateMax: strconv.Itoa(limit), + BurstMax: strconv.Itoa(limit), Priority: 2, Direction: apiv1.DirectionEgress, MatchType: apiv1.MatchTypeIP, @@ -765,7 +765,7 @@ func defaultQoSCases(f *framework.Framework, ginkgo.By("Patch natgw " + natgwName + " with qos policy " + qosPolicyName) _ = vpcNatGwClient.PatchQoSPolicySync(natgwName, qosPolicyName) - ginkgo.By("Check qos " + qosPolicyName + " is limited to " + fmt.Sprint(defaultNicLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is limited to " + strconv.Itoa(defaultNicLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, defaultNicLimit, true) ginkgo.By("Delete natgw pod " + natgwName + "-0") @@ -775,7 +775,7 @@ func defaultQoSCases(f *framework.Framework, ginkgo.By("Wait for natgw " + natgwName + "qos rebuild") time.Sleep(5 * time.Second) - ginkgo.By("Check qos " + qosPolicyName + " is limited to " + fmt.Sprint(defaultNicLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is limited to " + strconv.Itoa(defaultNicLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, defaultNicLimit, true) ginkgo.By("Remove qos policy " + qosPolicyName + " from natgw " + natgwName) @@ -784,7 +784,7 @@ func defaultQoSCases(f *framework.Framework, ginkgo.By("Deleting qos policy " + qosPolicyName) qosPolicyClient.DeleteSync(qosPolicyName) - ginkgo.By("Check qos " + qosPolicyName + " is not limited to " + fmt.Sprint(defaultNicLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is not limited to " + strconv.Itoa(defaultNicLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, defaultNicLimit, false) } @@ -813,7 +813,7 @@ func eipQoSCases(f *framework.Framework, ginkgo.By("Patch eip " + eipName + " with qos policy " + qosPolicyName) _ = eipClient.PatchQoSPolicySync(eipName, qosPolicyName) - ginkgo.By("Check qos " + qosPolicyName + " is limited to " + fmt.Sprint(eipLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is limited to " + strconv.Itoa(eipLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, eipLimit, true) ginkgo.By("Update qos policy " + qosPolicyName + " with new rate limit") @@ -824,7 +824,7 @@ func eipQoSCases(f *framework.Framework, qosPolicyClient.Patch(qosPolicy, modifiedqosPolicy) qosPolicyClient.WaitToQoSReady(qosPolicyName) - ginkgo.By("Check qos " + qosPolicyName + " is changed to " + fmt.Sprint(updatedEIPLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is changed to " + strconv.Itoa(updatedEIPLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, updatedEIPLimit, true) ginkgo.By("Delete natgw pod " + natgwName + "-0") @@ -834,7 +834,7 @@ func eipQoSCases(f *framework.Framework, ginkgo.By("Wait for natgw " + natgwName + "qos rebuid") time.Sleep(5 * time.Second) - ginkgo.By("Check qos " + qosPolicyName + " is limited to " + fmt.Sprint(updatedEIPLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is limited to " + strconv.Itoa(updatedEIPLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, updatedEIPLimit, true) newQoSPolicyName := "new-eip-qos-policy-" + framework.RandomSuffix() @@ -845,7 +845,7 @@ func eipQoSCases(f *framework.Framework, ginkgo.By("Change qos policy of eip " + eipName + " to " + newQoSPolicyName) _ = eipClient.PatchQoSPolicySync(eipName, newQoSPolicyName) - ginkgo.By("Check qos " + qosPolicyName + " is limited to " + fmt.Sprint(newEIPLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is limited to " + strconv.Itoa(newEIPLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, newEIPLimit, true) ginkgo.By("Remove qos policy " + qosPolicyName + " from natgw " + eipName) @@ -857,7 +857,7 @@ func eipQoSCases(f *framework.Framework, ginkgo.By("Deleting qos policy " + newQoSPolicyName) qosPolicyClient.DeleteSync(newQoSPolicyName) - ginkgo.By("Check qos " + qosPolicyName + " is not limited to " + fmt.Sprint(newEIPLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is not limited to " + strconv.Itoa(newEIPLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, newEIPLimit, false) } @@ -885,7 +885,7 @@ func specifyingIPQoSCases(f *framework.Framework, ginkgo.By("Patch natgw " + natgwName + " with qos policy " + qosPolicyName) _ = vpcNatGwClient.PatchQoSPolicySync(natgwName, qosPolicyName) - ginkgo.By("Check qos " + qosPolicyName + " is limited to " + fmt.Sprint(specificIPLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is limited to " + strconv.Itoa(specificIPLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, specificIPLimit, true) ginkgo.By("Remove qos policy " + qosPolicyName + " from natgw " + natgwName) @@ -894,7 +894,7 @@ func specifyingIPQoSCases(f *framework.Framework, ginkgo.By("Deleting qos policy " + qosPolicyName) qosPolicyClient.DeleteSync(qosPolicyName) - ginkgo.By("Check qos " + qosPolicyName + " is not limited to " + fmt.Sprint(specificIPLimit) + "Mbps") + ginkgo.By("Check qos " + qosPolicyName + " is not limited to " + strconv.Itoa(specificIPLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, specificIPLimit, false) } @@ -936,7 +936,7 @@ func priorityQoSCases(f *framework.Framework, _ = eipClient.PatchQoSPolicySync(eipName, eipQoSPolicyName) // match qos of priority 1 - ginkgo.By("Check qos to match priority 1 is limited to " + fmt.Sprint(eipLimit) + "Mbps") + ginkgo.By("Check qos to match priority 1 is limited to " + strconv.Itoa(eipLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, eipLimit, true) ginkgo.By("Remove qos policy " + eipQoSPolicyName + " from natgw " + eipName) @@ -946,7 +946,7 @@ func priorityQoSCases(f *framework.Framework, qosPolicyClient.DeleteSync(eipQoSPolicyName) // match qos of priority 2 - ginkgo.By("Check qos to match priority 2 is limited to " + fmt.Sprint(specificIPLimit) + "Mbps") + ginkgo.By("Check qos to match priority 2 is limited to " + strconv.Itoa(specificIPLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, specificIPLimit, true) // change qos policy of natgw @@ -961,7 +961,7 @@ func priorityQoSCases(f *framework.Framework, _ = vpcNatGwClient.PatchQoSPolicySync(natgwName, newNatGwQoSPolicyName) // match qos of priority 3 - ginkgo.By("Check qos to match priority 3 is limited to " + fmt.Sprint(specificIPLimit) + "Mbps") + ginkgo.By("Check qos to match priority 3 is limited to " + strconv.Itoa(specificIPLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, defaultNicLimit, true) ginkgo.By("Remove qos policy " + natGwQoSPolicyName + " from natgw " + natgwName) @@ -973,7 +973,7 @@ func priorityQoSCases(f *framework.Framework, ginkgo.By("Deleting qos policy " + newNatGwQoSPolicyName) qosPolicyClient.DeleteSync(newNatGwQoSPolicyName) - ginkgo.By("Check qos " + natGwQoSPolicyName + " is not limited to " + fmt.Sprint(defaultNicLimit) + "Mbps") + ginkgo.By("Check qos " + natGwQoSPolicyName + " is not limited to " + strconv.Itoa(defaultNicLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, defaultNicLimit, false) } @@ -1046,19 +1046,19 @@ func createNatGwAndSetQosCases(f *framework.Framework, fip := framework.MakeIptablesFIPRule(fipName, eipName, vpc1Pod.Status.PodIP) _ = fipClient.CreateSync(fip) - ginkgo.By("Check qos " + eipQoSPolicyName + " is limited to " + fmt.Sprint(eipLimit) + "Mbps") + ginkgo.By("Check qos " + eipQoSPolicyName + " is limited to " + strconv.Itoa(eipLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, eipLimit, true) ginkgo.By("Remove qos policy " + eipQoSPolicyName + " from natgw " + natgwName) _ = eipClient.PatchQoSPolicySync(eipName, "") - ginkgo.By("Check qos " + natgwQoSPolicyName + " is limited to " + fmt.Sprint(defaultNicLimit) + "Mbps") + ginkgo.By("Check qos " + natgwQoSPolicyName + " is limited to " + strconv.Itoa(defaultNicLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, defaultNicLimit, true) ginkgo.By("Remove qos policy " + natgwQoSPolicyName + " from natgw " + natgwName) _ = vpcNatGwClient.PatchQoSPolicySync(natgwName, "") - ginkgo.By("Check qos " + natgwQoSPolicyName + " is not limited to " + fmt.Sprint(defaultNicLimit) + "Mbps") + ginkgo.By("Check qos " + natgwQoSPolicyName + " is not limited to " + strconv.Itoa(defaultNicLimit) + "Mbps") checkQos(f, vpc1Pod, vpc2Pod, vpc1EIP, vpc2EIP, defaultNicLimit, false) ginkgo.By("Deleting qos policy " + natgwQoSPolicyName) diff --git a/test/e2e/kube-ovn/pod/pod_recreation.go b/test/e2e/kube-ovn/pod/pod_recreation.go index c8af23259878..923b6bf6a635 100644 --- a/test/e2e/kube-ovn/pod/pod_recreation.go +++ b/test/e2e/kube-ovn/pod/pod_recreation.go @@ -35,7 +35,7 @@ var _ = framework.SerialDescribe("[group:pod]", func() { pod := framework.MakePod(namespaceName, podName, nil, nil, framework.PauseImage, nil, nil) pod = podClient.CreateSync(pod) - ginkgo.By("Validating pod annoations") + ginkgo.By("Validating pod annotations") framework.ExpectHaveKeyWithValue(pod.Annotations, util.AllocatedAnnotation, "true") framework.ExpectMAC(pod.Annotations[util.MacAddressAnnotation]) framework.ExpectHaveKeyWithValue(pod.Annotations, util.RoutedAnnotation, "true") @@ -92,7 +92,7 @@ var _ = framework.SerialDescribe("[group:pod]", func() { ginkgo.By("Waiting for pod " + podName + " to be running") podClient.WaitForRunning(podName) - ginkgo.By("Validating pod annoations") + ginkgo.By("Validating pod annotations") pod = podClient.GetPod(podName) framework.ExpectHaveKeyWithValue(pod.Annotations, util.AllocatedAnnotation, "true") framework.ExpectMAC(pod.Annotations[util.MacAddressAnnotation]) diff --git a/test/e2e/kube-ovn/pod/pod _routes.go b/test/e2e/kube-ovn/pod/pod_routes.go similarity index 53% rename from test/e2e/kube-ovn/pod/pod _routes.go rename to test/e2e/kube-ovn/pod/pod_routes.go index 6ffb63991e8d..4fd15d50a10a 100644 --- a/test/e2e/kube-ovn/pod/pod _routes.go +++ b/test/e2e/kube-ovn/pod/pod_routes.go @@ -1,10 +1,14 @@ package pod import ( + "context" "encoding/json" + "fmt" "strings" + "time" "github.com/onsi/ginkgo/v2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apiv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" "github.com/kubeovn/kube-ovn/pkg/request" @@ -13,7 +17,7 @@ import ( "github.com/kubeovn/kube-ovn/test/e2e/framework/iproute" ) -var _ = framework.Describe("[group:pod]", func() { +var _ = framework.SerialDescribe("[group:pod]", func() { f := framework.NewDefaultFramework("pod") var podClient *framework.PodClient @@ -37,6 +41,73 @@ var _ = framework.Describe("[group:pod]", func() { subnetClient.DeleteSync(subnetName) }) + framework.ConformanceIt("should support north gateway via pod annotation", func() { + f.SkipVersionPriorTo(1, 12, "This feature was introduced in v1.12") + if f.ClusterNetworkMode == "underlay" { + ginkgo.Skip("This test is only for overlay network") + } + + ginkgo.By("Creating pod " + podName + " with north gateway annotation") + northGateway := "100.64.0.100" + ipSuffix := "ip4" + if f.ClusterIPFamily == "ipv6" { + northGateway = "fd00:100:64::100" + ipSuffix = "ip6" + } + + annotations := map[string]string{ + util.NorthGatewayAnnotation: northGateway, + } + cmd := []string{"sh", "-c", "sleep infinity"} + pod := framework.MakePod(namespaceName, podName, nil, annotations, f.KubeOVNImage, cmd, nil) + pod = podClient.CreateSync(pod) + + podIP := pod.Status.PodIP + nbCmd := fmt.Sprintf("ovn-nbctl --format=csv --data=bare --no-heading --columns=match,action,nexthops find logical_router_policy priority=%d", util.NorthGatewayRoutePolicyPriority) + out, _, err := framework.NBExec(nbCmd) + framework.ExpectNoError(err) + framework.ExpectEqual(strings.TrimSpace(string(out)), fmt.Sprintf("%s.src == %s,reroute,%s", ipSuffix, podIP, northGateway)) + + ginkgo.By("Deleting pod " + podName + " with north gateway annotation") + f.PodClientNS(namespaceName).DeleteSync(podName) + framework.WaitUntil(2*time.Second, 2*time.Minute, func(_ context.Context) (bool, error) { + out, _, err = framework.NBExec(nbCmd) + if err == nil && strings.TrimSpace(string(out)) == "" { + return true, nil + } + return false, err + }, "policy has been gc") + + ginkgo.By("gc policy route") + podClient.CreateSync(framework.MakePod(namespaceName, podName, nil, annotations, f.KubeOVNImage, cmd, nil)) + + ginkgo.By("restart kube-ovn-controller") + deployClient := f.DeploymentClientNS(framework.KubeOvnNamespace) + deploy := deployClient.Get("kube-ovn-controller") + framework.ExpectNotNil(deploy.Spec.Replicas) + deployClient.SetScale(deploy.Name, 0) + deployClient.RolloutStatus(deploy.Name) + + f.PodClientNS(namespaceName).DeleteSync(podName) + + deployClient.SetScale(deploy.Name, 1) + deployClient.RolloutStatus(deploy.Name) + + framework.WaitUntil(2*time.Second, 2*time.Minute, func(_ context.Context) (bool, error) { + out, _, err = framework.NBExec(nbCmd) + if err == nil && strings.TrimSpace(string(out)) == "" { + return true, nil + } + return false, err + }, "policy has been gc") + + ginkgo.By("remove legacy lsp") + deleteLspCmd := fmt.Sprintf("ovn-nbctl --if-exists lsp-del %s.%s", pod.Name, pod.Namespace) + _, _, err = framework.NBExec(deleteLspCmd) + framework.ExpectNoError(err) + err = f.KubeOVNClientSet.KubeovnV1().IPs().Delete(context.Background(), fmt.Sprintf("%s.%s", pod.Name, pod.Namespace), metav1.DeleteOptions{}) + }) + framework.ConformanceIt("should support configuring routes via pod annotation", func() { f.SkipVersionPriorTo(1, 12, "This feature was introduced in v1.12") @@ -70,7 +141,7 @@ var _ = framework.Describe("[group:pod]", func() { pod := framework.MakePod(namespaceName, podName, nil, annotations, f.KubeOVNImage, cmd, nil) pod = podClient.CreateSync(pod) - ginkgo.By("Validating pod annoations") + ginkgo.By("Validating pod annotations") framework.ExpectHaveKeyWithValue(pod.Annotations, util.AllocatedAnnotation, "true") framework.ExpectHaveKeyWithValue(pod.Annotations, util.CidrAnnotation, subnet.Spec.CIDRBlock) framework.ExpectHaveKeyWithValue(pod.Annotations, util.GatewayAnnotation, subnet.Spec.Gateway) diff --git a/test/e2e/kube-ovn/underlay/underlay.go b/test/e2e/kube-ovn/underlay/underlay.go index 7d63c539f9c1..bd7c28ff84bb 100644 --- a/test/e2e/kube-ovn/underlay/underlay.go +++ b/test/e2e/kube-ovn/underlay/underlay.go @@ -2,6 +2,7 @@ package underlay import ( "context" + "errors" "fmt" "net" "os/exec" @@ -1114,7 +1115,7 @@ func checkU2OFilterOpenFlowExist(clusterName string, pn *apiv1.ProviderNetwork, return fmt.Errorf("getting nodes in kind cluster: %w", err) } if len(nodes) == 0 { - return fmt.Errorf("no nodes found in kind cluster") + return errors.New("no nodes found in kind cluster") } for _, node := range nodes { @@ -1153,9 +1154,9 @@ func checkU2OFilterOpenFlowExist(clusterName string, pn *apiv1.ProviderNetwork, if !success { if expectRuleExist { - return fmt.Errorf("expected rule does not exist after 3 attempts") + return errors.New("expected rule does not exist after 3 attempts") } - return fmt.Errorf("unexpected rule exists after 3 attempts") + return errors.New("unexpected rule exists after 3 attempts") } } } diff --git a/test/server/server.go b/test/server/server.go index 0aa15fd4d628..49dcc438f6b4 100644 --- a/test/server/server.go +++ b/test/server/server.go @@ -96,7 +96,7 @@ func main() { config := parseFlag() go func() { - output, err := exec.Command("ping", "-D", "-O", "-c", fmt.Sprintf("%d", config.DurationSeconds*100), "-i", "0.01", config.RemoteAddress).CombinedOutput() + output, err := exec.Command("ping", "-D", "-O", "-c", strconv.Itoa(int(config.DurationSeconds*100)), "-i", "0.01", config.RemoteAddress).CombinedOutput() if err != nil { klog.Errorf("%s, %v", output, err) } diff --git a/yamls/adminnetworkpolicies-v0.1.5.yaml b/yamls/adminnetworkpolicies-v0.1.5.yaml new file mode 100644 index 000000000000..41c95048b83a --- /dev/null +++ b/yamls/adminnetworkpolicies-v0.1.5.yaml @@ -0,0 +1,969 @@ +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. Policies with lower priority values have + higher precedence, and are checked before policies with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + Every AdminNetworkPolicy should have a unique priority value; if two (or more) + policies with the same priority could both match a connection, then the + implementation can apply any of the matching policies to the connection, and + there is no way for the user to reliably determine which one it will choose. + + + 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/yamls/baselineadminnetworkpolicies-v0.1.5.yaml b/yamls/baselineadminnetworkpolicies-v0.1.5.yaml new file mode 100644 index 000000000000..6d62098da748 --- /dev/null +++ b/yamls/baselineadminnetworkpolicies-v0.1.5.yaml @@ -0,0 +1,941 @@ +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: baselineadminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: BaselineAdminNetworkPolicy + listKind: BaselineAdminNetworkPolicyList + plural: baselineadminnetworkpolicies + shortNames: + - banp + singular: baselineadminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + BaselineAdminNetworkPolicy 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 BaselineAdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods if + they are not matched by any AdminNetworkPolicy or NetworkPolicy rules. + A total of 100 Egress rules will be allowed in each BANP instance. + The relative precedence of egress rules within a single BANP object + 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. + BANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + BaselineAdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a BaselineAdminNetworkPolicy'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 + Deny: denies the selected traffic + + + Support: Core + enum: + - Allow + - Deny + 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 + BaselineAdminNetworkPolicies. + + + 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. + 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 + if they are not matched by any AdminNetworkPolicy or NetworkPolicy rules. + A total of 100 Ingress rules will be allowed in each BANP instance. + The relative precedence of ingress rules within a single BANP object + 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. + BANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + BaselineAdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by a BaselineAdminNetworkPolicy'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 + Deny: denies the selected traffic + + + Support: Core + enum: + - Allow + - Deny + 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 + BaselineAdminNetworkPolicies. + + + 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 + subject: + description: |- + Subject defines the pods to which this BaselineAdminNetworkPolicy 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: + - 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 + x-kubernetes-validations: + - message: Only one baseline admin network policy with metadata.name="default" + can be created in the cluster + rule: self.metadata.name == 'default' + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/yamls/kwok-stage.yaml b/yamls/kwok-stage.yaml index db6451d9589c..805d16ccec01 100644 --- a/yamls/kwok-stage.yaml +++ b/yamls/kwok-stage.yaml @@ -108,19 +108,20 @@ spec: memory: 1Ti pods: 1M {{ end }} - {{ with .status.nodeInfo }} + + {{ $nodeInfo := .status.nodeInfo }} + {{ $kwokVersion := printf "kwok-%s" Version }} nodeInfo: - architecture: {{ with .architecture }} {{ . }} {{ else }} "amd64" {{ end }} - bootID: {{ with .bootID }} {{ . }} {{ else }} "" {{ end }} - containerRuntimeVersion: {{ with .containerRuntimeVersion }} {{ . }} {{ else }} "kwok-{{ Version }}" {{ end }} - kernelVersion: {{ with .kernelVersion }} {{ . }} {{ else }} "kwok-{{ Version }}" {{ end }} - kubeProxyVersion: {{ with .kubeProxyVersion }} {{ . }} {{ else }} "kwok-{{ Version }}" {{ end }} - kubeletVersion: {{ with .kubeletVersion }} {{ . }} {{ else }} "kwok-{{ Version }}" {{ end }} - machineID: {{ with .machineID }} {{ . }} {{ else }} "" {{ end }} - operatingSystem: {{ with .operatingSystem }} {{ . }} {{ else }} "linux" {{ end }} - osImage: {{ with .osImage }} {{ . }} {{ else }} "" {{ end }} - systemUUID: {{ with .systemUUID }} {{ . }} {{ else }} "" {{ end }} - {{ end }} + architecture: {{ or $nodeInfo.architecture "amd64" }} + bootID: {{ or $nodeInfo.bootID `""` }} + containerRuntimeVersion: {{ or $nodeInfo.containerRuntimeVersion $kwokVersion }} + kernelVersion: {{ or $nodeInfo.kernelVersion $kwokVersion }} + kubeProxyVersion: {{ or $nodeInfo.kubeProxyVersion $kwokVersion }} + kubeletVersion: {{ or $nodeInfo.kubeletVersion $kwokVersion }} + machineID: {{ or $nodeInfo.machineID `""` }} + operatingSystem: {{ or $nodeInfo.operatingSystem "linux" }} + osImage: {{ or $nodeInfo.osImage `""` }} + systemUUID: {{ or $nodeInfo.systemUUID `""` }} phase: Running resourceRef: apiGroup: v1 @@ -232,12 +233,19 @@ spec: name: {{ .name | Quote }} ready: true restartCount: 0 + {{ if eq .restartPolicy "Always" }} + started: true + state: + running: + startedAt: {{ $now | Quote }} + {{ else }} state: terminated: exitCode: 0 finishedAt: {{ $now | Quote }} reason: Completed startedAt: {{ $now | Quote }} + {{ end }} {{ end }} hostIP: {{ NodeIPWith .spec.nodeName | Quote }} diff --git a/yamls/kwok.yaml b/yamls/kwok.yaml index 6710e1dd8627..50fff80a9831 100644 --- a/yamls/kwok.yaml +++ b/yamls/kwok.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: attaches.kwok.x-k8s.io @@ -127,7 +127,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: clusterattaches.kwok.x-k8s.io @@ -267,7 +267,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: clusterexecs.kwok.x-k8s.io @@ -449,7 +449,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: clusterlogs.kwok.x-k8s.io @@ -596,7 +596,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: clusterportforwards.kwok.x-k8s.io @@ -763,7 +763,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: clusterresourceusages.kwok.x-k8s.io @@ -920,7 +920,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: execs.kwok.x-k8s.io @@ -1084,7 +1084,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: logs.kwok.x-k8s.io @@ -1213,7 +1213,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: metrics.kwok.x-k8s.io @@ -1406,7 +1406,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: portforwards.kwok.x-k8s.io @@ -1556,7 +1556,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: resourceusages.kwok.x-k8s.io @@ -1695,7 +1695,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 labels: app: kwok-controller name: stages.kwok.x-k8s.io @@ -1829,12 +1829,53 @@ spec: type: object type: array type: object + patches: + description: Patches means that the resource will be patched. + items: + description: StagePatch describes the patch for the resource. + properties: + impersonation: + description: |- + Impersonation indicates the impersonating configuration for client when patching status. + In most cases this will be empty, in which case the default client service account will be used. + When this is not empty, a corresponding rbac change is required to grant `impersonate` privilege. + The support for this field is not available in Pod and Node resources. + properties: + username: + description: Username the target username for the client + to impersonate + type: string + required: + - username + type: object + root: + description: Root indicates the root of the template calculated + by the patch. + type: string + subresource: + description: Subresource indicates the name of the subresource + that will be patched. + type: string + template: + description: Template indicates the template for modifying + the resource in the next. + type: string + type: + description: Type indicates the type of the patch. + enum: + - json + - merge + - strategic + type: string + type: object + type: array statusPatchAs: description: |- StatusPatchAs indicates the impersonating configuration for client when patching status. In most cases this will be empty, in which case the default client service account will be used. When this is not empty, a corresponding rbac change is required to grant `impersonate` privilege. The support for this field is not available in Pod and Node resources. + Deprecated: Use Patches instead. properties: username: description: Username the target username for the client to @@ -1848,10 +1889,12 @@ spec: description: |- StatusSubresource indicates the name of the subresource that will be patched. The support for this field is not available in Pod and Node resources. + Deprecated: Use Patches instead. type: string statusTemplate: - description: StatusTemplate indicates the template for modifying - the status of the resource in the next. + description: |- + StatusTemplate indicates the template for modifying the status of the resource in the next. + Deprecated: Use Patches instead. type: string type: object resourceRef: @@ -1924,6 +1967,17 @@ spec: a random stage will be matched as the next stage based on the weight. minimum: 0 type: integer + weightFrom: + description: |- + WeightFrom means is the expression used to get the value. + If it is a number type, convert to int. + If it is a string type, the value get will be parsed by strconv.ParseInt. + properties: + expressionFrom: + description: ExpressionFrom is the expression used to get the + value. + type: string + type: object required: - next - resourceRef @@ -2347,8 +2401,6 @@ spec: - --manage-nodes-with-annotation-selector=kwok.x-k8s.io/node=fake - --manage-nodes-with-label-selector= - --manage-single-node= - - --disregard-status-with-annotation-selector=kwok.x-k8s.io/status=custom - - --disregard-status-with-label-selector= - --node-ip=$(POD_IP) - --node-port=10247 - --cidr=10.0.0.1/24 @@ -2374,7 +2426,7 @@ spec: valueFrom: fieldRef: fieldPath: status.hostIP - image: registry.k8s.io/kwok/kwok:v0.5.1 + image: registry.k8s.io/kwok/kwok:v0.6.0 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 10 diff --git a/yamls/speaker.yaml b/yamls/speaker.yaml index 38335c487519..030b13497b6b 100644 --- a/yamls/speaker.yaml +++ b/yamls/speaker.yaml @@ -29,7 +29,7 @@ spec: hostNetwork: true containers: - name: kube-ovn-speaker - image: "kubeovn/kube-ovn:v1.13.0" + image: "docker.io/kubeovn/kube-ovn:v1.13.0" imagePullPolicy: IfNotPresent command: - /kube-ovn/kube-ovn-speaker diff --git a/yamls/webhook.yaml b/yamls/webhook.yaml index fe76f86523da..b9b5231538a1 100644 --- a/yamls/webhook.yaml +++ b/yamls/webhook.yaml @@ -33,7 +33,7 @@ spec: hostNetwork: true containers: - name: kube-ovn-webhook - image: "kubeovn/kube-ovn:v1.13.0" + image: "docker.io/kubeovn/kube-ovn:v1.13.0" imagePullPolicy: IfNotPresent command: - /kube-ovn/kube-ovn-webhook