diff --git a/cmd/cephcsi.go b/cmd/cephcsi.go index bc6e1c7a3a0..b56b0cef7d5 100644 --- a/cmd/cephcsi.go +++ b/cmd/cephcsi.go @@ -26,6 +26,7 @@ import ( "github.com/ceph/ceph-csi/internal/cephfs" "github.com/ceph/ceph-csi/internal/controller" "github.com/ceph/ceph-csi/internal/controller/persistentvolume" + "github.com/ceph/ceph-csi/internal/controller/volumegroup" "github.com/ceph/ceph-csi/internal/liveness" nfsdriver "github.com/ceph/ceph-csi/internal/nfs/driver" rbddriver "github.com/ceph/ceph-csi/internal/rbd/driver" @@ -294,6 +295,7 @@ func setPIDLimit(conf *util.Config) { func initControllers() { // Add list of controller here. persistentvolume.Init() + volumegroup.Init() } func validateCloneDepthFlag(conf *util.Config) { diff --git a/go.mod b/go.mod index 10ccfe85a8a..8f876e7ca69 100644 --- a/go.mod +++ b/go.mod @@ -48,8 +48,11 @@ require ( require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.3.0 + github.com/csi-addons/kubernetes-csi-addons v0.9.0 ) +require github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect @@ -87,7 +90,6 @@ require ( github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -156,7 +158,7 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.9.0 // indirect diff --git a/go.sum b/go.sum index ec58b520cb0..ee33543a189 100644 --- a/go.sum +++ b/go.sum @@ -1504,6 +1504,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/csi-addons/kubernetes-csi-addons v0.9.0 h1:Hhb44WcrxtbzmpLY+uqX+DBWCI6HgA/rwQMPyvsyCc8= +github.com/csi-addons/kubernetes-csi-addons v0.9.0/go.mod h1:/YROZDdEi1N/1Ls9rdU5W2VNjm8MK7HHApl8W4Sqt9s= github.com/csi-addons/spec v0.2.1-0.20241104111131-27825f744db5 h1:j9NaWj5KmzEVarmsjxS/NDAhes6Uzq1qhkUGHvDlVBk= github.com/csi-addons/spec v0.2.1-0.20241104111131-27825f744db5/go.mod h1:Mwq4iLiUV4s+K1bszcWU6aMsR5KPsbIYzzszJ6+56vI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -2414,8 +2416,9 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/internal/cephfs/store/volumegroup.go b/internal/cephfs/store/volumegroup.go index 1140dcf6cc2..e2f69bb4435 100644 --- a/internal/cephfs/store/volumegroup.go +++ b/internal/cephfs/store/volumegroup.go @@ -249,7 +249,7 @@ func ReserveVolumeGroup( defer j.Destroy() groupUUID, vgsi.FsVolumeGroupSnapshotName, err = j.ReserveName( - ctx, volOptions.MetadataPool, volOptions.RequestName, volOptions.NamePrefix) + ctx, volOptions.MetadataPool, volOptions.RequestName, volOptions.ReservedID, volOptions.NamePrefix) if err != nil { return nil, err } diff --git a/internal/controller/controller.go b/internal/controller/controller.go index 5c4693d7d22..9ea1caf6552 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -20,13 +20,17 @@ import ( "github.com/ceph/ceph-csi/internal/util/log" - "k8s.io/apimachinery/pkg/runtime" + apiruntime "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "k8s.io/client-go/tools/leaderelection/resourcelock" clientConfig "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/manager/signals" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + + replicationv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1" ) // Manager is the interface that will wrap Add function. @@ -62,6 +66,9 @@ func addToManager(mgr manager.Manager, config Config) error { // Start will start all the registered managers. func Start(config Config) error { + scheme := apiruntime.NewScheme() + utilruntime.Must(replicationv1alpha1.AddToScheme(scheme)) + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) electionID := config.DriverName + "-" + config.Namespace opts := manager.Options{ LeaderElection: true, @@ -70,11 +77,12 @@ func Start(config Config) error { LeaderElectionNamespace: config.Namespace, LeaderElectionResourceLock: resourcelock.LeasesResourceLock, LeaderElectionID: electionID, + Scheme: scheme, } kubeConfig := clientConfig.GetConfigOrDie() coreKubeConfig := rest.CopyConfig(kubeConfig) - coreKubeConfig.ContentType = runtime.ContentTypeProtobuf + coreKubeConfig.ContentType = apiruntime.ContentTypeProtobuf mgr, err := manager.New(coreKubeConfig, opts) if err != nil { log.ErrorLogMsg("failed to create manager %s", err) diff --git a/internal/controller/volumegroup/volumegroupreplicationcontent.go b/internal/controller/volumegroup/volumegroupreplicationcontent.go new file mode 100644 index 00000000000..e0bc1be86d5 --- /dev/null +++ b/internal/controller/volumegroup/volumegroupreplicationcontent.go @@ -0,0 +1,200 @@ +/* +Copyright 2024 The Ceph-CSI 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 volumegroup + +import ( + "context" + "errors" + "fmt" + + replicationv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + + ctrl "github.com/ceph/ceph-csi/internal/controller" + "github.com/ceph/ceph-csi/internal/rbd" + "github.com/ceph/ceph-csi/internal/util" + "github.com/ceph/ceph-csi/internal/util/log" +) + +type ReconcileVGRContent struct { + client client.Client + config ctrl.Config + Locks *util.VolumeLocks +} + +var ( + _ reconcile.Reconciler = &ReconcileVGRContent{} + _ ctrl.Manager = &ReconcileVGRContent{} +) + +const ( + secretNameParameterName = "replication.storage.openshift.io/group-replication-secret-name" + secretNamespaceParameterName = "replication.storage.openshift.io/group-replication-secret-namespace" +) + +// Init will add the ReconcileVGRContent to the list. +func Init() { + // add ReconcileVGRContent to the list + ctrl.ControllerList = append(ctrl.ControllerList, &ReconcileVGRContent{}) +} + +// Add adds the newVGRContentReconciler. +func (r *ReconcileVGRContent) Add(mgr manager.Manager, config ctrl.Config) error { + return add(mgr, newVGRContentReconciler(mgr, config)) +} + +// newVGRContentReconciler returns a ReconcileVGRContent. +func newVGRContentReconciler(mgr manager.Manager, config ctrl.Config) reconcile.Reconciler { + r := &ReconcileVGRContent{ + client: mgr.GetClient(), + config: config, + Locks: util.NewVolumeLocks(), + } + + return r +} + +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New( + "vgrcontent-controller", + mgr, + controller.Options{MaxConcurrentReconciles: 1, Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to VolumeGroupReplicationContent + err = c.Watch(source.Kind( + mgr.GetCache(), + &replicationv1alpha1.VolumeGroupReplicationContent{}, + &handler.TypedEnqueueRequestForObject[*replicationv1alpha1.VolumeGroupReplicationContent]{}), + ) + if err != nil { + return fmt.Errorf("failed to watch the changes: %w", err) + } + + return nil +} + +func (r *ReconcileVGRContent) getSecrets( + ctx context.Context, + name, + namespace string, +) (map[string]string, error) { + if name == "" || namespace == "" { + return nil, errors.New("secret name or secret namespace is empty") + } + secret := &corev1.Secret{} + err := r.client.Get(ctx, types.NamespacedName{Name: name, Namespace: namespace}, secret) + if err != nil { + return nil, fmt.Errorf("error getting secret %s in namespace %s: %w", name, namespace, err) + } + + secrets := map[string]string{} + for key, value := range secret.Data { + secrets[key] = string(value) + } + + return secrets, nil +} + +func (r *ReconcileVGRContent) reconcileVGRContent(ctx context.Context, obj runtime.Object) error { + vgrc, ok := obj.(*replicationv1alpha1.VolumeGroupReplicationContent) + if !ok { + return nil + } + if vgrc.Spec.Provisioner != r.config.DriverName { + return nil + } + + reqName := vgrc.Name + groupHandle := vgrc.Spec.VolumeGroupReplicationHandle + volumeIds := vgrc.Spec.Source.VolumeHandles + + if groupHandle == "" { + return errors.New("volume group replication handle is empty") + } + + vgrClass := &replicationv1alpha1.VolumeGroupReplicationClass{} + err := r.client.Get(ctx, types.NamespacedName{Name: vgrc.Spec.VolumeGroupReplicationClassName}, vgrClass) + if err != nil { + return err + } + + if ok = r.Locks.TryAcquire(groupHandle); !ok { + return fmt.Errorf("failed to acquire lock for group handle %s", groupHandle) + } + defer r.Locks.Release(groupHandle) + + parameters := vgrClass.Spec.Parameters + secretName := vgrClass.Spec.Parameters[secretNameParameterName] + secretNamespace := vgrClass.Spec.Parameters[secretNamespaceParameterName] + + secrets, err := r.getSecrets(ctx, secretName, secretNamespace) + if err != nil { + return err + } + + mgr := rbd.NewManager(r.config.InstanceID, parameters, secrets) + defer mgr.Destroy(ctx) + + groupID, err := mgr.RegenerateVolumeGroupJournal(ctx, groupHandle, reqName, volumeIds) + if err != nil { + return err + } + if groupID != groupHandle { + log.DebugLog(ctx, "groupHandle changed from %s to %s", groupHandle, groupID) + } + + return nil +} + +// Reconcile reconciles the VolumeGroupReplicationContent object and creates a new omap entries +// for the volume group. +func (r *ReconcileVGRContent) Reconcile(ctx context.Context, + request reconcile.Request, +) (reconcile.Result, error) { + vgrc := &replicationv1alpha1.VolumeGroupReplicationContent{} + err := r.client.Get(ctx, request.NamespacedName, vgrc) + if err != nil { + if apierrors.IsNotFound(err) { + return reconcile.Result{}, nil + } + + return reconcile.Result{}, err + } + // Check if the object is under deletion + if !vgrc.GetDeletionTimestamp().IsZero() { + return reconcile.Result{}, nil + } + + err = r.reconcileVGRContent(ctx, vgrc) + if err != nil { + return reconcile.Result{}, err + } + + return reconcile.Result{}, nil +} diff --git a/internal/journal/volumegroupjournal.go b/internal/journal/volumegroupjournal.go index 99ad8dafd1b..80012c887b5 100644 --- a/internal/journal/volumegroupjournal.go +++ b/internal/journal/volumegroupjournal.go @@ -54,6 +54,7 @@ type VolumeGroupJournal interface { ctx context.Context, journalPool, reqName, + groupUUID, namePrefix string) (string, string, error) // AddVolumesMapping adds a volumeMap map which contains volumeID's and its // corresponding values mapping which need to be added to the UUID @@ -312,6 +313,7 @@ held, to prevent parallel operations from modifying the state of the omaps for t Input arguments: - journalPool: Pool where the CSI journal is stored - reqName: Name of the volumeGroupSnapshot request received + - groupUUID: UUID need to be reserved instead of auto-generating one (this is useful for RBD mirroring) - namePrefix: Prefix to use when generating the volumeGroupName name (suffix is an auto-generated UUID) Return values: @@ -320,7 +322,7 @@ Return values: - error: non-nil in case of any errors */ func (vgjc *volumeGroupJournalConnection) ReserveName(ctx context.Context, - journalPool, reqName, namePrefix string, + journalPool, reqName, groupUUID, namePrefix string, ) (string, string, error) { cj := vgjc.config @@ -335,7 +337,7 @@ func (vgjc *volumeGroupJournalConnection) ReserveName(ctx context.Context, journalPool, cj.namespace, cj.cephUUIDDirectoryPrefix, - "") + groupUUID) if err != nil { return "", "", err } diff --git a/internal/rbd/manager.go b/internal/rbd/manager.go index 8b0d6a06448..c6bfc145621 100644 --- a/internal/rbd/manager.go +++ b/internal/rbd/manager.go @@ -144,7 +144,7 @@ func (mgr *rbdManager) getGroupUUID( } else { log.DebugLog(ctx, "the journal does not contain a reservation for group %q yet", name) - uuid, _ /*vgsName*/, err = vgJournal.ReserveName(ctx, journalPool, name, prefix) + uuid, _ /*vgsName*/, err = vgJournal.ReserveName(ctx, journalPool, name, vgsData.GroupUUID, prefix) if err != nil { return "", nothingToUndo, fmt.Errorf("failed to reserve a UUID for group %q: %w", name, err) } @@ -273,7 +273,7 @@ func (mgr *rbdManager) CreateVolumeGroup(ctx context.Context, name string) (type log.DebugLog(ctx, "the journal does not contain a reservation for a volume group with name %q yet", name) var vgName string - uuid, vgName, err = vgJournal.ReserveName(ctx, journalPool, name, prefix) + uuid, vgName, err = vgJournal.ReserveName(ctx, journalPool, name, vgData.GroupUUID, prefix) if err != nil { return nil, fmt.Errorf("failed to reserve volume group for name %q: %w", name, err) } @@ -503,3 +503,134 @@ func (mgr *rbdManager) CreateVolumeGroupSnapshot( return vgs, nil } + +// RegenerateVolumeGroupJournal regenerate the omap data for the volume group. +// This performs the following operations: +// - extracts clusterID and Mons from the cluster mapping +// - Retrieves pool and journalPool parameters from the VolumeGroupReplicationClass +// - Reserves omap data +// - Add volumeIDs mapping to the reserved volume group omap object +// - Generate new volume group handle +// +// Returns the generated volume group handle. +// +// Note: The new volume group handle will differ from the original as it includes +// poolID and clusterID, which vary between clusters. +func (mgr *rbdManager) RegenerateVolumeGroupJournal( + ctx context.Context, + groupID, requestName string, + volumeIds []string, +) (string, error) { + var ( + clusterID string + monitors string + pool string + journalPool string + namePrefix string + groupUUID string + vgName string + + gi util.CSIIdentifier + ok bool + err error + ) + + err = gi.DecomposeCSIID(groupID) + if err != nil { + return "", fmt.Errorf("%w: error decoding volume group ID (%w) (%s)", ErrInvalidVolID, err, groupID) + } + + monitors, clusterID, err = util.FetchMappedClusterIDAndMons(ctx, gi.ClusterID) + if err != nil { + return "", err + } + + pool, ok = mgr.parameters["pool"] + if !ok { + return "", errors.New("required 'pool' parameter missing in parameters") + } + + journalPool = mgr.parameters["journalPool"] + if journalPool == "" { + journalPool = pool + } + + vgJournal, err := mgr.getVolumeGroupJournal(clusterID) + if err != nil { + return "", err + } + defer vgJournal.Destroy() + + namePrefix = mgr.parameters["volumeNamePrefix"] + vgData, err := vgJournal.CheckReservation(ctx, journalPool, requestName, namePrefix) + if err != nil { + return "", err + } + + if vgData != nil { + groupUUID = vgData.GroupUUID + vgName = vgData.GroupName + } else { + log.DebugLog(ctx, "the journal does not contain a reservation for a volume group with name %q yet", requestName) + groupUUID, vgName, err = vgJournal.ReserveName(ctx, journalPool, requestName, gi.ObjectUUID, namePrefix) + if err != nil { + return "", fmt.Errorf("failed to reserve volume group for name %q: %w", requestName, err) + } + defer func() { + if err != nil { + err = vgJournal.UndoReservation(ctx, journalPool, vgName, requestName) + if err != nil { + log.ErrorLog(ctx, "failed to undo the reservation for volume group %q: %w", requestName, err) + } + } + }() + } + + volumes := make([]types.Volume, len(volumeIds)) + defer func() { + for _, v := range volumes { + v.Destroy(ctx) + } + }() + var volume types.Volume + for i, id := range volumeIds { + volume, err = mgr.GetVolumeByID(ctx, id) + if err != nil { + return "", fmt.Errorf("failed to find required volume %q for volume group id %q: %w", id, vgName, err) + } + + volumes[i] = volume + } + + var volID string + for _, vol := range volumes { + volID, err = vol.GetID(ctx) + if err != nil { + return "", fmt.Errorf("failed to get VolumeID for %q: %w", vol, err) + } + + toAdd := map[string]string{ + volID: "", + } + log.DebugLog(ctx, "adding volume mapping for volume %q to volume group %q", volID, vgName) + err = mgr.vgJournal.AddVolumesMapping(ctx, pool, gi.ObjectUUID, toAdd) + if err != nil { + return "", fmt.Errorf("failed to add mapping for volume %q to volume group %q: %w", volID, vgName, err) + } + } + + _, poolID, err := util.GetPoolIDs(ctx, monitors, journalPool, pool, mgr.creds) + if err != nil { + return "", fmt.Errorf("failed to get poolID for %q: %w", groupUUID, err) + } + + groupHandle, err := util.GenerateVolID(ctx, monitors, mgr.creds, poolID, pool, clusterID, groupUUID) + if err != nil { + return "", fmt.Errorf("failed to generate a unique CSI volume group with uuid for %q: %w", groupUUID, err) + } + + log.DebugLog(ctx, "re-generated Group ID (%s) and Group Name (%s) for request name (%s)", + groupHandle, vgName, requestName) + + return groupHandle, nil +} diff --git a/internal/rbd/types/manager.go b/internal/rbd/types/manager.go index 273bd58109f..458bc93dc0d 100644 --- a/internal/rbd/types/manager.go +++ b/internal/rbd/types/manager.go @@ -67,4 +67,8 @@ type Manager interface { // VolumeGroup was paused, the snapshots in the group are crash // consistent. CreateVolumeGroupSnapshot(ctx context.Context, vg VolumeGroup, name string) (VolumeGroupSnapshot, error) + + // RegenerateVolumeGroupJournal regenerate the omap data for the volume group. + // returns the volume group handle + RegenerateVolumeGroupJournal(ctx context.Context, groupID, requestName string, volumeIds []string) (string, error) } diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/LICENSE b/vendor/github.com/csi-addons/kubernetes-csi-addons/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/groupversion_info.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/groupversion_info.go new file mode 100644 index 00000000000..37182b68daf --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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 v1alpha1 contains API Schema definitions for the replication.storage v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=replication.storage.openshift.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "replication.storage.openshift.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplication_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplication_types.go new file mode 100644 index 00000000000..8ad2bff704f --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplication_types.go @@ -0,0 +1,105 @@ +/* +Copyright 2024 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VolumeGroupReplicationSpec defines the desired state of VolumeGroupReplication +type VolumeGroupReplicationSpec struct { + // volumeGroupReplicationClassName is the volumeGroupReplicationClass name for this VolumeGroupReplication resource + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeGroupReplicationClassName is immutable" + VolumeGroupReplicationClassName string `json:"volumeGroupReplicationClassName"` + + // volumeReplicationClassName is the volumeReplicationClass name for VolumeReplication object + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumReplicationClassName is immutable" + VolumeReplicationClassName string `json:"volumeReplicationClassName"` + + // Name of the VolumeReplication object created for this volumeGroupReplication + // +kubebuilder:validation:Optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeReplicationName is immutable" + VolumeReplicationName string `json:"volumeReplicationName,omitempty"` + + // Name of the VolumeGroupReplicationContent object created for this volumeGroupReplication + // +kubebuilder:validation:Optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeGroupReplicationContentName is immutable" + VolumeGroupReplicationContentName string `json:"volumeGroupReplicationContentName,omitempty"` + + // Source specifies where a group replications will be created from. + // This field is immutable after creation. + // Required. + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="source is immutable" + Source VolumeGroupReplicationSource `json:"source"` + + // ReplicationState represents the replication operation to be performed on the group. + // Supported operations are "primary", "secondary" and "resync" + // +kubebuilder:validation:Required + ReplicationState ReplicationState `json:"replicationState"` + + // AutoResync represents the group to be auto resynced when + // ReplicationState is "secondary" + // +kubebuilder:default:=false + AutoResync bool `json:"autoResync"` +} + +// VolumeGroupReplicationSource specifies the source for the the volumeGroupReplication +type VolumeGroupReplicationSource struct { + // Selector is a label query over persistent volume claims that are to be + // grouped together for replication. + // +optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="selector is immutable" + Selector *metav1.LabelSelector `json:"selector,omitempty"` +} + +// VolumeGroupReplicationStatus defines the observed state of VolumeGroupReplication +type VolumeGroupReplicationStatus struct { + VolumeReplicationStatus `json:",inline"` + // PersistentVolumeClaimsRefList is the list of PVCs for the volume group replication. + // The maximum number of allowed PVCs in the group is 100. + // +optional + PersistentVolumeClaimsRefList []corev1.LocalObjectReference `json:"persistentVolumeClaimsRefList,omitempty"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// VolumeGroupReplication is the Schema for the volumegroupreplications API +type VolumeGroupReplication struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec VolumeGroupReplicationSpec `json:"spec,omitempty"` + Status VolumeGroupReplicationStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// VolumeGroupReplicationList contains a list of VolumeGroupReplication +type VolumeGroupReplicationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeGroupReplication `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeGroupReplication{}, &VolumeGroupReplicationList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationclass_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationclass_types.go new file mode 100644 index 00000000000..972bcd1ba4b --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationclass_types.go @@ -0,0 +1,67 @@ +/* +Copyright 2024 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VolumeGroupReplicationClassSpec specifies parameters that an underlying storage system uses +// when creating a volumegroup replica. A specific VolumeGroupReplicationClass is used by specifying +// its name in a VolumeGroupReplication object. +// +kubebuilder:validation:XValidation:rule="has(self.parameters) == has(oldSelf.parameters)",message="parameters are immutable" +type VolumeGroupReplicationClassSpec struct { + // Provisioner is the name of storage provisioner + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="provisioner is immutable" + Provisioner string `json:"provisioner"` + // Parameters is a key-value map with storage provisioner specific configurations for + // creating volume group replicas + // +kubebuilder:validation:Optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="parameters are immutable" + Parameters map[string]string `json:"parameters,omitempty"` +} + +// VolumeGroupReplicationClassStatus defines the observed state of VolumeGroupReplicationClass +type VolumeGroupReplicationClassStatus struct { +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:scope=Cluster + +// VolumeGroupReplicationClass is the Schema for the volumegroupreplicationclasses API +type VolumeGroupReplicationClass struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec VolumeGroupReplicationClassSpec `json:"spec,omitempty"` + Status VolumeGroupReplicationClassStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// VolumeGroupReplicationClassList contains a list of VolumeGroupReplicationClass +type VolumeGroupReplicationClassList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeGroupReplicationClass `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeGroupReplicationClass{}, &VolumeGroupReplicationClassList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationcontent_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationcontent_types.go new file mode 100644 index 00000000000..fcbb7a95a88 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationcontent_types.go @@ -0,0 +1,101 @@ +/* +Copyright 2024 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VolumeGroupReplicationContentSpec defines the desired state of VolumeGroupReplicationContent +type VolumeGroupReplicationContentSpec struct { + // VolumeGroupreplicationRef specifies the VolumeGroupReplication object to which this + // VolumeGroupReplicationContent object is bound. + // VolumeGroupReplication.Spec.VolumeGroupReplicationContentName field must reference to + // this VolumeGroupReplicationContent's name for the bidirectional binding to be valid. + // For a pre-existing VolumeGroupReplicationContent object, name and namespace of the + // VolumeGroupReplication object MUST be provided for binding to happen. + // This field is immutable after creation. + // Required. + // +kubebuilder:validation:XValidation:rule="has(self.name) && has(self.__namespace__)",message="both volumeGroupReplicationRef.name and volumeGroupReplicationRef.namespace must be set" + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeGroupReplicationRef is immutable" + VolumeGroupReplicationRef corev1.ObjectReference `json:"volumeGroupReplicationRef"` + + // VolumeGroupReplicationHandle is a unique id returned by the CSI driver + // to identify the VolumeGroupReplication on the storage system. + VolumeGroupReplicationHandle string `json:"volumeGroupReplicationHandle"` + + // provisioner is the name of the CSI driver used to create the physical + // volume group on + // the underlying storage system. + // This MUST be the same as the name returned by the CSI GetPluginName() call for + // that driver. + // Required. + Provisioner string `json:"provisioner"` + + // VolumeGroupReplicationClassName is the name of the VolumeGroupReplicationClass from + // which this group replication was (or will be) created. + // +optional + VolumeGroupReplicationClassName string `json:"volumeGroupReplicationClassName"` + + // Source specifies whether the snapshot is (or should be) dynamically provisioned + // or already exists, and just requires a Kubernetes object representation. + // This field is immutable after creation. + // Required. + Source VolumeGroupReplicationContentSource `json:"source"` +} + +// VolumeGroupReplicationContentSource represents the CSI source of a group replication. +type VolumeGroupReplicationContentSource struct { + // VolumeHandles is a list of volume handles on the backend to be grouped + // and replicated. + VolumeHandles []string `json:"volumeHandles"` +} + +// VolumeGroupReplicationContentStatus defines the status of VolumeGroupReplicationContent +type VolumeGroupReplicationContentStatus struct { + // PersistentVolumeRefList is the list of of PV for the group replication + // The maximum number of allowed PV in the group is 100. + // +optional + PersistentVolumeRefList []corev1.LocalObjectReference `json:"persistentVolumeRefList,omitempty"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:scope=Cluster + +// VolumeGroupReplicationContent is the Schema for the volumegroupreplicationcontents API +type VolumeGroupReplicationContent struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec VolumeGroupReplicationContentSpec `json:"spec,omitempty"` + Status VolumeGroupReplicationContentStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// VolumeGroupReplicationContentList contains a list of VolumeGroupReplicationContent +type VolumeGroupReplicationContentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeGroupReplicationContent `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeGroupReplicationContent{}, &VolumeGroupReplicationContentList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplication_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplication_types.go new file mode 100644 index 00000000000..d9fca40ad99 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplication_types.go @@ -0,0 +1,131 @@ +/* +Copyright 2022 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + VolumeReplicationNameAnnotation = "replication.storage.openshift.io/volume-replication-name" +) + +// ReplicationState represents the replication operations to be performed on the volume. +// +kubebuilder:validation:Enum=primary;secondary;resync +type ReplicationState string + +const ( + // Primary ReplicationState enables mirroring and promotes the volume to primary. + Primary ReplicationState = "primary" + + // Secondary ReplicationState demotes the volume to secondary and resyncs the volume if out of sync. + Secondary ReplicationState = "secondary" + + // Resync option resyncs the volume. + Resync ReplicationState = "resync" +) + +// State captures the latest state of the replication operation. +type State string + +const ( + // PrimaryState represents the Primary replication state. + PrimaryState State = "Primary" + + // SecondaryState represents the Secondary replication state. + SecondaryState State = "Secondary" + + // UnknownState represents the Unknown replication state. + UnknownState State = "Unknown" +) + +// VolumeReplicationSpec defines the desired state of VolumeReplication. +type VolumeReplicationSpec struct { + // VolumeReplicationClass is the VolumeReplicationClass name for this VolumeReplication resource + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeReplicationClass is immutable" + VolumeReplicationClass string `json:"volumeReplicationClass"` + + // ReplicationState represents the replication operation to be performed on the volume. + // Supported operations are "primary", "secondary" and "resync" + // +kubebuilder:validation:Required + ReplicationState ReplicationState `json:"replicationState"` + + // DataSource represents the object associated with the volume + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="dataSource is immutable" + DataSource corev1.TypedLocalObjectReference `json:"dataSource"` + + // AutoResync represents the volume to be auto resynced when + // ReplicationState is "secondary" + // +kubebuilder:default:=false + AutoResync bool `json:"autoResync"` + + // replicationHandle represents an existing (but new) replication id + // +kubebuilder:validation:Optional + ReplicationHandle string `json:"replicationHandle"` +} + +// VolumeReplicationStatus defines the observed state of VolumeReplication. +type VolumeReplicationStatus struct { + State State `json:"state,omitempty"` + Message string `json:"message,omitempty"` + // Conditions are the list of conditions and their status. + Conditions []metav1.Condition `json:"conditions,omitempty"` + // observedGeneration is the last generation change the operator has dealt with + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + LastStartTime *metav1.Time `json:"lastStartTime,omitempty"` + LastCompletionTime *metav1.Time `json:"lastCompletionTime,omitempty"` + LastSyncTime *metav1.Time `json:"lastSyncTime,omitempty"` + LastSyncBytes *int64 `json:"lastSyncBytes,omitempty"` + LastSyncDuration *metav1.Duration `json:"lastSyncDuration,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:JSONPath=".metadata.creationTimestamp",name=Age,type=date +// +kubebuilder:printcolumn:JSONPath=".spec.volumeReplicationClass",name=volumeReplicationClass,type=string +// +kubebuilder:printcolumn:JSONPath=".spec.dataSource.name",name=pvcName,type=string +// +kubebuilder:printcolumn:JSONPath=".spec.replicationState",name=desiredState,type=string +// +kubebuilder:printcolumn:JSONPath=".status.state",name=currentState,type=string +// +kubebuilder:resource:shortName=vr + +// VolumeReplication is the Schema for the volumereplications API. +type VolumeReplication struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +kubebuilder:validation:Required + Spec VolumeReplicationSpec `json:"spec"` + + Status VolumeReplicationStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// VolumeReplicationList contains a list of VolumeReplication. +type VolumeReplicationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeReplication `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeReplication{}, &VolumeReplicationList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplicationclass_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplicationclass_types.go new file mode 100644 index 00000000000..25632a04948 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplicationclass_types.go @@ -0,0 +1,69 @@ +/* +Copyright 2022 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VolumeReplicationClassSpec specifies parameters that an underlying storage system uses +// when creating a volume replica. A specific VolumeReplicationClass is used by specifying +// its name in a VolumeReplication object. +// +kubebuilder:validation:XValidation:rule="has(self.parameters) == has(oldSelf.parameters)",message="parameters are immutable" +type VolumeReplicationClassSpec struct { + // Provisioner is the name of storage provisioner + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="provisioner is immutable" + Provisioner string `json:"provisioner"` + // Parameters is a key-value map with storage provisioner specific configurations for + // creating volume replicas + // +kubebuilder:validation:Optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="parameters are immutable" + Parameters map[string]string `json:"parameters,omitempty"` +} + +// VolumeReplicationClassStatus defines the observed state of VolumeReplicationClass. +type VolumeReplicationClassStatus struct{} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster,shortName=vrc +// +kubebuilder:printcolumn:JSONPath=".spec.provisioner",name=provisioner,type=string + +// VolumeReplicationClass is the Schema for the volumereplicationclasses API. +type VolumeReplicationClass struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +kubebuilder:validation:Required + Spec VolumeReplicationClassSpec `json:"spec"` + + Status VolumeReplicationClassStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// VolumeReplicationClassList contains a list of VolumeReplicationClass. +type VolumeReplicationClassList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeReplicationClass `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeReplicationClass{}, &VolumeReplicationClassList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..dcfe62b4615 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,570 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2022 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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplication) DeepCopyInto(out *VolumeGroupReplication) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplication. +func (in *VolumeGroupReplication) DeepCopy() *VolumeGroupReplication { + if in == nil { + return nil + } + out := new(VolumeGroupReplication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplication) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationClass) DeepCopyInto(out *VolumeGroupReplicationClass) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationClass. +func (in *VolumeGroupReplicationClass) DeepCopy() *VolumeGroupReplicationClass { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationClass) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationClass) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationClassList) DeepCopyInto(out *VolumeGroupReplicationClassList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeGroupReplicationClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationClassList. +func (in *VolumeGroupReplicationClassList) DeepCopy() *VolumeGroupReplicationClassList { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationClassList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationClassList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationClassSpec) DeepCopyInto(out *VolumeGroupReplicationClassSpec) { + *out = *in + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationClassSpec. +func (in *VolumeGroupReplicationClassSpec) DeepCopy() *VolumeGroupReplicationClassSpec { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationClassSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationClassStatus) DeepCopyInto(out *VolumeGroupReplicationClassStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationClassStatus. +func (in *VolumeGroupReplicationClassStatus) DeepCopy() *VolumeGroupReplicationClassStatus { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationClassStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationContent) DeepCopyInto(out *VolumeGroupReplicationContent) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContent. +func (in *VolumeGroupReplicationContent) DeepCopy() *VolumeGroupReplicationContent { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationContent) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationContentList) DeepCopyInto(out *VolumeGroupReplicationContentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeGroupReplicationContent, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContentList. +func (in *VolumeGroupReplicationContentList) DeepCopy() *VolumeGroupReplicationContentList { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationContentList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationContentSource) DeepCopyInto(out *VolumeGroupReplicationContentSource) { + *out = *in + if in.VolumeHandles != nil { + in, out := &in.VolumeHandles, &out.VolumeHandles + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContentSource. +func (in *VolumeGroupReplicationContentSource) DeepCopy() *VolumeGroupReplicationContentSource { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContentSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationContentSpec) DeepCopyInto(out *VolumeGroupReplicationContentSpec) { + *out = *in + out.VolumeGroupReplicationRef = in.VolumeGroupReplicationRef + in.Source.DeepCopyInto(&out.Source) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContentSpec. +func (in *VolumeGroupReplicationContentSpec) DeepCopy() *VolumeGroupReplicationContentSpec { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationContentStatus) DeepCopyInto(out *VolumeGroupReplicationContentStatus) { + *out = *in + if in.PersistentVolumeRefList != nil { + in, out := &in.PersistentVolumeRefList, &out.PersistentVolumeRefList + *out = make([]corev1.LocalObjectReference, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContentStatus. +func (in *VolumeGroupReplicationContentStatus) DeepCopy() *VolumeGroupReplicationContentStatus { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationList) DeepCopyInto(out *VolumeGroupReplicationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeGroupReplication, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationList. +func (in *VolumeGroupReplicationList) DeepCopy() *VolumeGroupReplicationList { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationSource) DeepCopyInto(out *VolumeGroupReplicationSource) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationSource. +func (in *VolumeGroupReplicationSource) DeepCopy() *VolumeGroupReplicationSource { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationSpec) DeepCopyInto(out *VolumeGroupReplicationSpec) { + *out = *in + in.Source.DeepCopyInto(&out.Source) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationSpec. +func (in *VolumeGroupReplicationSpec) DeepCopy() *VolumeGroupReplicationSpec { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationStatus) DeepCopyInto(out *VolumeGroupReplicationStatus) { + *out = *in + in.VolumeReplicationStatus.DeepCopyInto(&out.VolumeReplicationStatus) + if in.PersistentVolumeClaimsRefList != nil { + in, out := &in.PersistentVolumeClaimsRefList, &out.PersistentVolumeClaimsRefList + *out = make([]corev1.LocalObjectReference, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationStatus. +func (in *VolumeGroupReplicationStatus) DeepCopy() *VolumeGroupReplicationStatus { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplication) DeepCopyInto(out *VolumeReplication) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplication. +func (in *VolumeReplication) DeepCopy() *VolumeReplication { + if in == nil { + return nil + } + out := new(VolumeReplication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeReplication) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationClass) DeepCopyInto(out *VolumeReplicationClass) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationClass. +func (in *VolumeReplicationClass) DeepCopy() *VolumeReplicationClass { + if in == nil { + return nil + } + out := new(VolumeReplicationClass) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeReplicationClass) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationClassList) DeepCopyInto(out *VolumeReplicationClassList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeReplicationClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationClassList. +func (in *VolumeReplicationClassList) DeepCopy() *VolumeReplicationClassList { + if in == nil { + return nil + } + out := new(VolumeReplicationClassList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeReplicationClassList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationClassSpec) DeepCopyInto(out *VolumeReplicationClassSpec) { + *out = *in + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationClassSpec. +func (in *VolumeReplicationClassSpec) DeepCopy() *VolumeReplicationClassSpec { + if in == nil { + return nil + } + out := new(VolumeReplicationClassSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationClassStatus) DeepCopyInto(out *VolumeReplicationClassStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationClassStatus. +func (in *VolumeReplicationClassStatus) DeepCopy() *VolumeReplicationClassStatus { + if in == nil { + return nil + } + out := new(VolumeReplicationClassStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationList) DeepCopyInto(out *VolumeReplicationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeReplication, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationList. +func (in *VolumeReplicationList) DeepCopy() *VolumeReplicationList { + if in == nil { + return nil + } + out := new(VolumeReplicationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeReplicationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationSpec) DeepCopyInto(out *VolumeReplicationSpec) { + *out = *in + in.DataSource.DeepCopyInto(&out.DataSource) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationSpec. +func (in *VolumeReplicationSpec) DeepCopy() *VolumeReplicationSpec { + if in == nil { + return nil + } + out := new(VolumeReplicationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationStatus) DeepCopyInto(out *VolumeReplicationStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LastStartTime != nil { + in, out := &in.LastStartTime, &out.LastStartTime + *out = (*in).DeepCopy() + } + if in.LastCompletionTime != nil { + in, out := &in.LastCompletionTime, &out.LastCompletionTime + *out = (*in).DeepCopy() + } + if in.LastSyncTime != nil { + in, out := &in.LastSyncTime, &out.LastSyncTime + *out = (*in).DeepCopy() + } + if in.LastSyncBytes != nil { + in, out := &in.LastSyncBytes, &out.LastSyncBytes + *out = new(int64) + **out = **in + } + if in.LastSyncDuration != nil { + in, out := &in.LastSyncDuration, &out.LastSyncDuration + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationStatus. +func (in *VolumeReplicationStatus) DeepCopy() *VolumeReplicationStatus { + if in == nil { + return nil + } + out := new(VolumeReplicationStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/go.uber.org/zap/.golangci.yml b/vendor/go.uber.org/zap/.golangci.yml index fbc6df79065..2346df13517 100644 --- a/vendor/go.uber.org/zap/.golangci.yml +++ b/vendor/go.uber.org/zap/.golangci.yml @@ -17,7 +17,7 @@ linters: - unused # Our own extras: - - gofmt + - gofumpt - nolintlint # lints nolint directives - revive diff --git a/vendor/go.uber.org/zap/.readme.tmpl b/vendor/go.uber.org/zap/.readme.tmpl index 92aa65d660b..4fea3027af3 100644 --- a/vendor/go.uber.org/zap/.readme.tmpl +++ b/vendor/go.uber.org/zap/.readme.tmpl @@ -1,7 +1,15 @@ # :zap: zap [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] +