diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index fdba57a4365..3f22042ebc5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -40,7 +40,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v6 with: - go-version: ^1.18 + go-version: '^1.25' id: go - name: Checkout repository diff --git a/.github/workflows/darwin.yaml b/.github/workflows/darwin.yaml index 91b76bf62db..66326774091 100644 --- a/.github/workflows/darwin.yaml +++ b/.github/workflows/darwin.yaml @@ -13,7 +13,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v6 with: - go-version: ^1.16 + go-version: '^1.25' id: go - name: Check out code into the Go module directory diff --git a/.github/workflows/linux.yaml b/.github/workflows/linux.yaml index 0f305fcadb7..c34e5525896 100644 --- a/.github/workflows/linux.yaml +++ b/.github/workflows/linux.yaml @@ -13,7 +13,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v6 with: - go-version: ^1.16 + go-version: '^1.25' id: go - name: Check out code into the Go module directory diff --git a/.github/workflows/static.yaml b/.github/workflows/static.yaml index b3ce54d0b19..ce17ac15495 100644 --- a/.github/workflows/static.yaml +++ b/.github/workflows/static.yaml @@ -10,10 +10,12 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v6 with: - go-version: ^1.19 + go-version: '^1.25' - uses: actions/checkout@master - name: Run linter - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v9 with: - version: v1.64 - args: -E=gofmt,unused,ineffassign,revive,misspell,copyloopvar,asciicheck,bodyclose,contextcheck,dogsled,durationcheck,errname,forbidigo -D=staticcheck --timeout=30m0s + version: v2.6 + args: --timeout=30m0s + skip-cache: true + skip-save-cache: true diff --git a/.github/workflows/trivy.yaml b/.github/workflows/trivy.yaml index c0759bdb522..75e3ba40149 100644 --- a/.github/workflows/trivy.yaml +++ b/.github/workflows/trivy.yaml @@ -12,12 +12,12 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v6 with: - go-version: 1.24.11 + go-version: '^1.25' id: go - name: Checkout code uses: actions/checkout@v6 - + - name: Build an image from Dockerfile run: | export PUBLISH=true @@ -25,7 +25,7 @@ jobs: export IMAGE_VERSION=latest export DOCKER_CLI_EXPERIMENTAL=enabled make container - + - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master env: diff --git a/.github/workflows/ubuntu-e2e.yml b/.github/workflows/ubuntu-e2e.yml index 74b7da47273..ef057fe9229 100644 --- a/.github/workflows/ubuntu-e2e.yml +++ b/.github/workflows/ubuntu-e2e.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v6 with: - go-version: ^1.16 + go-version: '^1.25' id: go - name: Check out code into the Go module directory diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index fc221eef318..12762b4e1e5 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -7,14 +7,14 @@ jobs: build: strategy: matrix: - go-versions: [1.16.x] + go-versions: [1.25.x] platform: [windows-latest] runs-on: ${{ matrix.platform }} steps: - name: Set up Go 1.x uses: actions/setup-go@v6 with: - go-version: ^1.16 + go-version: '^1.25' id: go - name: Checkout code uses: actions/checkout@v6 diff --git a/.golangci.yml b/.golangci.yml index a7102ad3395..0c09b798711 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,12 +1,42 @@ -linters-settings: - depguard: - rules: - main: - files: - - $all - - "!$test" - allow: - - $gostd - - k8s.io - - sigs.k8s.io - - github.com +version: "2" + +linters: + settings: + depguard: + rules: + main: + files: + - $all + - '!$test' + allow: + - $gostd + - k8s.io + - sigs.k8s.io + - github.com + + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ + - test/utils/azure/azure_helpers.go + - pkg/smb/smb_common_linux.go + - vendor$ +formatters: + enable: + - gofmt + - goimports + - gofumpt + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ + - vendor$ diff --git a/go.mod b/go.mod index 2e75691e83b..e5eff279b43 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/kubernetes-csi/csi-driver-smb -go 1.24.0 +go 1.25 godebug winsymlink=0 @@ -21,12 +21,12 @@ require ( go.uber.org/goleak v1.3.0 golang.org/x/net v0.47.0 google.golang.org/grpc v1.65.0 - k8s.io/api v0.31.12 - k8s.io/apimachinery v0.31.12 - k8s.io/client-go v0.31.12 - k8s.io/component-base v0.31.12 + k8s.io/api v0.31.14 + k8s.io/apimachinery v0.31.14 + k8s.io/client-go v0.31.14 + k8s.io/component-base v0.31.14 k8s.io/klog/v2 v2.130.1 - k8s.io/kubernetes v1.31.12 + k8s.io/kubernetes v1.31.14 k8s.io/mount-utils v0.32.0 k8s.io/pod-security-admission v0.31.12 k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 diff --git a/go.sum b/go.sum index 723dd1bddc1..33d049ec5c5 100644 --- a/go.sum +++ b/go.sum @@ -417,20 +417,20 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.31.12 h1:yysm83xHIoKAwfm2w0dT6Yz7vfWzl841AEMI7Y8wDa8= -k8s.io/api v0.31.12/go.mod h1:f/srhhI7aDs9K4s0W1GX4/zb+cIf5uWrBjGyoO/XgJc= +k8s.io/api v0.31.14 h1:xYn/S/WFJsksI7dk/5uBRd3Umm/D8W5g7sRnd4csotA= +k8s.io/api v0.31.14/go.mod h1:K8fvRey4z73RAuxBZCma7WtY8WFvkViYhfFLCMT4xgA= k8s.io/apiextensions-apiserver v0.31.12 h1:d32I3VReAly5Qoc9ZXhO4/iObYmm7Jk6VvAeRAbg/MA= k8s.io/apiextensions-apiserver v0.31.12/go.mod h1:KcBI/Z/WQmbffBwfqQmqHhALhvun5JNJJh8Y29CJwUo= -k8s.io/apimachinery v0.31.12 h1:y34W8rNKc+jDxUvEXarjahqM6vOV5iqgZPuRqRuyEh8= -k8s.io/apimachinery v0.31.12/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/apimachinery v0.31.14 h1:/eMIwjv+GFm6A/sSGlB1NupBU6wTDPhEWsju0Fj69kY= +k8s.io/apimachinery v0.31.14/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/apiserver v0.31.12 h1:W5hKS78HC/llxTLBICR/xXScPkc5sPkDA66pyAin+mQ= k8s.io/apiserver v0.31.12/go.mod h1:f0EWMQvAmOfNBrYYVesqnQFrfMyDYlxVUOLm/RNDbP8= -k8s.io/client-go v0.31.12 h1:JJhouOoU1bKdPWplkZ2CpYA74+lxj3Zsn15aoGLX6Hk= -k8s.io/client-go v0.31.12/go.mod h1:kjQ5WSec9ShP3T1auTDFW4bTqgmJdBuZPsjq5FqeuYE= +k8s.io/client-go v0.31.14 h1:d4/G0xfksNIbMWH7ghjzOwC5bTAwQ20gABTjZw7fLlQ= +k8s.io/client-go v0.31.14/go.mod h1:0uRpRB7r5QwtsbxEngZPkbcIVoNdAQAPIcopgiXjhQc= k8s.io/cloud-provider v0.31.12 h1:la9A7dGy0VpcnI5nNZ7/RhU4/0ZoAVx6QM6T+Lze96s= k8s.io/cloud-provider v0.31.12/go.mod h1:VKHFFjRqXQNryOxbW+xE/0tL8qm8ejxaQ0t3TRA2AMc= -k8s.io/component-base v0.31.12 h1:Z7SYHg782bY1NLGezTJYRZGPeywWVtFpE35iOEam//4= -k8s.io/component-base v0.31.12/go.mod h1:r6wrhZ7BrjAUhGZttUT6MNJdn0McPWF5RPz/xcQY3xI= +k8s.io/component-base v0.31.14 h1:VNjBuEMmvlwL4twRlMmlaVmsodIRaNivXcZoAx1/x7Q= +k8s.io/component-base v0.31.14/go.mod h1:9ogYcJBUdB4VQ/OMgInYVRScC9bguXxSEEZPsInY+uM= k8s.io/component-helpers v0.31.12 h1:Mb9/Ijz0euQQ2v2IEgtKkvWBbDeMTq2fqHs1OoXPxGM= k8s.io/component-helpers v0.31.12/go.mod h1:62Zm0UNTFymcAUItaHCL+g9Qbco1WcSuiUvVSKEQtvk= k8s.io/controller-manager v0.31.12 h1:wrRs4CWP2ZtL5JnyW9QaTgD9DB1YQI7Sr68ifKF9n+M= @@ -447,8 +447,8 @@ k8s.io/kubectl v0.31.12 h1:+f0KlQcVYX/7J7ii0AGRwCZYVx55u4dOj3Irrh17Daw= k8s.io/kubectl v0.31.12/go.mod h1:BbqRvKt1mdJLdk+0Qovx38/d2MCLwTA31I8IN+Fql1s= k8s.io/kubelet v0.31.12 h1:iSaYgKgLig52YOqsu+3wIXq/p++sawwQM59D7t0gIgQ= k8s.io/kubelet v0.31.12/go.mod h1:lOqTjK7k1wmGMPanLMykpEYYyfjNgCu9EDG6kYqu2Jc= -k8s.io/kubernetes v1.31.12 h1:dPgK1slI7p/D3I2J1NA6UfBeMMHcjB91rHdXMpx8fkU= -k8s.io/kubernetes v1.31.12/go.mod h1:9xmT2buyTYj8TRKwRae7FcuY8k5+xlxv7VivvO0KKfs= +k8s.io/kubernetes v1.31.14 h1:UtjLfqvXLuSVDdJ4+NpQCIfFkKkLnAAVmxAEMsnkhjk= +k8s.io/kubernetes v1.31.14/go.mod h1:9xmT2buyTYj8TRKwRae7FcuY8k5+xlxv7VivvO0KKfs= k8s.io/mount-utils v0.32.0 h1:KOQAhPzJICATXnc6XCkWoexKbkOexRnMCUW8APFfwg4= k8s.io/mount-utils v0.32.0/go.mod h1:Kun5c2svjAPx0nnvJKYQWhfeNW+O0EpzHgRhDcYoSY0= k8s.io/pod-security-admission v0.31.12 h1:lL+0Mn2MqTdFqgRPo0u+nO9/GhaBB/MrOxJLILw3oO4= diff --git a/pkg/csi-common/driver.go b/pkg/csi-common/driver.go index d70c58cafde..2e1c2dd90d3 100644 --- a/pkg/csi-common/driver.go +++ b/pkg/csi-common/driver.go @@ -48,7 +48,7 @@ func NewCSIDriver(name string, v string, nodeID string) *CSIDriver { // TODO version format and validation if len(v) == 0 { klog.Errorf("Version argument missing, now skip it") - //return nil + // return nil } driver := CSIDriver{ diff --git a/pkg/csi-common/driver_test.go b/pkg/csi-common/driver_test.go index 8b8aa513ff0..6d2894cf8a4 100644 --- a/pkg/csi-common/driver_test.go +++ b/pkg/csi-common/driver_test.go @@ -31,12 +31,9 @@ const ( fakeNodeID = "fakeNodeID" ) -var ( - vendorVersion = "0.3.0" -) +var vendorVersion = "0.3.0" func NewFakeDriver() *CSIDriver { - driver := NewCSIDriver(fakeDriverName, vendorVersion, fakeNodeID) return driver @@ -102,7 +99,6 @@ func TestNewCSIDriver(t *testing.T) { } func TestGetVolumeCapabilityAccessModes(t *testing.T) { - d := NewFakeDriver() // Test no volume access modes. @@ -159,7 +155,6 @@ func TestValidateControllerServiceRequest(t *testing.T) { // Test controller service clone volumes is supported err = d.ValidateControllerServiceRequest(csi.ControllerServiceCapability_RPC_CLONE_VOLUME) assert.NoError(t, err) - } func TestValidateNodeServiceRequest(t *testing.T) { diff --git a/pkg/csi-common/server.go b/pkg/csi-common/server.go index 5d3209a15fa..4bfda3a5901 100644 --- a/pkg/csi-common/server.go +++ b/pkg/csi-common/server.go @@ -69,7 +69,6 @@ func (s *nonBlockingGRPCServer) ForceStop() { } func (s *nonBlockingGRPCServer) serve(endpoint string, ids csi.IdentityServer, cs csi.ControllerServer, ns csi.NodeServer, testMode bool) { - proto, addr, err := ParseEndpoint(endpoint) if err != nil { klog.Fatal(err.Error()) diff --git a/pkg/csi-common/server_test.go b/pkg/csi-common/server_test.go index b7a88bd9783..ab8f1d9ee83 100644 --- a/pkg/csi-common/server_test.go +++ b/pkg/csi-common/server_test.go @@ -42,7 +42,7 @@ func TestServe(_ *testing.T) { s := nonBlockingGRPCServer{} s.server = grpc.NewServer() s.wg = sync.WaitGroup{} - //need to add one here as the actual also requires one. + // need to add one here as the actual also requires one. s.wg.Add(1) s.serve("tcp://127.0.0.1:0", nil, nil, nil, true) } diff --git a/pkg/csi-common/utils.go b/pkg/csi-common/utils.go index a82333efd8f..de3709d240e 100644 --- a/pkg/csi-common/utils.go +++ b/pkg/csi-common/utils.go @@ -17,11 +17,10 @@ limitations under the License. package csicommon import ( + "context" "fmt" "strings" - "context" - "github.com/container-storage-interface/spec/lib/go/csi" "github.com/kubernetes-csi/csi-lib-utils/protosanitizer" "google.golang.org/grpc" @@ -35,7 +34,7 @@ func ParseEndpoint(ep string) (string, string, error) { return s[0], s[1], nil } } - return "", "", fmt.Errorf("Invalid endpoint: %v", ep) + return "", "", fmt.Errorf("invalid endpoint: %v", ep) } func NewVolumeCapabilityAccessMode(mode csi.VolumeCapability_AccessMode_Mode) *csi.VolumeCapability_AccessMode { diff --git a/pkg/csi-common/utils_test.go b/pkg/csi-common/utils_test.go index ba39b1aeada..53e288f9b54 100644 --- a/pkg/csi-common/utils_test.go +++ b/pkg/csi-common/utils_test.go @@ -30,7 +30,7 @@ import ( ) func TestParseEndpoint(t *testing.T) { - //Valid unix domain socket endpoint + // Valid unix domain socket endpoint sockType, addr, err := ParseEndpoint("unix://fake.sock") assert.NoError(t, err) assert.Equal(t, sockType, "unix") @@ -41,25 +41,25 @@ func TestParseEndpoint(t *testing.T) { assert.Equal(t, sockType, "unix") assert.Equal(t, addr, "/fakedir/fakedir/fake.sock") - //Valid unix domain socket with uppercase + // Valid unix domain socket with uppercase sockType, addr, err = ParseEndpoint("UNIX://fake.sock") assert.NoError(t, err) assert.Equal(t, sockType, "UNIX") assert.Equal(t, addr, "fake.sock") - //Valid TCP endpoint with ip + // Valid TCP endpoint with ip sockType, addr, err = ParseEndpoint("tcp://127.0.0.1:80") assert.NoError(t, err) assert.Equal(t, sockType, "tcp") assert.Equal(t, addr, "127.0.0.1:80") - //Valid TCP endpoint with uppercase + // Valid TCP endpoint with uppercase sockType, addr, err = ParseEndpoint("TCP://127.0.0.1:80") assert.NoError(t, err) assert.Equal(t, sockType, "TCP") assert.Equal(t, addr, "127.0.0.1:80") - //Valid TCP endpoint with hostname + // Valid TCP endpoint with hostname sockType, addr, err = ParseEndpoint("tcp://fakehost:80") assert.NoError(t, err) assert.Equal(t, sockType, "tcp") diff --git a/pkg/mounter/refcounter_windows.go b/pkg/mounter/refcounter_windows.go index f36f2e1b4a5..0bc2a3664d5 100644 --- a/pkg/mounter/refcounter_windows.go +++ b/pkg/mounter/refcounter_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2020 The Kubernetes Authors. @@ -28,8 +27,10 @@ import ( "sync" ) -var basePath = "c:\\csi\\smbmounts" -var mutexes sync.Map +var ( + basePath = "c:\\csi\\smbmounts" + mutexes sync.Map +) func lock(key string) func() { value, _ := mutexes.LoadOrStore(key, &sync.Mutex{}) diff --git a/pkg/mounter/safe_mounter_host_process_windows.go b/pkg/mounter/safe_mounter_host_process_windows.go index 32331238ae5..50549fbff51 100644 --- a/pkg/mounter/safe_mounter_host_process_windows.go +++ b/pkg/mounter/safe_mounter_host_process_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2022 The Kubernetes Authors. @@ -197,7 +196,7 @@ func (mounter *winMounter) IsLikelyNotMountPoint(path string) (bool, error) { // Currently the make dir is only used from the staging code path, hence we call it // with Plugin context.. func (mounter *winMounter) MakeDir(path string) error { - return os.MkdirAll(normalizeWindowsPath(path), 0755) + return os.MkdirAll(normalizeWindowsPath(path), 0o755) } // ExistsPath - Checks if a path exists. Unlike util ExistsPath, this call does not perform follow link. diff --git a/pkg/mounter/safe_mounter_unix.go b/pkg/mounter/safe_mounter_unix.go index efbf6f64e51..3fbd89cb730 100644 --- a/pkg/mounter/safe_mounter_unix.go +++ b/pkg/mounter/safe_mounter_unix.go @@ -1,5 +1,4 @@ //go:build linux || darwin -// +build linux darwin /* Copyright 2020 The Kubernetes Authors. diff --git a/pkg/mounter/safe_mounter_v1beta_windows.go b/pkg/mounter/safe_mounter_v1beta_windows.go index 54a75ae9839..16363d2b494 100644 --- a/pkg/mounter/safe_mounter_v1beta_windows.go +++ b/pkg/mounter/safe_mounter_v1beta_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2020 The Kubernetes Authors. diff --git a/pkg/mounter/safe_mounter_windows.go b/pkg/mounter/safe_mounter_windows.go index 57e7694a188..fb5298eead8 100644 --- a/pkg/mounter/safe_mounter_windows.go +++ b/pkg/mounter/safe_mounter_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2020 The Kubernetes Authors. diff --git a/pkg/os/filesystem/filesystem.go b/pkg/os/filesystem/filesystem.go index 47de07d8c61..0b91f89d682 100644 --- a/pkg/os/filesystem/filesystem.go +++ b/pkg/os/filesystem/filesystem.go @@ -30,8 +30,10 @@ import ( "k8s.io/klog/v2" ) -var invalidPathCharsRegexWindows = regexp.MustCompile(`["/\:\?\*|]`) -var absPathRegexWindows = regexp.MustCompile(`^[a-zA-Z]:\\`) +var ( + invalidPathCharsRegexWindows = regexp.MustCompile(`["/\:\?\*|]`) + absPathRegexWindows = regexp.MustCompile(`^[a-zA-Z]:\\`) +) func containsInvalidCharactersWindows(path string) bool { if isAbsWindows(path) { diff --git a/pkg/smb/controllerserver.go b/pkg/smb/controllerserver.go index b16d0b88eaa..a712868bf21 100644 --- a/pkg/smb/controllerserver.go +++ b/pkg/smb/controllerserver.go @@ -123,7 +123,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) // Create subdirectory under base-dir // TODO: revisit permissions internalVolumePath := getInternalVolumePath(d.workingMountDir, smbVol) - if err = os.MkdirAll(internalVolumePath, 0777); err != nil { + if err = os.MkdirAll(internalVolumePath, 0o777); err != nil { return nil, status.Errorf(codes.Internal, "failed to make subdirectory: %v", err) } @@ -215,7 +215,7 @@ func (d *Driver) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) if strings.Contains(smbVol.subDir, "/") { parentDir := filepath.Dir(archivedInternalVolumePath) klog.V(2).Infof("DeleteVolume: subdirectory(%s) contains '/', make sure the parent directory(%s) exists", smbVol.subDir, parentDir) - if err = os.MkdirAll(parentDir, 0777); err != nil { + if err = os.MkdirAll(parentDir, 0o777); err != nil { return nil, status.Errorf(codes.Internal, "create parent directory(%s) of %s failed with %v", parentDir, archivedInternalVolumePath, err) } } @@ -235,7 +235,7 @@ func (d *Driver) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) } else { if _, err := os.Lstat(internalVolumePath); err == nil { if err2 := filepath.WalkDir(internalVolumePath, func(path string, _ fs.DirEntry, _ error) error { - return os.Chmod(path, 0777) + return os.Chmod(path, 0o777) }); err2 != nil { klog.Errorf("failed to chmod subdirectory: %v", err2) } diff --git a/pkg/smb/fake_mounter_test.go b/pkg/smb/fake_mounter_test.go index 473995c1292..5a216bfa5d3 100644 --- a/pkg/smb/fake_mounter_test.go +++ b/pkg/smb/fake_mounter_test.go @@ -122,7 +122,8 @@ func TestIsLikelyNotMountPoint(t *testing.T) { file: "./error_is_likely_target", expectedErr: fmt.Errorf("fake IsLikelyNotMountPoint: fake error"), }, - {desc: "[Success] Successful run", + { + desc: "[Success] Successful run", file: targetTest, expectedErr: nil, }, diff --git a/pkg/smb/identityserver_test.go b/pkg/smb/identityserver_test.go index 4c592a98e62..43035a2ecc2 100644 --- a/pkg/smb/identityserver_test.go +++ b/pkg/smb/identityserver_test.go @@ -18,12 +18,13 @@ package smb import ( "context" + "reflect" + "testing" + "github.com/container-storage-interface/spec/lib/go/csi" "github.com/stretchr/testify/assert" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "reflect" - "testing" ) func TestGetPluginInfo(t *testing.T) { diff --git a/pkg/smb/nodeserver.go b/pkg/smb/nodeserver.go index 104def37e32..4102896a759 100644 --- a/pkg/smb/nodeserver.go +++ b/pkg/smb/nodeserver.go @@ -17,6 +17,7 @@ limitations under the License. package smb import ( + "context" "encoding/base64" "fmt" "os" @@ -34,8 +35,6 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "golang.org/x/net/context" - "github.com/kubernetes-csi/csi-driver-smb/pkg/util" azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache" ) @@ -230,11 +229,11 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe sensitiveMountOptions = []string{password} } } else { - var useKerberosCache, err = ensureKerberosCache(d.krb5CacheDirectory, d.krb5Prefix, volumeID, mountFlags, secrets) + useKerberosCache, err := ensureKerberosCache(d.krb5CacheDirectory, d.krb5Prefix, volumeID, mountFlags, secrets) if err != nil { return nil, status.Error(codes.Internal, fmt.Sprintf("Error writing kerberos cache: %v", err)) } - if err := os.MkdirAll(targetPath, 0750); err != nil { + if err := os.MkdirAll(targetPath, 0o750); err != nil { return nil, status.Error(codes.Internal, fmt.Sprintf("MkdirAll %s failed with error: %v", targetPath, err)) } if requireUsernamePwdOption && !useKerberosCache { @@ -482,7 +481,7 @@ func (d *Driver) ensureMountPoint(target string) (bool, error) { } func makeDir(pathname string) error { - err := os.MkdirAll(pathname, os.FileMode(0755)) + err := os.MkdirAll(pathname, os.FileMode(0o755)) if err != nil { if !os.IsExist(err) { return err @@ -510,13 +509,13 @@ func hasKerberosMountOption(mountFlags []string) bool { } func getCredUID(mountFlags []string) (int, error) { - var cruidPrefix = "cruid=" + cruidPrefix := "cruid=" for _, mountFlag := range mountFlags { if strings.HasPrefix(mountFlag, cruidPrefix) { return strconv.Atoi(strings.TrimPrefix(mountFlag, cruidPrefix)) } } - return -1, fmt.Errorf("Can't find credUid in mount flags") + return -1, fmt.Errorf("can't find credUid in mount flags") } func getKrb5CcacheName(krb5Prefix string, credUID int) string { @@ -544,7 +543,7 @@ func kerberosCacheDirectoryExists(krb5CacheDirectory string) (bool, error) { } func getKerberosCache(krb5CacheDirectory, krb5Prefix string, credUID int, secrets map[string]string) (string, []byte, error) { - var krb5CcacheName = getKrb5CcacheName(krb5Prefix, credUID) + krb5CcacheName := getKrb5CcacheName(krb5Prefix, credUID) var krb5CcacheContent string for k, v := range secrets { switch strings.ToLower(k) { @@ -559,7 +558,7 @@ func getKerberosCache(krb5CacheDirectory, krb5Prefix string, credUID int, secret if err != nil { return "", nil, status.Error(codes.InvalidArgument, fmt.Sprintf("Malformed kerberos cache in key %s, expected to be in base64 form: %v", krb5CcacheName, err)) } - var krb5CacheFileName = getKerberosFilePath(krb5CacheDirectory, getKrb5CcacheName(krb5Prefix, credUID)) + krb5CacheFileName := getKerberosFilePath(krb5CacheDirectory, getKrb5CcacheName(krb5Prefix, credUID)) return krb5CacheFileName, content, nil } @@ -568,7 +567,7 @@ func getKerberosCache(krb5CacheDirectory, krb5Prefix string, credUID int, secret // At the same time, kerberos expects to find cache in file named "krb5cc_*", so creating symlink // will allow both clean up and serving proper cache to the kerberos. func ensureKerberosCache(krb5CacheDirectory, krb5Prefix, volumeID string, mountFlags []string, secrets map[string]string) (bool, error) { - var securityIsKerberos = hasKerberosMountOption(mountFlags) + securityIsKerberos := hasKerberosMountOption(mountFlags) if securityIsKerberos { _, err := kerberosCacheDirectoryExists(krb5CacheDirectory) if err != nil { @@ -586,7 +585,7 @@ func ensureKerberosCache(krb5CacheDirectory, krb5Prefix, volumeID string, mountF volumeIDCacheFileName := volumeKerberosCacheName(volumeID) volumeIDCacheAbsolutePath := getKerberosFilePath(krb5CacheDirectory, volumeIDCacheFileName) - if err := os.WriteFile(volumeIDCacheAbsolutePath, content, os.FileMode(0700)); err != nil { + if err := os.WriteFile(volumeIDCacheAbsolutePath, content, os.FileMode(0o700)); err != nil { return false, status.Error(codes.Internal, fmt.Sprintf("Couldn't write kerberos cache to file %s: %v", volumeIDCacheAbsolutePath, err)) } if err := os.Chown(volumeIDCacheAbsolutePath, credUID, credUID); err != nil { @@ -623,7 +622,7 @@ func deleteKerberosCache(krb5CacheDirectory, volumeID string) error { volumeIDCacheFileName := volumeKerberosCacheName(volumeID) - var volumeIDCacheAbsolutePath = getKerberosFilePath(krb5CacheDirectory, volumeIDCacheFileName) + volumeIDCacheAbsolutePath := getKerberosFilePath(krb5CacheDirectory, volumeIDCacheFileName) _, err = os.Stat(volumeIDCacheAbsolutePath) // Not created or already removed if os.IsNotExist(err) { @@ -663,7 +662,7 @@ func enableGroupRWX(mode string) string { if e != nil || v < 0 { return mode } - return fmt.Sprintf("0%o", v|070) + return fmt.Sprintf("0%o", v|0o70) } // Apply enableGroupRWX() to the option "flag=xyz" diff --git a/pkg/smb/nodeserver_test.go b/pkg/smb/nodeserver_test.go index b7d674d4335..62827a230c6 100644 --- a/pkg/smb/nodeserver_test.go +++ b/pkg/smb/nodeserver_test.go @@ -137,18 +137,22 @@ func TestNodeStageVolume(t *testing.T) { }, { desc: "[Error] Source field is missing in context", - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1", StagingTargetPath: sourceTest, - VolumeCapability: &stdVolCap}, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1", StagingTargetPath: sourceTest, + VolumeCapability: &stdVolCap, + }, expectedErr: testutil.TestError{ DefaultError: status.Error(codes.InvalidArgument, "source field is missing, current context: map[]"), }, }, { desc: "[Error] Not a Directory", - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1##", StagingTargetPath: smbFile, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1##", StagingTargetPath: smbFile, VolumeCapability: &stdVolCap, VolumeContext: volContext, - Secrets: secrets}, + Secrets: secrets, + }, expectedErr: testutil.TestError{ DefaultError: status.Error(codes.Internal, fmt.Sprintf("MkdirAll %s failed with error: mkdir %s: not a directory", smbFile, smbFile)), WindowsError: status.Error(codes.Internal, fmt.Sprintf("Could not mount target %s: mkdir %s: The system cannot find the path specified.", smbFile, smbFile)), @@ -159,10 +163,12 @@ func TestNodeStageVolume(t *testing.T) { setup: func(d *Driver) { d.volumeLocks.TryAcquire(fmt.Sprintf("%s-%s", "vol_1", sourceTest)) }, - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1", StagingTargetPath: sourceTest, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1", StagingTargetPath: sourceTest, VolumeCapability: &stdVolCap, VolumeContext: volContext, - Secrets: secrets}, + Secrets: secrets, + }, expectedErr: testutil.TestError{ DefaultError: status.Error(codes.Aborted, fmt.Sprintf(volumeOperationAlreadyExistsFmt, "vol_1")), }, @@ -172,84 +178,96 @@ func TestNodeStageVolume(t *testing.T) { }, { desc: "[Error] Failed SMB mount mocked by MountSensitive", - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1##", StagingTargetPath: errorMountSensSource, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1##", StagingTargetPath: errorMountSensSource, VolumeCapability: &stdVolCap, VolumeContext: volContext, - Secrets: secrets}, + Secrets: secrets, + }, skipOnWindows: true, flakyWindowsErrorMessage: fmt.Sprintf("rpc error: code = Internal desc = volume(vol_1##) mount \"%s\" on %#v failed "+ "with NewSmbGlobalMapping(%s, %s) failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.", - strings.Replace(testSource, "\\", "\\\\", -1), errorMountSensSource, testSource, errorMountSensSource), + strings.ReplaceAll(testSource, "\\", "\\\\"), errorMountSensSource, testSource, errorMountSensSource), expectedErr: testutil.TestError{ DefaultError: status.Errorf(codes.Internal, "volume(vol_1##) mount \"%s\" on \"%s\" failed with fake "+ "MountSensitive: target error", - strings.Replace(testSource, "\\", "\\\\", -1), errorMountSensSource), + strings.ReplaceAll(testSource, "\\", "\\\\"), errorMountSensSource), }, }, { desc: "[Error] Failed SMB mount mocked by MountSensitive (password with special characters)", - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1##", StagingTargetPath: errorMountSensSource, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1##", StagingTargetPath: errorMountSensSource, VolumeCapability: &stdVolCap, VolumeContext: volContext, - Secrets: secretsSpecial}, + Secrets: secretsSpecial, + }, skipOnWindows: true, flakyWindowsErrorMessage: fmt.Sprintf("rpc error: code = Internal desc = volume(vol_1##) mount \"%s\" on %#v failed "+ "with NewSmbGlobalMapping(%s, %s) failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.", - strings.Replace(testSource, "\\", "\\\\", -1), errorMountSensSource, testSource, errorMountSensSource), + strings.ReplaceAll(testSource, "\\", "\\\\"), errorMountSensSource, testSource, errorMountSensSource), expectedErr: testutil.TestError{ DefaultError: status.Errorf(codes.Internal, "volume(vol_1##) mount \"%s\" on \"%s\" failed with fake "+ "MountSensitive: target error", - strings.Replace(testSource, "\\", "\\\\", -1), errorMountSensSource), + strings.ReplaceAll(testSource, "\\", "\\\\"), errorMountSensSource), }, }, { desc: "[Success] Valid request", - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1##", StagingTargetPath: sourceTest, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1##", StagingTargetPath: sourceTest, VolumeCapability: &stdVolCap, VolumeContext: volContext, - Secrets: secrets}, + Secrets: secrets, + }, skipOnWindows: true, flakyWindowsErrorMessage: fmt.Sprintf("rpc error: code = Internal desc = volume(vol_1##) mount \"%s\" on %#v failed with "+ "NewSmbGlobalMapping(%s, %s) failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.", - strings.Replace(testSource, "\\", "\\\\", -1), sourceTest, testSource, sourceTest), + strings.ReplaceAll(testSource, "\\", "\\\\"), sourceTest, testSource, sourceTest), expectedErr: testutil.TestError{}, }, { desc: "[Success] Valid request with pv/pvc metadata", - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1##", StagingTargetPath: sourceTest, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1##", StagingTargetPath: sourceTest, VolumeCapability: &stdVolCap, VolumeContext: volContextWithMetadata, - Secrets: secrets}, + Secrets: secrets, + }, skipOnWindows: true, flakyWindowsErrorMessage: fmt.Sprintf("rpc error: code = Internal desc = volume(vol_1##) mount \"%s\" on %#v failed with "+ "NewSmbGlobalMapping(%s, %s) failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.", - strings.Replace(testSource, "\\", "\\\\", -1), sourceTest, testSource, sourceTest), + strings.ReplaceAll(testSource, "\\", "\\\\"), sourceTest, testSource, sourceTest), expectedErr: testutil.TestError{}, }, { desc: "[Success] Valid request with VolumeMountGroup", - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1##", StagingTargetPath: sourceTest, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1##", StagingTargetPath: sourceTest, VolumeCapability: &mountGroupVolCap, VolumeContext: volContext, - Secrets: secrets}, + Secrets: secrets, + }, skipOnWindows: true, flakyWindowsErrorMessage: fmt.Sprintf("rpc error: code = Internal desc = volume(vol_1##) mount \"%s\" on %#v failed with "+ "NewSmbGlobalMapping(%s, %s) failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.", - strings.Replace(testSource, "\\", "\\\\", -1), sourceTest, testSource, sourceTest), + strings.ReplaceAll(testSource, "\\", "\\\\"), sourceTest, testSource, sourceTest), expectedErr: testutil.TestError{}, }, { desc: "[Success] Valid request with VolumeMountGroup and file/dir modes", - req: &csi.NodeStageVolumeRequest{VolumeId: "vol_1##", StagingTargetPath: sourceTest, + req: &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1##", StagingTargetPath: sourceTest, VolumeCapability: &mountGroupWithModesVolCap, VolumeContext: volContext, - Secrets: secrets}, + Secrets: secrets, + }, skipOnWindows: true, flakyWindowsErrorMessage: fmt.Sprintf("rpc error: code = Internal desc = volume(vol_1##) mount \"%s\" on %#v failed with "+ "NewSmbGlobalMapping(%s, %s) failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.", - strings.Replace(testSource, "\\", "\\\\", -1), sourceTest, testSource, sourceTest), + strings.ReplaceAll(testSource, "\\", "\\\\"), sourceTest, testSource, sourceTest), expectedErr: testutil.TestError{}, }, } @@ -292,7 +310,6 @@ func TestNodeStageVolume(t *testing.T) { assert.NoError(t, err) err = os.RemoveAll(errorMountSensSource) assert.NoError(t, err) - } func TestNodeGetInfo(t *testing.T) { @@ -366,28 +383,34 @@ func TestNodePublishVolume(t *testing.T) { }, { desc: "[Error] Target path missing", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, - VolumeId: "vol_1"}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + VolumeId: "vol_1", + }, expectedErr: testutil.TestError{ DefaultError: status.Error(codes.InvalidArgument, "Target path not provided"), }, }, { desc: "[Error] Stage target path missing", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, - VolumeId: "vol_1", - TargetPath: targetTest}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + VolumeId: "vol_1", + TargetPath: targetTest, + }, expectedErr: testutil.TestError{ DefaultError: status.Error(codes.InvalidArgument, "Staging target not provided"), }, }, { desc: "[Error] Not a directory", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, VolumeId: "vol_1", TargetPath: smbFile, StagingTargetPath: sourceTest, - Readonly: true}, + Readonly: true, + }, expectedErr: testutil.TestError{ DefaultError: status.Errorf(codes.Internal, "Could not mount target \"%s\": mkdir %s: not a directory", smbFile, smbFile), @@ -396,11 +419,13 @@ func TestNodePublishVolume(t *testing.T) { }, { desc: "[Error] Mount error mocked by Mount", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, VolumeId: "vol_1", TargetPath: targetTest, StagingTargetPath: errorMountSource, - Readonly: true}, + Readonly: true, + }, // todo: This test does not return any error on windows // Once the issue is figured out, we'll remove this field skipOnWindows: true, @@ -410,34 +435,41 @@ func TestNodePublishVolume(t *testing.T) { }, { desc: "[Success] Valid request read only", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, VolumeId: "vol_1", TargetPath: targetTest, StagingTargetPath: sourceTest, - Readonly: true}, + Readonly: true, + }, expectedErr: testutil.TestError{}, }, { desc: "[Success] Valid request already mounted", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, VolumeId: "vol_1", TargetPath: alreadyMountedTarget, StagingTargetPath: sourceTest, - Readonly: true}, + Readonly: true, + }, expectedErr: testutil.TestError{}, }, { desc: "[Success] Valid request", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, VolumeId: "vol_1", TargetPath: targetTest, StagingTargetPath: sourceTest, - Readonly: true}, + Readonly: true, + }, expectedErr: testutil.TestError{}, }, { desc: "[Error] failed to create ephemeral Volume", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, VolumeId: "vol_1", TargetPath: targetTest, StagingTargetPath: sourceTest, @@ -450,7 +482,8 @@ func TestNodePublishVolume(t *testing.T) { }, { desc: "[error] failed request with ephemeral Volume", - req: &csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + req: &csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, VolumeId: "vol_1", TargetPath: targetTest, StagingTargetPath: sourceTest, @@ -478,7 +511,7 @@ func TestNodePublishVolume(t *testing.T) { d.mounter = mounter for _, test := range tests { - if !(test.skipOnWindows && runtime.GOOS == "windows") { + if !test.skipOnWindows || runtime.GOOS != "windows" { if test.setup != nil { test.setup(d) } @@ -543,7 +576,7 @@ func TestNodeUnpublishVolume(t *testing.T) { d.mounter = mounter for _, test := range tests { - if !(test.skipOnWindows && runtime.GOOS == "windows") { + if !test.skipOnWindows || runtime.GOOS != "windows" { if test.setup != nil { test.setup(d) } @@ -619,7 +652,7 @@ func TestNodeUnstageVolume(t *testing.T) { d.mounter = mounter for _, test := range tests { - if !(test.skipOnWindows && runtime.GOOS == "windows") { + if !test.skipOnWindows || runtime.GOOS != "windows" { if test.setup != nil { test.setup(d) } @@ -703,11 +736,11 @@ func TestEnsureMountPoint(t *testing.T) { func TestMakeDir(t *testing.T) { targetTest := "./target_test" - //Successfully create directory + // Successfully create directory err := makeDir(targetTest) assert.NoError(t, err) - //Failed case + // Failed case err = makeDir("./smb.go") var e *os.PathError if !errors.As(err, &e) { @@ -874,7 +907,7 @@ func TestGetCredUID(t *testing.T) { desc: "[Error] Got error when no CredUID", MountFlags: []string{}, result: -1, - expectedErr: fmt.Errorf("Can't find credUid in mount flags"), + expectedErr: fmt.Errorf("can't find credUid in mount flags"), }, { desc: "[Error] Got error when CredUID is not an int", @@ -968,7 +1001,6 @@ func TestGetKerberosCache(t *testing.T) { } } } - } func TestNodePublishVolumeIdempotentMount(t *testing.T) { @@ -990,11 +1022,13 @@ func TestNodePublishVolumeIdempotentMount(t *testing.T) { } volumeCap := csi.VolumeCapability_AccessMode{Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER} - req := csi.NodePublishVolumeRequest{VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, + req := csi.NodePublishVolumeRequest{ + VolumeCapability: &csi.VolumeCapability{AccessMode: &volumeCap}, VolumeId: "vol_1", TargetPath: targetTest, StagingTargetPath: sourceTest, - Readonly: true} + Readonly: true, + } _, err = d.NodePublishVolume(context.Background(), &req) assert.NoError(t, err) diff --git a/pkg/smb/smb_common_darwin.go b/pkg/smb/smb_common_darwin.go index f4b4fcc3270..bbbe4042788 100644 --- a/pkg/smb/smb_common_darwin.go +++ b/pkg/smb/smb_common_darwin.go @@ -1,5 +1,4 @@ //go:build darwin -// +build darwin /* Copyright 2020 The Kubernetes Authors. diff --git a/pkg/smb/smb_common_linux.go b/pkg/smb/smb_common_linux.go index 03bc9d0312c..4a3601e8498 100644 --- a/pkg/smb/smb_common_linux.go +++ b/pkg/smb/smb_common_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2020 The Kubernetes Authors. @@ -47,6 +46,7 @@ func Mount(m *mount.SafeFormatAndMount, source, target, fsType string, options, }() for _, option := range sensitiveMountOptions { + //lint:ignore QF1012 reason: adhering to rule breaks tests. if _, err := file.Write([]byte(fmt.Sprintf("%s\n", option))); err != nil { return err } diff --git a/pkg/smb/smb_common_linux_test.go b/pkg/smb/smb_common_linux_test.go index ebb6bab9947..be50044a2a1 100644 --- a/pkg/smb/smb_common_linux_test.go +++ b/pkg/smb/smb_common_linux_test.go @@ -17,8 +17,9 @@ limitations under the License. package smb import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestNeedsCredentialsOption(t *testing.T) { diff --git a/pkg/smb/smb_common_windows.go b/pkg/smb/smb_common_windows.go index 61a86eeeff0..8330288e39a 100644 --- a/pkg/smb/smb_common_windows.go +++ b/pkg/smb/smb_common_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2020 The Kubernetes Authors. diff --git a/pkg/smb/smb_test.go b/pkg/smb/smb_test.go index 3102bfbc003..2956edb26db 100644 --- a/pkg/smb/smb_test.go +++ b/pkg/smb/smb_test.go @@ -424,7 +424,7 @@ func TestGetRootPath(t *testing.T) { func TestGetKubeConfig(t *testing.T) { // skip for now as this is very flaky on Windows - //skipIfTestingOnWindows(t) + // skipIfTestingOnWindows(t) emptyKubeConfig := "empty-Kube-Config" validKubeConfig := "valid-Kube-Config" fakeContent := ` @@ -471,7 +471,7 @@ users: } }() - if err := os.WriteFile(validKubeConfig, []byte(fakeContent), 0666); err != nil { + if err := os.WriteFile(validKubeConfig, []byte(fakeContent), 0o666); err != nil { t.Error(err) } diff --git a/pkg/smb/version_test.go b/pkg/smb/version_test.go index c6efc50ad83..ecfdcbf3121 100644 --- a/pkg/smb/version_test.go +++ b/pkg/smb/version_test.go @@ -42,7 +42,6 @@ func TestGetVersion(t *testing.T) { if !reflect.DeepEqual(version, expected) { t.Errorf("Unexpected error. \n Expected: %v \n Found: %v", expected, version) } - } func TestGetVersionYAML(t *testing.T) { diff --git a/pkg/smb/volume_lock.go b/pkg/smb/volume_lock.go index df63b87e039..c6789052bdf 100644 --- a/pkg/smb/volume_lock.go +++ b/pkg/smb/volume_lock.go @@ -29,13 +29,13 @@ const ( // VolumeLocks implements a map with atomic operations. It stores a set of all volume IDs // with an ongoing operation. type volumeLocks struct { - locks sets.String + locks sets.Set[string] mux sync.Mutex } func newVolumeLocks() *volumeLocks { return &volumeLocks{ - locks: sets.NewString(), + locks: sets.New[string](), } } diff --git a/release-tools/filter-junit.go b/release-tools/filter-junit.go index aab1b8b603a..78338ace64f 100644 --- a/release-tools/filter-junit.go +++ b/release-tools/filter-junit.go @@ -142,7 +142,7 @@ func main() { panic(err) } } else { - if err := os.WriteFile(*output, data, 0644); err != nil { + if err := os.WriteFile(*output, data, 0o644); err != nil { panic(err) } } diff --git a/test/e2e/suite_test.go b/test/e2e/suite_test.go index 0b831725667..85ebe0d9bb3 100644 --- a/test/e2e/suite_test.go +++ b/test/e2e/suite_test.go @@ -30,7 +30,6 @@ import ( "github.com/kubernetes-csi/csi-driver-smb/pkg/smb" "github.com/onsi/ginkgo/v2" - "github.com/onsi/ginkgo/v2/reporters" "github.com/onsi/gomega" "github.com/pborman/uuid" "k8s.io/kubernetes/test/e2e/framework" @@ -271,8 +270,10 @@ func TestE2E(t *testing.T) { if reportDir == "" { reportDir = defaultReportDir } - r := []ginkgo.Reporter{reporters.NewJUnitReporter(path.Join(reportDir, "junit_01.xml"))} - ginkgo.RunSpecsWithDefaultAndCustomReporters(t, "SMB CSI Driver End-to-End Tests", r) + // Set the GINKGO_JUNIT_REPORT environment variable to enable JUnit reporting + os.Setenv("GINKGO_JUNIT_REPORT", path.Join(reportDir, "junit_01.xml")) + + ginkgo.RunSpecs(t, "SMB CSI Driver End-to-End Tests") } func execTestCmd(cmds []testCmd) { diff --git a/test/e2e/testsuites/dynamically_provisioned_cmd_volume_tester.go b/test/e2e/testsuites/dynamically_provisioned_cmd_volume_tester.go index cd5e2020359..f52ab509413 100644 --- a/test/e2e/testsuites/dynamically_provisioned_cmd_volume_tester.go +++ b/test/e2e/testsuites/dynamically_provisioned_cmd_volume_tester.go @@ -18,6 +18,7 @@ package testsuites import ( "context" + "github.com/kubernetes-csi/csi-driver-smb/test/e2e/driver" "github.com/onsi/ginkgo/v2" diff --git a/test/e2e/testsuites/dynamically_provisioned_collocated_pod_tester.go b/test/e2e/testsuites/dynamically_provisioned_collocated_pod_tester.go index 628d5a33a9f..09cd1edf859 100644 --- a/test/e2e/testsuites/dynamically_provisioned_collocated_pod_tester.go +++ b/test/e2e/testsuites/dynamically_provisioned_collocated_pod_tester.go @@ -18,6 +18,7 @@ package testsuites import ( "context" + "github.com/kubernetes-csi/csi-driver-smb/test/e2e/driver" "github.com/onsi/ginkgo/v2" @@ -55,5 +56,4 @@ func (t *DynamicallyProvisionedCollocatedPodTest) Run(ctx context.Context, clien tpod.WaitForRunning(ctx) nodeName = tpod.pod.Spec.NodeName } - } diff --git a/test/e2e/testsuites/dynamically_provisioned_pod_with_multiple_pv.go b/test/e2e/testsuites/dynamically_provisioned_pod_with_multiple_pv.go index 44edcb4cae4..4d697d34ab3 100644 --- a/test/e2e/testsuites/dynamically_provisioned_pod_with_multiple_pv.go +++ b/test/e2e/testsuites/dynamically_provisioned_pod_with_multiple_pv.go @@ -18,6 +18,7 @@ package testsuites import ( "context" + "github.com/kubernetes-csi/csi-driver-smb/test/e2e/driver" "github.com/onsi/ginkgo/v2" diff --git a/test/e2e/testsuites/dynamically_provisioned_resize_volume_tester.go b/test/e2e/testsuites/dynamically_provisioned_resize_volume_tester.go index 97e2f9b9c0f..2685728c2e6 100644 --- a/test/e2e/testsuites/dynamically_provisioned_resize_volume_tester.go +++ b/test/e2e/testsuites/dynamically_provisioned_resize_volume_tester.go @@ -55,7 +55,7 @@ func (t *DynamicallyProvisionedResizeVolumeTest) Run(ctx context.Context, client ginkgo.By("checking that the pods command exits with no error") tpod.WaitForSuccess(ctx) - pvcName := tpod.pod.Spec.Volumes[0].VolumeSource.PersistentVolumeClaim.ClaimName + pvcName := tpod.pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName pvc, err := client.CoreV1().PersistentVolumeClaims(namespace.Name).Get(ctx, pvcName, metav1.GetOptions{}) if err != nil { framework.ExpectNoError(err, fmt.Sprintf("fail to get original pvc(%s): %v", pvcName, err)) @@ -78,7 +78,7 @@ func (t *DynamicallyProvisionedResizeVolumeTest) Run(ctx context.Context, client time.Sleep(30 * time.Second) ginkgo.By("checking the resizing result") - newPvc, err := client.CoreV1().PersistentVolumeClaims(namespace.Name).Get(ctx, tpod.pod.Spec.Volumes[0].VolumeSource.PersistentVolumeClaim.ClaimName, metav1.GetOptions{}) + newPvc, err := client.CoreV1().PersistentVolumeClaims(namespace.Name).Get(ctx, tpod.pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, metav1.GetOptions{}) if err != nil { framework.ExpectNoError(err, fmt.Sprintf("fail to get new pvc(%s): %v", pvcName, err)) } diff --git a/test/e2e/testsuites/dynamically_provisioned_restart_driver_tester.go b/test/e2e/testsuites/dynamically_provisioned_restart_driver_tester.go index e2cb4956706..782c1964c83 100644 --- a/test/e2e/testsuites/dynamically_provisioned_restart_driver_tester.go +++ b/test/e2e/testsuites/dynamically_provisioned_restart_driver_tester.go @@ -18,6 +18,7 @@ package testsuites import ( "context" + "github.com/kubernetes-csi/csi-driver-smb/test/e2e/driver" "github.com/onsi/ginkgo/v2" v1 "k8s.io/api/core/v1" diff --git a/test/e2e/testsuites/dynamically_provisioned_volume_cloning_tester.go b/test/e2e/testsuites/dynamically_provisioned_volume_cloning_tester.go index c2b1bac72ed..b6a206aa5be 100644 --- a/test/e2e/testsuites/dynamically_provisioned_volume_cloning_tester.go +++ b/test/e2e/testsuites/dynamically_provisioned_volume_cloning_tester.go @@ -59,7 +59,7 @@ func (t *DynamicallyProvisionedVolumeCloningTest) Run(ctx context.Context, clien ginkgo.By("cloning existing volume") clonedVolume := t.Pod.Volumes[0] clonedVolume.DataSource = &DataSource{ - Name: tpod.pod.Spec.Volumes[0].VolumeSource.PersistentVolumeClaim.ClaimName, + Name: tpod.pod.Spec.Volumes[0].PersistentVolumeClaim.ClaimName, Kind: VolumePVCKind, } clonedVolume.StorageClass = tsc.storageClass diff --git a/test/e2e/testsuites/dynamically_provisioned_volume_subpath_tester.go b/test/e2e/testsuites/dynamically_provisioned_volume_subpath_tester.go index 185db3f44cc..2c9d6099f51 100644 --- a/test/e2e/testsuites/dynamically_provisioned_volume_subpath_tester.go +++ b/test/e2e/testsuites/dynamically_provisioned_volume_subpath_tester.go @@ -18,6 +18,7 @@ package testsuites import ( "context" + "github.com/kubernetes-csi/csi-driver-smb/test/e2e/driver" "github.com/onsi/ginkgo/v2" diff --git a/test/e2e/testsuites/testsuites.go b/test/e2e/testsuites/testsuites.go index 3e1dc329a4f..b845402e4d7 100644 --- a/test/e2e/testsuites/testsuites.go +++ b/test/e2e/testsuites/testsuites.go @@ -186,8 +186,8 @@ func (t *TestPersistentVolumeClaim) ValidateProvisionedPersistentVolume(ctx cont ginkgo.By("checking the PV") expectedAccessModes := t.requestedPersistentVolumeClaim.Spec.AccessModes gomega.Expect(t.persistentVolume.Spec.AccessModes).To(gomega.Equal(expectedAccessModes)) - gomega.Expect(t.persistentVolume.Spec.ClaimRef.Name).To(gomega.Equal(t.persistentVolumeClaim.ObjectMeta.Name)) - gomega.Expect(t.persistentVolume.Spec.ClaimRef.Namespace).To(gomega.Equal(t.persistentVolumeClaim.ObjectMeta.Namespace)) + gomega.Expect(t.persistentVolume.Spec.ClaimRef.Name).To(gomega.Equal(t.persistentVolumeClaim.Name)) + gomega.Expect(t.persistentVolume.Spec.ClaimRef.Namespace).To(gomega.Equal(t.persistentVolumeClaim.Namespace)) // If storageClass is nil, PV was pre-provisioned with these values already set if t.storageClass != nil { gomega.Expect(t.persistentVolume.Spec.PersistentVolumeReclaimPolicy).To(gomega.Equal(*t.storageClass.ReclaimPolicy)) @@ -313,7 +313,7 @@ func (t *TestPersistentVolumeClaim) removeFinalizers(ctx context.Context) { oldData, err := json.Marshal(pvClone) framework.ExpectNoError(err) - pvClone.ObjectMeta.Finalizers = nil + pvClone.Finalizers = nil newData, err := json.Marshal(pvClone) framework.ExpectNoError(err) @@ -450,18 +450,25 @@ func pollForStringInPodsExec(namespace string, pods []string, command []string, func pollForStringWorker(namespace string, pod string, command []string, expectedString string, ch chan<- error) { args := append([]string{"exec", pod, "--"}, command...) - err := wait.PollImmediate(poll, pollForStringTimeout, func() (bool, error) { - stdout, err := e2ekubectl.RunKubectl(namespace, args...) - if err != nil { - framework.Logf("Error waiting for output %q in pod %q: %v.", expectedString, pod, err) - return false, nil - } - if !strings.Contains(stdout, expectedString) { - framework.Logf("The stdout did not contain output %q in pod %q, found: %q.", expectedString, pod, stdout) - return false, nil - } - return true, nil - }) + ctx, cancel := context.WithTimeout(context.Background(), pollForStringTimeout) + defer cancel() + err := wait.PollUntilContextTimeout( + ctx, + poll, + pollForStringTimeout, + true, + func(ctx context.Context) (bool, error) { + stdout, err := e2ekubectl.RunKubectl(namespace, args...) + if err != nil { + framework.Logf("Error waiting for output %q in pod %q: %v.", expectedString, pod, err) + return false, nil + } + if !strings.Contains(stdout, expectedString) { + framework.Logf("The stdout did not contain output %q in pod %q, found: %q.", expectedString, pod, stdout) + return false, nil + } + return true, nil + }) ch <- err } diff --git a/test/utils/azure/azure_helpers.go b/test/utils/azure/azure_helpers.go index 9c4507338b5..2b9f422e477 100644 --- a/test/utils/azure/azure_helpers.go +++ b/test/utils/azure/azure_helpers.go @@ -224,7 +224,6 @@ func (az *Client) EnsureVirtualNetworkAndSubnet(ctx context.Context, groupName, }, }, }) - if err != nil { return vnet, fmt.Errorf("cannot create virtual network: %v", err) } diff --git a/test/utils/credentials/credentials.go b/test/utils/credentials/credentials.go index de98a7c5de6..b5bcae2e7e7 100644 --- a/test/utils/credentials/credentials.go +++ b/test/utils/credentials/credentials.go @@ -142,7 +142,7 @@ func CreateAzureCredentialFile(isAzureChinaCloud bool) (*Credentials, error) { return parseAndExecuteTemplate(cloud, c.TenantID, c.SubscriptionID, c.ClientID, c.ClientSecret, resourceGroup, location) } - return nil, fmt.Errorf("If you are running tests locally, you will need to set the following env vars: $%s, $%s, $%s, $%s, $%s, $%s", + return nil, fmt.Errorf("if you are running tests locally, you will need to set the following env vars: $%s, $%s, $%s, $%s, $%s, $%s", tenantIDEnvVar, subscriptionIDEnvVar, aadClientIDEnvVar, aadClientSecretEnvVar, resourceGroupEnvVar, locationEnvVar) } diff --git a/vendor/k8s.io/client-go/util/cert/cert.go b/vendor/k8s.io/client-go/util/cert/cert.go index 91e171271af..4805d09ab55 100644 --- a/vendor/k8s.io/client-go/util/cert/cert.go +++ b/vendor/k8s.io/client-go/util/cert/cert.go @@ -75,13 +75,15 @@ func NewSelfSignedCACert(cfg Config, key crypto.Signer) (*x509.Certificate, erro CommonName: cfg.CommonName, Organization: cfg.Organization, }, - DNSNames: []string{cfg.CommonName}, NotBefore: notBefore, NotAfter: now.Add(duration365d * 10).UTC(), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, BasicConstraintsValid: true, IsCA: true, } + if len(cfg.CommonName) > 0 { + tmpl.DNSNames = []string{cfg.CommonName} + } certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &tmpl, &tmpl, key.Public(), key) if err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/securitycontext/util.go b/vendor/k8s.io/kubernetes/pkg/securitycontext/util.go index 28771b6df27..5e000f93333 100644 --- a/vendor/k8s.io/kubernetes/pkg/securitycontext/util.go +++ b/vendor/k8s.io/kubernetes/pkg/securitycontext/util.go @@ -17,6 +17,10 @@ limitations under the License. package securitycontext import ( + "fmt" + "os" + "sync" + v1 "k8s.io/api/core/v1" ) @@ -188,21 +192,32 @@ func AddNoNewPrivileges(sc *v1.SecurityContext) bool { var ( // These *must* be kept in sync with moby/moby. - // https://github.com/moby/moby/blob/master/oci/defaults.go#L105-L124 - // @jessfraz will watch changes to those files upstream. - defaultMaskedPaths = []string{ - "/proc/asound", - "/proc/acpi", - "/proc/kcore", - "/proc/keys", - "/proc/latency_stats", - "/proc/timer_list", - "/proc/timer_stats", - "/proc/sched_debug", - "/proc/scsi", - "/sys/firmware", - "/sys/devices/virtual/powercap", - } + // https://github.com/moby/moby/blob/ecb03c4cdae6f323150fc11b303dcc5dc4d82416/oci/defaults.go#L190-L218 + defaultMaskedPaths = sync.OnceValue(func() []string { + maskedPaths := []string{ + "/proc/asound", + "/proc/acpi", + "/proc/interrupts", + "/proc/kcore", + "/proc/keys", + "/proc/latency_stats", + "/proc/timer_list", + "/proc/timer_stats", + "/proc/sched_debug", + "/proc/scsi", + "/sys/firmware", + "/sys/devices/virtual/powercap", + } + + for _, cpu := range possibleCPUs() { + path := fmt.Sprintf("/sys/devices/system/cpu/cpu%d/thermal_throttle", cpu) + if _, err := os.Stat(path); err == nil { + maskedPaths = append(maskedPaths, path) + } + } + + return maskedPaths + }) defaultReadonlyPaths = []string{ "/proc/bus", "/proc/fs", @@ -221,7 +236,7 @@ func ConvertToRuntimeMaskedPaths(opt *v1.ProcMountType) []string { } // Otherwise, add the default masked paths to the runtime security context. - return defaultMaskedPaths + return defaultMaskedPaths() } // ConvertToRuntimeReadonlyPaths converts the ProcMountType to the specified or default diff --git a/vendor/k8s.io/kubernetes/pkg/securitycontext/util_darwin.go b/vendor/k8s.io/kubernetes/pkg/securitycontext/util_darwin.go new file mode 100644 index 00000000000..9d14502acb7 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/securitycontext/util_darwin.go @@ -0,0 +1,21 @@ +/* +Copyright 2025 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package securitycontext + +func possibleCPUs() []int { + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/securitycontext/util_linux.go b/vendor/k8s.io/kubernetes/pkg/securitycontext/util_linux.go new file mode 100644 index 00000000000..bcaab4eb3e1 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/securitycontext/util_linux.go @@ -0,0 +1,74 @@ +/* +Copyright 2025 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package securitycontext + +import ( + "os" + "runtime" + "strconv" + "strings" + "sync" +) + +// possibleCPUs returns the number of possible CPUs on this host. +func possibleCPUs() (cpus []int) { + if ncpu := possibleCPUsParsed(); ncpu != nil { + return ncpu + } + + for i := range runtime.NumCPU() { + cpus = append(cpus, i) + } + + return cpus +} + +// possibleCPUsParsed is parsing the amount of possible CPUs on this host from +// /sys/devices. +var possibleCPUsParsed = sync.OnceValue(func() (cpus []int) { + data, err := os.ReadFile("/sys/devices/system/cpu/possible") + if err != nil { + return nil + } + + ranges := strings.Split(strings.TrimSpace(string(data)), ",") + + for _, r := range ranges { + if rStart, rEnd, ok := strings.Cut(r, "-"); !ok { + cpu, err := strconv.Atoi(rStart) + if err != nil { + return nil + } + cpus = append(cpus, cpu) + } else { + var start, end int + start, err := strconv.Atoi(rStart) + if err != nil { + return nil + } + end, err = strconv.Atoi(rEnd) + if err != nil { + return nil + } + for i := start; i <= end; i++ { + cpus = append(cpus, i) + } + } + } + + return cpus +}) diff --git a/vendor/k8s.io/kubernetes/pkg/securitycontext/util_windows.go b/vendor/k8s.io/kubernetes/pkg/securitycontext/util_windows.go new file mode 100644 index 00000000000..9d14502acb7 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/securitycontext/util_windows.go @@ -0,0 +1,21 @@ +/* +Copyright 2025 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package securitycontext + +func possibleCPUs() []int { + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go index 8c9e7584bda..1257437267e 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go @@ -984,7 +984,7 @@ func NewPersistentVolumeRecyclerPodTemplate() *v1.Pod { Containers: []v1.Container{ { Name: "pv-recycler", - Image: "registry.k8s.io/build-image/debian-base:bookworm-v1.0.3", + Image: "registry.k8s.io/build-image/debian-base:bookworm-v1.0.6", Command: []string{"/bin/sh"}, Args: []string{"-c", "test -e /scrub && find /scrub -mindepth 1 -delete && test -z \"$(ls -A /scrub)\" || exit 1"}, VolumeMounts: []v1.VolumeMount{ diff --git a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go index 4312a03d780..67f3e7c92f9 100644 --- a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go +++ b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go @@ -234,7 +234,7 @@ func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.36.1-1"} configs[CudaVectorAdd] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "1.0"} configs[CudaVectorAdd2] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "2.3"} - configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.6.12"} + configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.7.11"} configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.15-0"} configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-4"} configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-4"} diff --git a/vendor/modules.txt b/vendor/modules.txt index 46a0923edee..0661ecabcdd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -693,7 +693,7 @@ gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.1 ## explicit gopkg.in/yaml.v3 -# k8s.io/api v0.31.12 +# k8s.io/api v0.31.14 ## explicit; go 1.22.0 k8s.io/api/admission/v1 k8s.io/api/admission/v1beta1 @@ -758,7 +758,7 @@ k8s.io/api/storagemigration/v1alpha1 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/features -# k8s.io/apimachinery v0.31.12 +# k8s.io/apimachinery v0.31.14 ## explicit; go 1.22.0 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -976,7 +976,7 @@ k8s.io/apiserver/plugin/pkg/audit/webhook k8s.io/apiserver/plugin/pkg/authenticator/token/webhook k8s.io/apiserver/plugin/pkg/authorizer/webhook k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics -# k8s.io/client-go v0.31.12 +# k8s.io/client-go v0.31.14 ## explicit; go 1.22.0 k8s.io/client-go/applyconfigurations k8s.io/client-go/applyconfigurations/admissionregistration/v1 @@ -1332,7 +1332,7 @@ k8s.io/cloud-provider/controllers/service/config k8s.io/cloud-provider/controllers/service/config/v1alpha1 k8s.io/cloud-provider/names k8s.io/cloud-provider/options -# k8s.io/component-base v0.31.12 +# k8s.io/component-base v0.31.14 ## explicit; go 1.22.0 k8s.io/component-base/cli/flag k8s.io/component-base/config @@ -1417,7 +1417,7 @@ k8s.io/kubectl/pkg/util/podutils # k8s.io/kubelet v0.31.12 => k8s.io/kubelet v0.31.12 ## explicit; go 1.22.0 k8s.io/kubelet/pkg/apis -# k8s.io/kubernetes v1.31.12 +# k8s.io/kubernetes v1.31.14 ## explicit; go 1.22.0 k8s.io/kubernetes/pkg/api/legacyscheme k8s.io/kubernetes/pkg/api/service