diff --git a/docs/volumegroupreplicationclass.md b/docs/volumegroupreplicationclass.md new file mode 100644 index 000000000..969fef727 --- /dev/null +++ b/docs/volumegroupreplicationclass.md @@ -0,0 +1,24 @@ +# VolumeGroupReplicationClass + +VolumeGroupReplicationClass is a cluster scoped resource that contains driver related configuration parameters for volume group replication. + +`provisioner` is name of the storage provisioner. + +`parameters` contains key-value pairs that are passed down to the driver. Users can add their own key-value pairs. Keys with `replication.storage.openshift.io/` prefix are reserved by operator and not passed down to the driver. + +## Reserved parameter keys + +- `replication.storage.openshift.io/group-replication-secret-name` +- `replication.storage.openshift.io/group-replication-secret-namespace` + +```yaml +apiVersion: replication.storage.openshift.io/v1alpha1 +kind: VolumeGroupReplicationClass +metadata: + name: volumegroupreplicationclass-sample +spec: + provisioner: example.provisioner.io + parameters: + replication.storage.openshift.io/group-replication-secret-name: secret-name + replication.storage.openshift.io/group-replication-secret-namespace: secret-namespace +``` diff --git a/internal/controller/replication.storage/parameters.go b/internal/controller/replication.storage/parameters.go index 1f3f58404..08182c73f 100644 --- a/internal/controller/replication.storage/parameters.go +++ b/internal/controller/replication.storage/parameters.go @@ -29,8 +29,10 @@ const ( // Driver. replicationParameterPrefix = "replication.storage.openshift.io/" - prefixedReplicationSecretNameKey = replicationParameterPrefix + "replication-secret-name" // name key for secret - prefixedReplicationSecretNamespaceKey = replicationParameterPrefix + "replication-secret-namespace" // namespace key secret + prefixedReplicationSecretNameKey = replicationParameterPrefix + "replication-secret-name" // name key for secret + prefixedReplicationSecretNamespaceKey = replicationParameterPrefix + "replication-secret-namespace" // namespace key secret + prefixedGroupReplicationSecretNameKey = replicationParameterPrefix + "group-replication-secret-name" // name key for secret + prefixedGroupReplicationSecretNamespaceKey = replicationParameterPrefix + "group-replication-secret-namespace" // namespace key secret ) // filterPrefixedParameters removes all the reserved keys from the @@ -53,10 +55,14 @@ func validatePrefixedParameters(param map[string]string) error { if strings.HasPrefix(k, replicationParameterPrefix) { switch k { case prefixedReplicationSecretNameKey: + fallthrough + case prefixedGroupReplicationSecretNameKey: if v == "" { return errors.New("secret name cannot be empty") } case prefixedReplicationSecretNamespaceKey: + fallthrough + case prefixedGroupReplicationSecretNamespaceKey: if v == "" { return errors.New("secret namespace cannot be empty") } diff --git a/internal/controller/replication.storage/volumegroupreplicationclass.go b/internal/controller/replication.storage/volumegroupreplicationclass.go new file mode 100644 index 000000000..d4e939abb --- /dev/null +++ b/internal/controller/replication.storage/volumegroupreplicationclass.go @@ -0,0 +1,45 @@ +/* +Copyright 2025 The Kubernetes-CSI-Addons 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 controller + +import ( + "context" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + + replicationv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1" +) + +// getVolumeGroupReplicationClass fetches the volumegroupreplicationclass object in the given namespace and return the same. +// nolint:unused // Ignore unused function, will be updated later +func (r VolumeGroupReplicationReconciler) getVolumeGroupReplicationClass(logger logr.Logger, vgrClassName string) (*replicationv1alpha1.VolumeGroupReplicationClass, error) { + vgrClassObj := &replicationv1alpha1.VolumeGroupReplicationClass{} + err := r.Client.Get(context.TODO(), types.NamespacedName{Name: vgrClassName}, vgrClassObj) + if err != nil { + if errors.IsNotFound(err) { + logger.Error(err, "VolumeGroupReplicationClass not found", "VolumeGroupReplicationClass", vgrClassName) + } else { + logger.Error(err, "Got an unexpected error while fetching VolumeGroupReplicationClass", "VolumeGroupReplicationClass", vgrClassName) + } + + return nil, err + } + + return vgrClassObj, nil +}