Skip to content

Commit

Permalink
controllers: Generates VGSClass
Browse files Browse the repository at this point in the history
Signed-off-by: raaizik <[email protected]>
  • Loading branch information
raaizik committed Nov 13, 2024
1 parent 284e512 commit 523d103
Show file tree
Hide file tree
Showing 10 changed files with 1,069 additions and 10 deletions.
18 changes: 18 additions & 0 deletions bundle/manifests/ocs-client-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,24 @@ spec:
- list
- update
- watch
- apiGroups:
- groupsnapshot.storage.k8s.io
resources:
- volumegroupsnapshotclasses
verbs:
- create
- delete
- get
- list
- watch
- apiGroups:
- groupsnapshot.storage.k8s.io
resources:
- volumegroupsnapshotcontents
verbs:
- get
- list
- watch
- apiGroups:
- monitoring.coreos.com
resources:
Expand Down
1 change: 1 addition & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ func main() {
Scheme: mgr.GetScheme(),
OperatorNamespace: utils.GetOperatorNamespace(),
ConsolePort: int32(consolePort),
AvailCrds: availCrds,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "OperatorConfigMapReconciler")
os.Exit(1)
Expand Down
18 changes: 18 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,24 @@ rules:
- list
- update
- watch
- apiGroups:
- groupsnapshot.storage.k8s.io
resources:
- volumegroupsnapshotclasses
verbs:
- create
- delete
- get
- list
- watch
- apiGroups:
- groupsnapshot.storage.k8s.io
resources:
- volumegroupsnapshotcontents
verbs:
- get
- list
- watch
- apiGroups:
- monitoring.coreos.com
resources:
Expand Down
5 changes: 5 additions & 0 deletions internal/controller/operatorconfigmap_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type OperatorConfigMapReconciler struct {
OperatorNamespace string
ConsolePort int32
Scheme *runtime.Scheme
AvailCrds map[string]bool

log logr.Logger
ctx context.Context
Expand Down Expand Up @@ -327,6 +328,10 @@ func (c *OperatorConfigMapReconciler) reconcileDelegatedCSI() error {
templates.CSIOperatorConfigSpec.DeepCopyInto(&csiOperatorConfig.Spec)
csiOperatorConfig.Spec.DriverSpecDefaults.ImageSet = &corev1.LocalObjectReference{Name: cmName}
csiOperatorConfig.Spec.DriverSpecDefaults.ClusterName = ptr.To(string(clusterVersion.Spec.ClusterID))
if c.AvailCrds[volumeGroupSnapshotClassCrd] {
csiOperatorConfig.Spec.DriverSpecDefaults.SnapshotPolicy = csiopv1a1.VolumeGroupSnapshotPolicy
}

return nil
}); err != nil {
return fmt.Errorf("failed to reconcile csi operator config: %v", err)
Expand Down
88 changes: 78 additions & 10 deletions internal/controller/storageclaim_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
csiopv1a1 "github.com/ceph/ceph-csi-operator/api/v1alpha1"
"github.com/go-logr/logr"

groupsnapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1alpha1"
snapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
ramenv1alpha1 "github.com/ramendr/ramen/api/v1alpha1"
providerclient "github.com/red-hat-storage/ocs-operator/services/provider/api/v4/client"
Expand All @@ -56,9 +57,10 @@ const (
storageClaimAnnotation = "ocs.openshift.io/storageclaim"
keyRotationAnnotation = "keyrotation.csiaddons.openshift.io/schedule"

pvClusterIDIndexName = "index:persistentVolumeClusterID"
vscClusterIDIndexName = "index:volumeSnapshotContentCSIDriver"
drClusterConfigCRDName = "drclusterconfigs.ramendr.openshift.io"
pvClusterIDIndexName = "index:persistentVolumeClusterID"
vscClusterIDIndexName = "index:volumeSnapshotContentCSIDriver"
volumeGroupSnapshotClassCrd = "groupsnapshot.storage.k8s.io/volumegroupsnapshotclass"
drClusterConfigCRDName = "drclusterconfigs.ramendr.openshift.io"
)

// StorageClaimReconciler reconciles a StorageClaim object
Expand Down Expand Up @@ -120,11 +122,16 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
&extv1.CustomResourceDefinition{},
&handler.EnqueueRequestForObject{},
builder.WithPredicates(
utils.NamePredicate(volumeGroupSnapshotClassCrd),
utils.CrdCreateAndDeletePredicate(&r.log, volumeGroupSnapshotClassCrd, r.AvailableCrds[volumeGroupSnapshotClassCrd]),
utils.NamePredicate(drClusterConfigCRDName),
utils.CrdCreateAndDeletePredicate(&r.log, drClusterConfigCRDName, r.AvailableCrds[drClusterConfigCRDName]),
),
builder.OnlyMetadata,
)
if r.AvailableCrds[volumeGroupSnapshotClassCrd] {
bldr = bldr.Owns(&groupsnapapi.VolumeGroupSnapshotClass{})
}

if r.AvailableCrds[drClusterConfigCRDName] {
bldr = bldr.Owns(&ramenv1alpha1.DRClusterConfig{}, builder.WithPredicates(generationChangePredicate))
Expand All @@ -139,8 +146,10 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;delete
//+kubebuilder:rbac:groups=storage.k8s.io,resources=storageclasses,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotclasses,verbs=get;list;watch;create;delete
//+kubebuilder:rbac:groups=groupsnapshot.storage.k8s.io,resources=volumegroupsnapshotclasses,verbs=create;delete;get;list;watch
//+kubebuilder:rbac:groups=core,resources=persistentvolumes,verbs=get;list;watch
//+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotcontents,verbs=get;list;watch
//+kubebuilder:rbac:groups=groupsnapshot.storage.k8s.io,resources=volumegroupsnapshotcontents,verbs=get;list;watch
//+kubebuilder:rbac:groups=csi.ceph.io,resources=clientprofiles,verbs=get;list;update;create;watch;delete
//+kubebuilder:rbac:groups=ramendr.openshift.io,resources=drclusterconfigs,verbs=get;list;update;create;watch;delete

Expand All @@ -160,13 +169,15 @@ func (r *StorageClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request
r.log.Info("Reconciling StorageClaim.")

crd := &metav1.PartialObjectMetadata{}
crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
crd.Name = drClusterConfigCRDName
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
r.log.Error(err, "Failed to get CRD", "CRD", drClusterConfigCRDName)
return reconcile.Result{}, err
for _, crdName := range []string{volumeGroupSnapshotClassCrd, drClusterConfigCRDName} {
crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
crd.Name = crdName
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
r.log.Error(err, "Failed to get CRD", "CRD", crdName)
return reconcile.Result{}, err
}
utils.AssertEqual(r.AvailableCrds[crdName], crd.UID != "", utils.ExitCodeThatShouldRestartTheProcess)
}
utils.AssertEqual(r.AvailableCrds[drClusterConfigCRDName], crd.UID != "", utils.ExitCodeThatShouldRestartTheProcess)

// Fetch the StorageClaim instance
r.storageClaim = &v1alpha1.StorageClaim{}
Expand Down Expand Up @@ -422,7 +433,31 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
return nil
})
if err != nil {
return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeSnapshotClass: %s", err)
return reconcile.Result{}, fmt.Errorf("failed to create or update StorageClass: %s", err)
}
case "VolumeGroupSnapshotClass":
// check for CRD availability
if r.AvailableCrds[("VolumeGroupSnapshotClass")] {
var volumeGroupSnapshotClass *groupsnapapi.VolumeGroupSnapshotClass
data := map[string]string{}
err = json.Unmarshal(resource.Data, &data)
if err != nil {
return reconcile.Result{}, fmt.Errorf("failed to unmarshal StorageClaim configuration response: %v", err)
}
data["csi.storage.k8s.io/group-snapshotter-secret-namespace"] = r.OperatorNamespace
// generate a new clusterID for cephfs subvolumegroup, as
// storageclaim is clusterscoped resources using its
// hash as the clusterID
data["clusterID"] = r.storageClaimHash
volumeGroupSnapshotClass = r.getCephDriverVolumeGroupSnapshotClass(resource.Labels, resource.Annotations)
utils.AddAnnotation(volumeGroupSnapshotClass, storageClaimAnnotation, r.storageClaim.Name)
err = utils.CreateOrReplace(r.ctx, r.Client, volumeGroupSnapshotClass, func() error {
volumeGroupSnapshotClass.Parameters = data
return nil
})
if err != nil {
return reconcile.Result{}, fmt.Errorf("failed to create or update StorageClass: %s", err)
}
}
case "ClientProfile":
clientProfile := &csiopv1a1.ClientProfile{}
Expand Down Expand Up @@ -466,6 +501,11 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
} else if exist {
return reconcile.Result{}, fmt.Errorf("one or more volumesnapshotcontents exist that are dependent on storageclaim %s", r.storageClaim.Name)
}
if exist, err := r.hasVolumeGroupSnapshotContents(); err != nil {
return reconcile.Result{}, fmt.Errorf("failed to verify volumegroupsnapshotcontents dependent on storageclaim %q: %v", r.storageClaim.Name, err)
} else if exist {
return reconcile.Result{}, fmt.Errorf("one or more volumegroupsnapshotcontents exist that are dependent on storageclaim %s", r.storageClaim.Name)
}

// Call `RevokeStorageClaim` service on the provider server with StorageClaim as a request message.
// Check if StorageClaim is still exists (it might have been manually removed during the StorageClass
Expand Down Expand Up @@ -550,6 +590,20 @@ func (r *StorageClaimReconciler) getCephRBDVolumeSnapshotClass() *snapapi.Volume
return volumesnapshotclass
}

func (r *StorageClaimReconciler) getCephDriverVolumeGroupSnapshotClass(
labels map[string]string, annotations map[string]string) *groupsnapapi.VolumeGroupSnapshotClass {
volumegroupsnapshotclass := &groupsnapapi.VolumeGroupSnapshotClass{
ObjectMeta: metav1.ObjectMeta{
Name: r.storageClaim.Name,
Labels: labels,
Annotations: annotations,
},
Driver: templates.RBDDriverName,
DeletionPolicy: snapapi.VolumeSnapshotContentDelete,
}
return volumegroupsnapshotclass
}

func (r *StorageClaimReconciler) get(obj client.Object) error {
key := client.ObjectKeyFromObject(obj)
return r.Client.Get(r.ctx, key, obj)
Expand Down Expand Up @@ -594,3 +648,17 @@ func (r *StorageClaimReconciler) hasVolumeSnapshotContents() (bool, error) {

return false, nil
}

func (r *StorageClaimReconciler) hasVolumeGroupSnapshotContents() (bool, error) {
vscList := &groupsnapapi.VolumeGroupSnapshotContentList{}
if err := r.list(vscList, client.MatchingFields{vscClusterIDIndexName: r.storageClaimHash}); err != nil {
return false, fmt.Errorf("failed to list volume group snapshot content resources: %v", err)
}

if len(vscList.Items) != 0 {
r.log.Info(fmt.Sprintf("VolumeGroupSnapshotContent referring storageclaim %q exists", r.storageClaim.Name))
return true, nil
}

return false, nil
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 523d103

Please sign in to comment.