Files
my-rook-config/pkg/operator/ceph/csi/secrets_test.go
T
dependabot[bot] 3c51e808f2 build(deps): bump the k8s-dependencies group with 6 updates
Bumps the k8s-dependencies group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.34.2` | `0.34.3` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.34.2` | `0.34.3` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.34.2` | `0.34.3` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.34.2` | `0.34.3` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.34.2` | `0.34.3` |
| [k8s.io/cloud-provider](https://github.com/kubernetes/cloud-provider) | `0.34.2` | `0.34.3` |

Updates `k8s.io/api` from 0.34.2 to 0.34.3
- [Commits](https://github.com/kubernetes/api/compare/v0.34.2...v0.34.3)

Updates `k8s.io/apiextensions-apiserver` from 0.34.2 to 0.34.3
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.34.2...v0.34.3)

Updates `k8s.io/apimachinery` from 0.34.2 to 0.34.3
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.34.2...v0.34.3)

Updates `k8s.io/cli-runtime` from 0.34.2 to 0.34.3
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.34.2...v0.34.3)

Updates `k8s.io/client-go` from 0.34.2 to 0.34.3
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.34.2...v0.34.3)

Updates `k8s.io/cloud-provider` from 0.34.2 to 0.34.3
- [Commits](https://github.com/kubernetes/cloud-provider/compare/v0.34.2...v0.34.3)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: k8s-dependencies
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: k8s-dependencies
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: k8s-dependencies
- dependency-name: k8s.io/cli-runtime
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: k8s-dependencies
- dependency-name: k8s.io/client-go
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: k8s-dependencies
- dependency-name: k8s.io/cloud-provider
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: k8s-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-07 07:59:21 -07:00

600 lines
21 KiB
Go

/*
Copyright 2019 The Rook Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package csi
import (
"context"
"fmt"
"reflect"
"testing"
"github.com/pkg/errors"
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
"github.com/rook/rook/pkg/clusterd"
"github.com/rook/rook/pkg/daemon/ceph/client"
"github.com/rook/rook/pkg/operator/ceph/config/keyring"
"github.com/rook/rook/pkg/operator/k8sutil"
exectest "github.com/rook/rook/pkg/util/exec/test"
"github.com/stretchr/testify/assert"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sfake "k8s.io/client-go/kubernetes/fake"
)
const (
mockAuthLs = `{"auth_dump":[
{"entity":"osd.0"},
{"entity":"client.admin"},
{"entity":"client.bootstrap-mds"},
{"entity":"client.bootstrap-rbd-mirror"},
{"entity":"client.csi-rbd-node.10"},
{"entity":"client.csi-rbd-node.4"},
{"entity":"client.csi-rbd-node.2"},
{"entity":"client.csi-rbd-node.1"},
{"entity":"client.csi-cepfs-node"},
{"entity":"client.csi-rbd-node"},
{"entity":"client.csi-rbd-provisioner"},
{"entity":"client.rbd-mirror-peer"},
{"entity":"mgr.a"},
{"entity":"client.csi-cepfs-node"},
{"entity":"client.csi-cephfs-node.2"}
]}`
)
func TestCephCSIKeyringRBDNodeCaps(t *testing.T) {
caps := cephCSIKeyringRBDNodeCaps()
assert.Equal(t, caps, []string{"mon", "profile rbd", "mgr", "allow rw", "osd", "profile rbd"})
}
func TestCephCSIKeyringRBDProvisionerCaps(t *testing.T) {
caps := cephCSIKeyringRBDProvisionerCaps()
assert.Equal(t, caps, []string{"mon", "profile rbd, allow command 'osd blocklist'", "mgr", "allow rw", "osd", "profile rbd"})
}
func TestCephCSIKeyringCephFSNodeCaps(t *testing.T) {
caps := cephCSIKeyringCephFSNodeCaps()
assert.Equal(t, caps, []string{"mon", "allow r", "mgr", "allow rw", "osd", "allow rwx tag cephfs metadata=*, allow rw tag cephfs data=*", "mds", "allow rw"})
}
func TestCephCSIKeyringCephFSProvisionerCaps(t *testing.T) {
caps := cephCSIKeyringCephFSProvisionerCaps()
assert.Equal(t, caps, []string{"mon", "allow r, allow command 'osd blocklist'", "mgr", "allow rw", "osd", "allow rw tag cephfs metadata=*", "mds", "allow *"})
}
func Test_deleteOwnedCSISecretsByCephCluster(t *testing.T) {
const (
namespace = "rook-ceph"
cephCluster = "my-ceph-cluster"
)
// Create fake client
clientset := k8sfake.NewClientset()
// Cluster context
clusterContext := &clusterd.Context{
Clientset: clientset,
}
clusterInfo := &client.ClusterInfo{
OwnerInfo: k8sutil.NewOwnerInfoWithOwnerRef(&metav1.OwnerReference{
APIVersion: "ceph.rook.io/v1",
Kind: "CephCluster",
Name: cephCluster,
}, namespace),
}
clusterInfo.Namespace = namespace
clusterInfo.SetName(cephCluster)
ctx := &clusterd.Context{
Clientset: clientset,
}
k := keyring.GetSecretStore(ctx, clusterInfo, clusterInfo.OwnerInfo)
// create csi secrets
err := createOrUpdateCSISecret(clusterInfo, csiSecretStore{}, k)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Remove ownerRef from the CsiCephFSNodeSecret to ensure it won't get deleted
secret, err := clientset.CoreV1().Secrets(namespace).Get(context.TODO(), CsiCephFSProvisionerSecret, metav1.GetOptions{})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
secret.OwnerReferences = nil
secret.SetOwnerReferences([]metav1.OwnerReference{
{
APIVersion: "ceph.rook.io/v1",
Kind: "CephClient",
Name: "test-client",
},
})
_, err = clientset.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
err = deleteOwnedCSISecretsByCephCluster(clusterContext, clusterInfo)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Verify owned secret is deleted
secrets := []string{CsiRBDNodeSecret, CsiRBDProvisionerSecret, CsiCephFSNodeSecret}
for _, secretName := range secrets {
_, err = clientset.CoreV1().Secrets(namespace).Get(context.TODO(), secretName, metav1.GetOptions{})
if err == nil {
t.Errorf("expected owned secret %q to be deleted", secretName)
}
}
// Verify unowned secret still exists
_, err = clientset.CoreV1().Secrets(namespace).Get(context.TODO(), CsiCephFSProvisionerSecret, metav1.GetOptions{})
if err != nil && apierrors.IsNotFound(err) {
t.Errorf("expected unowned secret %q to still exist", CsiCephFSProvisionerSecret)
}
}
func TestSortCsiClientName(t *testing.T) {
tests := []struct {
args []string
want []string
}{
{
args: []string{"client.csi-rbd-node.10", "client.csi-rbd-node.1", "client.csi-rbd-node.4", "client.csi-rbd-node.2", "client.csi-rbd-node"},
want: []string{
"client.csi-rbd-node", "client.csi-rbd-node.1", "client.csi-rbd-node.2", "client.csi-rbd-node.4", "client.csi-rbd-node.10",
},
},
{
args: []string{"client.csi-rbd-node"},
want: []string{"client.csi-rbd-node"},
},
{
args: []string{},
want: []string{},
},
{
// JFYI, // We'll not have list of mixed client name as argument to `sortCsiClientName`
args: []string{"client.csi-cephfs-node.1", "client.csi-cephfs-node.2", "client.csi-rbd-node.1", "client.csi-cephfs-node", "client.csi-rbd-node"},
want: []string{"client.csi-cephfs-node", "client.csi-rbd-node", "client.csi-cephfs-node.1", "client.csi-rbd-node.1", "client.csi-cephfs-node.2"},
},
}
for _, tt := range tests {
t.Run("testCases", func(t *testing.T) {
got := sortCSIClientName(tt.args)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("sortCsiClientName() go = %v, want %v", got, tt.want)
}
})
}
}
func TestDeleteOldKeyGen(t *testing.T) {
ctx, clusterInfo, _ := loadTestClusterDetails()
ctx.Executor = &exectest.MockExecutor{}
keys := []string{
"client.csi-rbd-node.10", "client.csi-rbd-node.1", "client.csi-rbd-node.4", "client.csi-rbd-node.2", "client.csi-rbd-node",
}
var keyDeleted []string
var err error
// deleting nothing when keep prior count more than current number of existing prior keys
keyDeleted, err = deleteOldKeyGen(ctx, clusterInfo, keys, 5)
assert.NoError(t, err)
assert.Equal(t, []string{}, keyDeleted)
// deleting nothing when keep prior count is same as current number of existing prior keys
keyDeleted, err = deleteOldKeyGen(ctx, clusterInfo, keys, 4)
assert.NoError(t, err)
assert.Equal(t, []string{}, keyDeleted)
// Delete 1 oldest key ("client.csi-rbd-node") is deleted to retain the prior 3 generations.
keyDeleted, err = deleteOldKeyGen(ctx, clusterInfo, keys, 3)
assert.NoError(t, err)
assert.Equal(t, []string{"client.csi-rbd-node"}, keyDeleted)
keyDeleted, err = deleteOldKeyGen(ctx, clusterInfo, keys, 2)
assert.NoError(t, err)
assert.Equal(t, []string{"client.csi-rbd-node", "client.csi-rbd-node.1"}, keyDeleted)
keyDeleted, err = deleteOldKeyGen(ctx, clusterInfo, keys, 1)
assert.NoError(t, err)
assert.Equal(t, []string{"client.csi-rbd-node", "client.csi-rbd-node.1", "client.csi-rbd-node.2"}, keyDeleted)
// No keys should be deleted when the input key list is empty.
keys = []string{}
keyDeleted, err = deleteOldKeyGen(ctx, clusterInfo, keys, 0)
assert.NoError(t, err)
assert.Equal(t, []string{}, keyDeleted)
// When only one key is present and keepCount is 0, no keys should be deleted.
keys = []string{"client.csi-rbd-node"}
keyDeleted, err = deleteOldKeyGen(ctx, clusterInfo, keys, 0)
assert.NoError(t, err)
assert.Equal(t, []string{}, keyDeleted)
// When only one key is present and keepCount is 1, no keys should be deleted.
keys = []string{"client.csi-rbd-node"}
keyDeleted, err = deleteOldKeyGen(ctx, clusterInfo, keys, 1)
assert.NoError(t, err)
assert.Equal(t, []string{}, keyDeleted)
}
func TestGetCsiKeyRotationInfo(t *testing.T) {
ctx, clusterInfo, _ := loadTestClusterDetails()
// Different mock auth responses for testing different currentMaxKeyGen values
mockAuthLsWithMaxGen10 := `{"auth_dump":[
{"entity":"osd.0"},{"entity":"client.admin"},{"entity":"client.bootstrap-mds"},{"entity":"client.bootstrap-rbd-mirror"},{"entity":"client.csi-rbd-node.10"},
{"entity":"client.csi-rbd-node.4"},{"entity":"client.csi-rbd-node.2"},{"entity":"client.csi-rbd-node.1"},{"entity":"client.csi-cepfs-node"},
{"entity":"client.csi-rbd-node"},{"entity":"client.csi-rbd-provisioner"},{"entity":"client.rbd-mirror-peer"},{"entity":"mgr.a"},
{"entity":"client.csi-cepfs-node"},{"entity":"client.csi-cephfs-node.2"}
]}`
mockAuthLsWithMaxGen5 := `{"auth_dump":[
{"entity":"osd.0"},{"entity":"client.admin"},{"entity":"client.bootstrap-mds"},{"entity":"client.bootstrap-rbd-mirror"},
{"entity":"client.csi-rbd-node.5"},{"entity":"client.csi-rbd-node.3"},{"entity":"client.csi-rbd-node.1"},{"entity":"client.csi-cepfs-node"},
{"entity":"client.csi-rbd-node"},{"entity":"client.csi-rbd-provisioner"},{"entity":"client.rbd-mirror-peer"},{"entity":"mgr.a"}
]}`
mockAuthLsWithMaxGen0 := `{"auth_dump":[
{"entity":"osd.0"},{"entity":"client.admin"},{"entity":"client.bootstrap-mds"},{"entity":"client.bootstrap-rbd-mirror"},
{"entity":"client.csi-cepfs-node"},{"entity":"client.csi-rbd-node"},{"entity":"client.csi-rbd-provisioner"},{"entity":"client.rbd-mirror-peer"},{"entity":"mgr.a"}
]}`
mockAuthLsEmpty := `{"auth_dump":[]}`
mockAuthLsNoCSIKeys := `{"auth_dump":[
{"entity":"osd.0"},{"entity":"client.admin"},{"entity":"client.bootstrap-mds"},{"entity":"client.bootstrap-rbd-mirror"},
{"entity":"client.rbd-mirror-peer"},{"entity":"mgr.a"}
]}`
tests := []struct {
name string
mockAuthResponse string
mockError error
expectedMaxKeyGen int
expectedKeyList []string
expectError bool
errorType string
}{
{
name: "currentMaxKeyGen 10 with multiple generations",
mockAuthResponse: mockAuthLsWithMaxGen10,
mockError: nil,
expectedMaxKeyGen: 10,
expectedKeyList: []string{"client.csi-rbd-node.10", "client.csi-rbd-node.4", "client.csi-rbd-node.2", "client.csi-rbd-node.1", "client.csi-rbd-node"},
expectError: false,
},
{
name: "currentMaxKeyGen 5 with fewer generations",
mockAuthResponse: mockAuthLsWithMaxGen5,
mockError: nil,
expectedMaxKeyGen: 5,
expectedKeyList: []string{"client.csi-rbd-node.5", "client.csi-rbd-node.3", "client.csi-rbd-node.1", "client.csi-rbd-node"},
expectError: false,
},
{
name: "currentMaxKeyGen 0 with only base name",
mockAuthResponse: mockAuthLsWithMaxGen0,
mockError: nil,
expectedMaxKeyGen: 0,
expectedKeyList: []string{"client.csi-rbd-node"},
expectError: false,
},
{
name: "empty auth list returns no keys",
mockAuthResponse: mockAuthLsEmpty,
mockError: nil,
expectedMaxKeyGen: 0,
expectedKeyList: []string{},
expectError: false,
},
{
name: "no CSI keys found returns empty list",
mockAuthResponse: mockAuthLsNoCSIKeys,
mockError: nil,
expectedMaxKeyGen: 0,
expectedKeyList: []string{},
expectError: false,
},
{
name: "auth list command fails with timeout error",
mockAuthResponse: "",
mockError: errors.New("timeout: command execution exceeded time limit"),
expectedMaxKeyGen: 0,
expectedKeyList: []string{},
expectError: true,
errorType: "timeout",
},
{
name: "invalid JSON response from auth list",
mockAuthResponse: `{"auth_dump":[invalid json}`,
mockError: nil,
expectedMaxKeyGen: 0,
expectedKeyList: []string{},
expectError: true,
errorType: "invalid_json",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
executor := &exectest.MockExecutor{}
executor.MockExecuteCommandWithOutput = func(command string, args ...string) (string, error) {
logger.Infof("Command: %s %v", command, args)
if args[0] == "auth" && args[1] == "ls" {
if tt.mockError != nil {
return "", tt.mockError
}
return tt.mockAuthResponse, nil
}
return "", errors.New("unknown command")
}
ctx.Executor = executor
currentMaxKeyGen, keysWithBaseName, err := getCsiKeyRotationInfo(ctx, clusterInfo, csiKeyringRBDNodeUsername)
if tt.expectError {
assert.Error(t, err, "Expected error for test case: %s", tt.name)
assert.Equal(t, tt.expectedMaxKeyGen, currentMaxKeyGen, "Max key generation should be 0 on error")
assert.Equal(t, tt.expectedKeyList, keysWithBaseName, "Key list should be empty on error")
if tt.errorType == "timeout" {
assert.Contains(t, err.Error(), "timeout", "Error should contain timeout message")
}
} else {
assert.NoError(t, err, "No error expected for test case: %s", tt.name)
assert.Equal(t, tt.expectedMaxKeyGen, currentMaxKeyGen, "Max key generation mismatch for test case: %s", tt.name)
assert.Equal(t, tt.expectedKeyList, keysWithBaseName, "Key list mismatch for test case: %s", tt.name)
}
})
}
}
func TestGetCSIKeyInfoAndDeleteOldKey(t *testing.T) {
ctx, clusterInfo, clusterSpec := loadTestClusterDetails()
clusterSpec.Security.CephX.CSI.KeyGeneration = 18
executor := &exectest.MockExecutor{}
ctx.Executor = executor
keyList := []string{"client.csi-rbd-node.10", "client.csi-rbd-node.4", "client.csi-rbd-node.2", "client.csi-rbd-node.1", "client.csi-rbd-node"}
executor.MockExecuteCommandWithOutput = func(command string, args ...string) (string, error) {
logger.Infof("Command: %s %v", command, args)
if args[0] == "auth" && args[1] == "ls" {
return mockAuthLs, nil
}
panic(fmt.Sprintf("unexpected command %s %v", command, args))
}
currentMaxKeyGen, keyWithBaseName, err := getCsiKeyRotationInfo(ctx, clusterInfo, csiKeyringRBDNodeUsername)
assert.NoError(t, err)
assert.Equal(t, 10, currentMaxKeyGen)
assert.Equal(t, keyList, keyWithBaseName)
tests := []struct {
name string
keyList []string
keepCount uint8
wantDeleted []string
}{
{"test deletion", keyWithBaseName, 2, []string{"client.csi-rbd-node", "client.csi-rbd-node.1"}},
{"keep count = current gen", keyWithBaseName, 10, []string{}},
{"keep count > current gen", keyWithBaseName, 11, []string{}},
{"keep count 0", keyWithBaseName, 0, []string{"client.csi-rbd-node", "client.csi-rbd-node.1", "client.csi-rbd-node.2", "client.csi-rbd-node.4"}},
{"keep count 1", keyWithBaseName, 1, []string{"client.csi-rbd-node", "client.csi-rbd-node.1", "client.csi-rbd-node.2"}},
{"keep count 2", keyWithBaseName, 2, []string{"client.csi-rbd-node", "client.csi-rbd-node.1"}},
{"keep count 3", keyWithBaseName, 3, []string{"client.csi-rbd-node"}},
{"keep count = current count - 1 = 4", keyWithBaseName, 4, []string{}},
{"keep count = current count = 5", keyWithBaseName, 5, []string{}},
{"keep count > current count", keyWithBaseName, 6, []string{}},
{"key list empty, keep count 0", []string{}, 0, []string{}},
{"key list empty, keep count 1", []string{}, 1, []string{}},
{"key list empty, keep count 3", []string{}, 3, []string{}},
{"key list with 1 item, keep count 0", []string{"client.csi-rbd-node"}, 0, []string{}},
{"key list with 1 item, keep count 1", []string{"client.csi-rbd-node"}, 1, []string{}},
{"key list with 1 item, keep count 3", []string{"client.csi-rbd-node"}, 3, []string{}},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
delKeyArgList := []string{}
executor.MockExecuteCommandWithOutput = func(command string, args ...string) (string, error) {
logger.Infof("Command: %s %v", command, args)
if args[0] == "auth" && args[1] == "ls" {
return mockAuthLs, nil
} else if args[0] == "auth" && args[1] == "del" {
delKeyArgList = append(delKeyArgList, args[2])
return "", nil
}
panic(fmt.Sprintf("unexpected command %s %v", command, args))
}
keyDeleted, err := deleteOldKeyGen(ctx, clusterInfo, test.keyList, test.keepCount)
assert.NoError(t, err)
assert.Equal(t, test.wantDeleted, keyDeleted)
assert.Equal(t, test.wantDeleted, delKeyArgList)
})
}
}
func loadTestClusterDetails() (*clusterd.Context, *client.ClusterInfo, *cephv1.ClusterSpec) {
namespace := "rook-ceph"
cephCluster := "my-ceph-cluster"
clusterInfo := &client.ClusterInfo{
OwnerInfo: k8sutil.NewOwnerInfoWithOwnerRef(&metav1.OwnerReference{
APIVersion: "ceph.rook.io/v1",
Kind: "CephCluster",
Name: cephCluster,
}, namespace),
Context: context.TODO(),
CephVersion: keyring.CephAuthRotateSupportedVersion,
}
clusterInfo.Namespace = namespace
clusterInfo.SetName(cephCluster)
clusterSpec := &cephv1.ClusterSpec{
Security: cephv1.ClusterSecuritySpec{
CephX: cephv1.ClusterCephxConfig{
CSI: cephv1.CephXConfigWithPriorCount{
CephxConfig: cephv1.CephxConfig{
KeyRotationPolicy: "KeyGeneration",
},
},
},
},
}
clientset := k8sfake.NewClientset()
ctx := &clusterd.Context{
Clientset: clientset,
}
return ctx, clusterInfo, clusterSpec
}
func Test_getMatchingClient(t *testing.T) {
clientBaseName := csiKeyringRBDNodeUsername
want := []string{clientBaseName, clientBaseName + ".1", clientBaseName + ".2", clientBaseName + ".3"}
t.Run("auth list is valid", func(t *testing.T) {
authList := client.AuthListOutput{
AuthDump: []client.AuthListEntry{
{Entity: clientBaseName}, {Entity: clientBaseName + ".1"}, {Entity: clientBaseName + ".2"}, {Entity: clientBaseName + ".3"}, {Entity: csiKeyringRBDProvisionerUsername + ".4"},
},
}
got, err := getMatchingClient(authList, clientBaseName)
assert.NoError(t, err)
assert.Equal(t, want, got)
})
// When fresh cluster is deployed `authList` will be empty
t.Run("auth list empty", func(t *testing.T) {
authList := client.AuthListOutput{
AuthDump: []client.AuthListEntry{},
}
got, err := getMatchingClient(authList, clientBaseName)
assert.NoError(t, err)
assert.Equal(t, []string{}, got)
})
// When no matching key found in `authList` means key is created for first time
t.Run("auth list doesn't contain match", func(t *testing.T) {
authList := client.AuthListOutput{
AuthDump: []client.AuthListEntry{
{Entity: clientBaseName}, {Entity: clientBaseName + ".1"}, {Entity: clientBaseName + ".2"}, {Entity: clientBaseName + ".3"},
},
}
got, err := getMatchingClient(authList, csiKeyringRBDProvisionerUsername)
assert.NoError(t, err)
assert.Equal(t, []string{}, got)
})
}
func TestParseCsiClient(t *testing.T) {
tests := []struct {
args string
baseName string
keyGen int
wantErr bool
}{
{args: "client.csi-rbd-node", baseName: "client.csi-rbd-node", keyGen: 0, wantErr: false},
{args: "client.csi-rbd-node.10", baseName: "client.csi-rbd-node", keyGen: 10, wantErr: false},
{args: "client.csi-rbd-node.9", baseName: "client.csi-rbd-node", keyGen: 9, wantErr: false},
{args: "client.csi-rbd-node.", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node.1a", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node.a1", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node. ", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node. 1", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node .1", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node.1 ", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node. a", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node .a", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node.a ", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node. a1", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node.a1 ", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node. a1", baseName: "", keyGen: 0, wantErr: true},
{args: " client.csi-rbd-node. ", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node. 1a", baseName: "", keyGen: 0, wantErr: true},
{args: "client.csi-rbd-node .1a", baseName: "", keyGen: 0, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.args, func(t *testing.T) {
got, got1, err := parseCsiClient(tt.args)
if (err != nil) != tt.wantErr {
t.Errorf("parseCsiClient() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.baseName {
t.Errorf("parseCsiClient() got = %v, want %v", got, tt.baseName)
}
if got1 != tt.keyGen {
t.Errorf("parseCsiClient() got1 = %v, want %v", got1, tt.keyGen)
}
})
}
}
func TestGetPriorKeyCount(t *testing.T) {
tests := []struct {
name string
keyCount int
want int
}{
{"keyGen 0", 0, 0},
{"keyGen 1", 1, 0},
{"keyGen 2", 2, 1},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := getPriorKeyCount(tt.keyCount)
assert.Equal(t, tt.want, got)
})
}
}
func Test_deleteCount(t *testing.T) {
tests := []struct {
numKeys int
keepPriorCount int
want int
}{
{2, 0, 1},
{3, 0, 2},
{4, 0, 3},
{2, 1, 0},
{3, 1, 1},
{4, 1, 2},
{2, 2, 0},
{3, 2, 0},
{4, 2, 1},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("%d,%d", tt.numKeys, tt.keepPriorCount), func(t *testing.T) {
if got := deleteCount(tt.numKeys, tt.keepPriorCount); got != tt.want {
t.Errorf("deleteCount() = %v, want %v", got, tt.want)
}
})
}
}