Merge pull request #16066 from rook/mergify/bp/release-1.17/pr-16061

csi: Provide a flag to skip csi user creation (backport #16061)
This commit is contained in:
Travis Nielsen authored and GitHub committed 2025-06-27 15:41:32 -06:00
commit 4e17072b2c
6 files changed
+142

No files matched your search

+13
View File
@@ -3120,6 +3120,19 @@ CSICephFSSpec
<p>CephFS defines CSI Driver settings for CephFS driver.</p>
</td>
</tr>
<tr>
<td>
<code>skipUserCreation</code><br/>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>SkipUserCreation determines whether CSI users and their associated secrets should be skipped.
If set to true, the user must manually manage these secrets.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="ceph.rook.io/v1.Capacity">Capacity
@@ -1560,6 +1560,11 @@ spec:
description: Enables read affinity for CSI driver.
type: boolean
type: object
skipUserCreation:
description: |-
SkipUserCreation determines whether CSI users and their associated secrets should be skipped.
If set to true, the user must manually manage these secrets.
type: boolean
type: object
dashboard:
description: Dashboard settings
+5
View File
@@ -1558,6 +1558,11 @@ spec:
description: Enables read affinity for CSI driver.
type: boolean
type: object
skipUserCreation:
description: |-
SkipUserCreation determines whether CSI users and their associated secrets should be skipped.
If set to true, the user must manually manage these secrets.
type: boolean
type: object
dashboard:
description: Dashboard settings
+4
View File
@@ -255,6 +255,10 @@ type CSIDriverSpec struct {
// CephFS defines CSI Driver settings for CephFS driver.
// +optional
CephFS CSICephFSSpec `json:"cephfs,omitempty"`
// SkipUserCreation determines whether CSI users and their associated secrets should be skipped.
// If set to true, the user must manually manage these secrets.
// +optional
SkipUserCreation bool `json:"skipUserCreation,omitempty"`
}
// CSICephFSSpec defines the settings for CephFS CSI driver.
+32
View File
@@ -17,6 +17,8 @@ limitations under the License.
package csi
import (
"fmt"
"github.com/pkg/errors"
"github.com/rook/rook/pkg/clusterd"
"github.com/rook/rook/pkg/daemon/ceph/client"
@@ -172,6 +174,13 @@ func createOrUpdateCSISecret(clusterInfo *client.ClusterInfo, csiRBDProvisionerS
// CreateCSISecrets creates all the Kubernetes CSI Secrets
func CreateCSISecrets(context *clusterd.Context, clusterInfo *client.ClusterInfo) error {
if clusterInfo.CSIDriverSpec.SkipUserCreation {
if err := deleteOwnedCSISecretsByCephCluster(context, clusterInfo); err != nil {
return err
}
logger.Info("CSI user creation is disabled; skipping user and secret creation")
return nil
}
k := keyring.GetSecretStore(context, clusterInfo, clusterInfo.OwnerInfo)
// Create CSI RBD Provisioner Ceph key
@@ -205,3 +214,26 @@ func CreateCSISecrets(context *clusterd.Context, clusterInfo *client.ClusterInfo
return nil
}
func deleteOwnedCSISecretsByCephCluster(context *clusterd.Context, clusterInfo *client.ClusterInfo) error {
ownerRef := metav1.OwnerReference{
APIVersion: "ceph.rook.io/v1",
Kind: "CephCluster",
Name: clusterInfo.NamespacedName().Name,
}
secrets := []string{CsiRBDNodeSecret, CsiRBDProvisionerSecret, CsiCephFSNodeSecret, CsiCephFSProvisionerSecret}
for _, secretName := range secrets {
err := k8sutil.DeleteSecretIfOwnedBy(
clusterInfo.Context,
context.Clientset,
secretName,
clusterInfo.Namespace,
ownerRef,
)
if err != nil {
return fmt.Errorf("failed to delete secret %q: %w", secretName, err)
}
}
return nil
}
+83
View File
@@ -17,9 +17,17 @@ limitations under the License.
package csi
import (
"context"
"testing"
"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"
"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"
)
func TestCephCSIKeyringRBDNodeCaps(t *testing.T) {
@@ -41,3 +49,78 @@ 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.NewSimpleClientset()
// 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, "", "", "", "", 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)
}
}