Skip to content

Commit 10c81ce

Browse files
Merge pull request #276 from rewantsoni/vrcs
controllers: create vrc sent by the provider
2 parents 7190d9f + 9cd543b commit 10c81ce

29 files changed

+1539
-1963
lines changed

bundle/manifests/ocs-client-operator.clusterserviceversion.yaml

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ metadata:
77
categories: Storage
88
console.openshift.io/plugins: '["odf-client-console"]'
99
containerImage: quay.io/ocs-dev/ocs-client-operator:latest
10-
createdAt: "2024-11-18T12:48:54Z"
10+
createdAt: "2024-11-22T04:24:54Z"
1111
description: OpenShift Data Foundation client operator enables consumption of
1212
storage services from a remote centralized OpenShift Data Foundation provider
1313
cluster.
@@ -316,15 +316,14 @@ spec:
316316
- update
317317
- watch
318318
- apiGroups:
319-
- ramendr.openshift.io
319+
- replication.storage.openshift.io
320320
resources:
321-
- drclusterconfigs
321+
- volumereplicationclass
322322
verbs:
323323
- create
324324
- delete
325325
- get
326326
- list
327-
- update
328327
- watch
329328
- apiGroups:
330329
- security.openshift.io

cmd/main.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
3232
// to ensure that exec-entrypoint and run can make use of them.
3333
csiopv1a1 "github.com/ceph/ceph-csi-operator/api/v1alpha1"
34+
replicationv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1"
3435
snapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
3536
nbapis "github.com/noobaa/noobaa-operator/v5/pkg/apis"
3637
configv1 "github.com/openshift/api/config/v1"
@@ -80,6 +81,7 @@ func init() {
8081
utilruntime.Must(csiopv1a1.AddToScheme(scheme))
8182
utilruntime.Must(nbapis.AddToScheme(scheme))
8283
utilruntime.Must(ramenv1alpha1.AddToScheme(scheme))
84+
utilruntime.Must(replicationv1alpha1.AddToScheme(scheme))
8385
//+kubebuilder:scaffold:scheme
8486
}
8587

@@ -152,7 +154,7 @@ func main() {
152154
os.Exit(1)
153155
}
154156

155-
availCrds, err := getAvailableCRDNames(context.Background(), apiClient)
157+
_, err = getAvailableCRDNames(context.Background(), apiClient)
156158
if err != nil {
157159
setupLog.Error(err, "Unable get a list of available CRD names")
158160
os.Exit(1)
@@ -183,7 +185,6 @@ func main() {
183185
Client: mgr.GetClient(),
184186
Scheme: mgr.GetScheme(),
185187
OperatorNamespace: utils.GetOperatorNamespace(),
186-
AvailableCrds: availCrds,
187188
}).SetupWithManager(mgr); err != nil {
188189
setupLog.Error(err, "unable to create controller", "controller", "StorageClaim")
189190
os.Exit(1)

config/rbac/role.yaml

+2-3
Original file line numberDiff line numberDiff line change
@@ -273,15 +273,14 @@ rules:
273273
- update
274274
- watch
275275
- apiGroups:
276-
- ramendr.openshift.io
276+
- replication.storage.openshift.io
277277
resources:
278-
- drclusterconfigs
278+
- volumereplicationclass
279279
verbs:
280280
- create
281281
- delete
282282
- get
283283
- list
284-
- update
285284
- watch
286285
- apiGroups:
287286
- security.openshift.io

go.mod

+5-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ exclude (
1919

2020
require (
2121
github.com/ceph/ceph-csi-operator/api v0.0.0-20241114115439-f325f74205d3
22+
github.com/csi-addons/kubernetes-csi-addons v0.10.0
2223
github.com/go-logr/logr v1.4.2
2324
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.0.0
2425
github.com/onsi/ginkgo v1.16.5
25-
github.com/onsi/gomega v1.34.1
26+
github.com/onsi/gomega v1.34.2
2627
github.com/openshift/api v0.0.0-20240828125535-01b3675ba7b3
2728
github.com/operator-framework/api v0.27.0
2829
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.76.0
@@ -31,10 +32,10 @@ require (
3132
github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20241120160011-2e7cf0127dd4
3233
github.com/stretchr/testify v1.9.0
3334
google.golang.org/grpc v1.68.0
34-
k8s.io/api v0.31.0
35+
k8s.io/api v0.31.1
3536
k8s.io/apiextensions-apiserver v0.31.0
36-
k8s.io/apimachinery v0.31.0
37-
k8s.io/client-go v0.31.0
37+
k8s.io/apimachinery v0.31.1
38+
k8s.io/client-go v0.31.1
3839
k8s.io/klog/v2 v2.130.1
3940
k8s.io/utils v0.0.0-20240821151609-f90d01438635
4041
sigs.k8s.io/controller-runtime v0.19.0

go.sum

+14-12
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
6666
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
6767
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
6868
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
69+
github.com/csi-addons/kubernetes-csi-addons v0.10.0 h1:bBc6nb1oROz4RLhqoLFNeGymk2jIRXcx7LvAup9+3Jg=
70+
github.com/csi-addons/kubernetes-csi-addons v0.10.0/go.mod h1:nqi369YuYMIdysBbHjtYJcWFpcxujPot1HS6tnNWBV4=
6971
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7072
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7173
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -207,8 +209,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe
207209
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
208210
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
209211
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
210-
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
211-
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
212+
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
213+
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
212214
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
213215
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
214216
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -291,15 +293,15 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv
291293
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
292294
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
293295
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
294-
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
295-
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
296+
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
297+
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
296298
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
297299
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
298300
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
299301
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
300302
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
301-
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
302-
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
303+
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
304+
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
303305
github.com/openshift/api v0.0.0-20240828125535-01b3675ba7b3 h1:Igew1pwW1pAiBQj0KP7Ms0SaPr8neAvbUhjBuTtJsSo=
304306
github.com/openshift/api v0.0.0-20240828125535-01b3675ba7b3/go.mod h1:OOh6Qopf21pSzqNVCB5gomomBXb8o5sGKZxG2KNpaXM=
305307
github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87 h1:cHyxR+Y8rAMT6m1jQCaYGRwikqahI0OjjUDhFNf3ySQ=
@@ -765,17 +767,17 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
765767
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
766768
k8s.io/api v0.23.3/go.mod h1:w258XdGyvCmnBj/vGzQMj6kzdufJZVUwEM1U2fRJwSQ=
767769
k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8=
768-
k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo=
769-
k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE=
770+
k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU=
771+
k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
770772
k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk=
771773
k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk=
772774
k8s.io/apimachinery v0.23.3/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
773775
k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
774-
k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc=
775-
k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
776+
k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
777+
k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
776778
k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4=
777-
k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8=
778-
k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU=
779+
k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
780+
k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
779781
k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
780782
k8s.io/code-generator v0.23.3/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk=
781783
k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs=

internal/controller/storageclaim_controller.go

+30-31
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ import (
3131
csiopv1a1 "github.com/ceph/ceph-csi-operator/api/v1alpha1"
3232
"github.com/go-logr/logr"
3333

34+
replicationv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1"
3435
snapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
35-
ramenv1alpha1 "github.com/ramendr/ramen/api/v1alpha1"
3636
providerclient "github.com/red-hat-storage/ocs-operator/services/provider/api/v4/client"
3737
corev1 "k8s.io/api/core/v1"
3838
storagev1 "k8s.io/api/storage/v1"
39-
extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
4039
"k8s.io/apimachinery/pkg/api/errors"
4140
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4241
"k8s.io/apimachinery/pkg/runtime"
@@ -45,7 +44,6 @@ import (
4544
"sigs.k8s.io/controller-runtime/pkg/cache"
4645
"sigs.k8s.io/controller-runtime/pkg/client"
4746
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
48-
"sigs.k8s.io/controller-runtime/pkg/handler"
4947
ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
5048
"sigs.k8s.io/controller-runtime/pkg/predicate"
5149
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -56,9 +54,8 @@ const (
5654
storageClaimAnnotation = "ocs.openshift.io/storageclaim"
5755
keyRotationAnnotation = "keyrotation.csiaddons.openshift.io/schedule"
5856

59-
pvClusterIDIndexName = "index:persistentVolumeClusterID"
60-
vscClusterIDIndexName = "index:volumeSnapshotContentCSIDriver"
61-
drClusterConfigCRDName = "drclusterconfigs.ramendr.openshift.io"
57+
pvClusterIDIndexName = "index:persistentVolumeClusterID"
58+
vscClusterIDIndexName = "index:volumeSnapshotContentCSIDriver"
6259
)
6360

6461
// StorageClaimReconciler reconciles a StorageClaim object
@@ -67,7 +64,6 @@ type StorageClaimReconciler struct {
6764
cache.Cache
6865
Scheme *runtime.Scheme
6966
OperatorNamespace string
70-
AvailableCrds map[string]bool
7167

7268
log logr.Logger
7369
ctx context.Context
@@ -115,20 +111,8 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
115111
For(&v1alpha1.StorageClaim{}, builder.WithPredicates(generationChangePredicate)).
116112
Owns(&storagev1.StorageClass{}).
117113
Owns(&snapapi.VolumeSnapshotClass{}).
118-
Owns(&csiopv1a1.ClientProfile{}, builder.WithPredicates(generationChangePredicate)).
119-
Watches(
120-
&extv1.CustomResourceDefinition{},
121-
&handler.EnqueueRequestForObject{},
122-
builder.WithPredicates(
123-
utils.NamePredicate(drClusterConfigCRDName),
124-
utils.CrdCreateAndDeletePredicate(&r.log, drClusterConfigCRDName, r.AvailableCrds[drClusterConfigCRDName]),
125-
),
126-
builder.OnlyMetadata,
127-
)
128-
129-
if r.AvailableCrds[drClusterConfigCRDName] {
130-
bldr = bldr.Owns(&ramenv1alpha1.DRClusterConfig{}, builder.WithPredicates(generationChangePredicate))
131-
}
114+
Owns(&replicationv1alpha1.VolumeReplicationClass{}, builder.WithPredicates(generationChangePredicate)).
115+
Owns(&csiopv1a1.ClientProfile{}, builder.WithPredicates(generationChangePredicate))
132116

133117
return bldr.Complete(r)
134118
}
@@ -142,7 +126,7 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
142126
//+kubebuilder:rbac:groups=core,resources=persistentvolumes,verbs=get;list;watch
143127
//+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotcontents,verbs=get;list;watch
144128
//+kubebuilder:rbac:groups=csi.ceph.io,resources=clientprofiles,verbs=get;list;update;create;watch;delete
145-
//+kubebuilder:rbac:groups=ramendr.openshift.io,resources=drclusterconfigs,verbs=get;list;update;create;watch;delete
129+
//+kubebuilder:rbac:groups=replication.storage.openshift.io,resources=volumereplicationclass,verbs=get;list;watch;create;delete
146130

147131
// Reconcile is part of the main kubernetes reconciliation loop which aims to
148132
// move the current state of the cluster closer to the desired state.
@@ -159,15 +143,6 @@ func (r *StorageClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request
159143
r.ctx = ctrllog.IntoContext(ctx, r.log)
160144
r.log.Info("Reconciling StorageClaim.")
161145

162-
crd := &metav1.PartialObjectMetadata{}
163-
crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
164-
crd.Name = drClusterConfigCRDName
165-
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
166-
r.log.Error(err, "Failed to get CRD", "CRD", drClusterConfigCRDName)
167-
return reconcile.Result{}, err
168-
}
169-
utils.AssertEqual(r.AvailableCrds[drClusterConfigCRDName], crd.UID != "", utils.ExitCodeThatShouldRestartTheProcess)
170-
171146
// Fetch the StorageClaim instance
172147
r.storageClaim = &v1alpha1.StorageClaim{}
173148
r.storageClaim.Name = req.Name
@@ -424,6 +399,30 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
424399
if err != nil {
425400
return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeSnapshotClass: %s", err)
426401
}
402+
case "VolumeReplicationClass":
403+
vrc := &replicationv1alpha1.VolumeReplicationClass{}
404+
vrc.Name = r.storageClaim.Name
405+
if strings.Contains(resource.Name, "flatten") {
406+
vrc.Name = fmt.Sprintf("%s-flatten", r.storageClaim.Name)
407+
}
408+
err := utils.CreateOrReplace(r.ctx, r.Client, vrc, func() error {
409+
if err := r.own(vrc); err != nil {
410+
return fmt.Errorf("failed to own VolumeReplicationClass resource: %v", err)
411+
}
412+
if err := json.Unmarshal(resource.Data, &vrc.Spec); err != nil {
413+
return fmt.Errorf("failed to unmarshall VolumeReplicationClass spec: %v", err)
414+
}
415+
vrc.Spec.Parameters["replication.storage.openshift.io/replication-secret-namespace"] = r.OperatorNamespace
416+
417+
utils.AddLabels(vrc, resource.Labels)
418+
utils.AddAnnotations(vrc, resource.Annotations)
419+
420+
return nil
421+
})
422+
if err != nil {
423+
return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeReplicationClass: %s", err)
424+
}
425+
427426
case "ClientProfile":
428427
clientProfile := &csiopv1a1.ClientProfile{}
429428
clientProfile.Name = r.storageClaimHash

pkg/utils/k8sutils.go

+9
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ func AddLabel(obj metav1.Object, key string, value string) bool {
100100
return false
101101
}
102102

103+
func AddAnnotations(obj metav1.Object, newAnnotations map[string]string) {
104+
annotations := obj.GetAnnotations()
105+
if annotations == nil {
106+
annotations = map[string]string{}
107+
obj.SetAnnotations(annotations)
108+
}
109+
maps.Copy(annotations, newAnnotations)
110+
}
111+
103112
// AddAnnotation adds an annotation to a resource metadata, returns true if added else false
104113
func AddAnnotation(obj metav1.Object, key string, value string) bool {
105114
annotations := obj.GetAnnotations()

0 commit comments

Comments
 (0)