Skip to content

Commit f6374fb

Browse files
Merge pull request openshift#736 from kevinrizza/alreadyexists-fix-4.15
OCPBUGS-32311: [release-4.15]: Update if AlreadyExists
2 parents 764c6fe + c077b3d commit f6374fb

35 files changed

+296
-174
lines changed

staging/operator-lifecycle-manager/pkg/api/wrappers/deployment_install_client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ func (c *InstallStrategyDeploymentClientForNamespace) GetOpLister() operatorlist
5858
}
5959

6060
func (c *InstallStrategyDeploymentClientForNamespace) CreateRole(role *rbacv1.Role) (*rbacv1.Role, error) {
61-
return c.opClient.KubernetesInterface().RbacV1().Roles(c.Namespace).Create(context.TODO(), role, metav1.CreateOptions{})
61+
return c.opClient.CreateRole(role)
6262
}
6363

6464
func (c *InstallStrategyDeploymentClientForNamespace) CreateRoleBinding(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) {
65-
return c.opClient.KubernetesInterface().RbacV1().RoleBindings(c.Namespace).Create(context.TODO(), roleBinding, metav1.CreateOptions{})
65+
return c.opClient.CreateRoleBinding(roleBinding)
6666
}
6767

6868
func (c *InstallStrategyDeploymentClientForNamespace) EnsureServiceAccount(serviceAccount *corev1.ServiceAccount, owner ownerutil.Owner) (*corev1.ServiceAccount, error) {

staging/operator-lifecycle-manager/pkg/controller/bundle/bundle_unpacker.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,9 @@ func (c *ConfigMapUnpacker) ensureRole(cmRef *corev1.ObjectReference) (role *rba
734734
if err != nil {
735735
if apierrors.IsNotFound(err) {
736736
role, err = c.client.RbacV1().Roles(fresh.GetNamespace()).Create(context.TODO(), fresh, metav1.CreateOptions{})
737+
if apierrors.IsAlreadyExists(err) {
738+
role, err = c.client.RbacV1().Roles(fresh.GetNamespace()).Update(context.TODO(), fresh, metav1.UpdateOptions{})
739+
}
737740
}
738741

739742
return
@@ -778,6 +781,9 @@ func (c *ConfigMapUnpacker) ensureRoleBinding(cmRef *corev1.ObjectReference) (ro
778781
if err != nil {
779782
if apierrors.IsNotFound(err) {
780783
roleBinding, err = c.client.RbacV1().RoleBindings(fresh.GetNamespace()).Create(context.TODO(), fresh, metav1.CreateOptions{})
784+
if apierrors.IsAlreadyExists(err) {
785+
roleBinding, err = c.client.RbacV1().RoleBindings(fresh.GetNamespace()).Update(context.TODO(), fresh, metav1.UpdateOptions{})
786+
}
781787
}
782788

783789
return

staging/operator-lifecycle-manager/pkg/controller/install/certresources.go

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -463,53 +463,24 @@ func (i *StrategyDeploymentInstaller) installCertRequirementsForDeployment(deplo
463463
return nil, nil, err
464464
}
465465

466-
// Create RoleBinding to extension-apiserver-authentication-reader Role in the kube-system namespace.
467-
authReaderRoleBinding := &rbacv1.RoleBinding{
468-
Subjects: []rbacv1.Subject{
469-
{
470-
Kind: "ServiceAccount",
471-
APIGroup: "",
472-
Name: depSpec.Template.Spec.ServiceAccountName,
473-
Namespace: i.owner.GetNamespace(),
474-
},
475-
},
476-
RoleRef: rbacv1.RoleRef{
477-
APIGroup: "rbac.authorization.k8s.io",
478-
Kind: "Role",
479-
Name: "extension-apiserver-authentication-reader",
480-
},
481-
}
482-
authReaderRoleBinding.SetName(AuthReaderRoleBindingName(serviceName))
483-
authReaderRoleBinding.SetNamespace(KubeSystem)
484-
authReaderRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue})
466+
// Apply RoleBinding to extension-apiserver-authentication-reader Role in the kube-system namespace.
467+
authReaderRoleBindingApplyConfig := rbacv1ac.RoleBinding(AuthReaderRoleBindingName(serviceName), KubeSystem).
468+
WithLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}).
469+
WithSubjects(rbacv1ac.Subject().
470+
WithKind("ServiceAccount").
471+
WithAPIGroup("").
472+
WithName(depSpec.Template.Spec.ServiceAccountName).
473+
WithNamespace(i.owner.GetNamespace())).
474+
WithRoleRef(rbacv1ac.RoleRef().
475+
WithAPIGroup("rbac.authorization.k8s.io").
476+
WithKind("Role").
477+
WithName("extension-apiserver-authentication-reader"))
485478

486-
existingAuthReaderRoleBinding, err := i.strategyClient.GetOpLister().RbacV1().RoleBindingLister().RoleBindings(KubeSystem).Get(authReaderRoleBinding.GetName())
487-
if err == nil {
488-
// Check if the only owners are this CSV or in this CSV's replacement chain.
489-
if ownerutil.AdoptableLabels(existingAuthReaderRoleBinding.GetLabels(), true, i.owner) {
490-
logger.WithFields(log.Fields{"obj": "existingAuthReaderRB", "labels": existingAuthReaderRoleBinding.GetLabels()}).Debug("adopting")
491-
if err := ownerutil.AddOwnerLabels(authReaderRoleBinding, i.owner); err != nil {
492-
return nil, nil, err
493-
}
494-
}
495-
// Attempt an update.
496-
if _, err := i.strategyClient.GetOpClient().UpdateRoleBinding(authReaderRoleBinding); err != nil {
497-
logger.Warnf("could not update auth reader role binding %s", authReaderRoleBinding.GetName())
498-
return nil, nil, err
499-
}
500-
} else if apierrors.IsNotFound(err) {
501-
// Create the role.
502-
if err := ownerutil.AddOwnerLabels(authReaderRoleBinding, i.owner); err != nil {
503-
return nil, nil, err
504-
}
505-
_, err = i.strategyClient.GetOpClient().CreateRoleBinding(authReaderRoleBinding)
506-
if err != nil {
507-
log.Warnf("could not create auth reader role binding %s", authReaderRoleBinding.GetName())
508-
return nil, nil, err
509-
}
510-
} else {
479+
if _, err = i.strategyClient.GetOpClient().ApplyRoleBinding(authReaderRoleBindingApplyConfig, metav1.ApplyOptions{Force: true, FieldManager: "olm.install"}); err != nil {
480+
log.Errorf("could not apply auth reader rolebinding %s: %s", *authReaderRoleBindingApplyConfig.Name, err.Error())
511481
return nil, nil, err
512482
}
483+
513484
AddDefaultCertVolumeAndVolumeMounts(&depSpec, secret.GetName())
514485

515486
// Setting the olm hash label forces a rollout and ensures that the new secret

staging/operator-lifecycle-manager/pkg/controller/install/certresources_test.go

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,19 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) {
309309
authReaderRoleBinding.SetNamespace(KubeSystem)
310310
authReaderRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue})
311311

312-
mockOpClient.EXPECT().UpdateRoleBinding(authReaderRoleBinding).Return(authReaderRoleBinding, nil)
312+
authReaderRoleBindingApplyConfig := rbacv1ac.RoleBinding(AuthReaderRoleBindingName(service.GetName()), KubeSystem).
313+
WithLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}).
314+
WithSubjects(rbacv1ac.Subject().
315+
WithKind("ServiceAccount").
316+
WithAPIGroup("").
317+
WithName(args.depSpec.Template.Spec.ServiceAccountName).
318+
WithNamespace(namespace)).
319+
WithRoleRef(rbacv1ac.RoleRef().
320+
WithAPIGroup("rbac.authorization.k8s.io").
321+
WithKind("Role").
322+
WithName("extension-apiserver-authentication-reader"))
323+
324+
mockOpClient.EXPECT().ApplyRoleBinding(authReaderRoleBindingApplyConfig, metav1.ApplyOptions{Force: true, FieldManager: "olm.install"}).Return(authReaderRoleBinding, nil)
313325
},
314326
state: fakeState{
315327
existingService: &corev1.Service{
@@ -569,7 +581,19 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) {
569581
authReaderRoleBinding.SetNamespace(KubeSystem)
570582
authReaderRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue})
571583

572-
mockOpClient.EXPECT().UpdateRoleBinding(authReaderRoleBinding).Return(authReaderRoleBinding, nil)
584+
authReaderRoleBindingApplyConfig := rbacv1ac.RoleBinding(AuthReaderRoleBindingName(service.GetName()), KubeSystem).
585+
WithLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}).
586+
WithSubjects(rbacv1ac.Subject().
587+
WithKind("ServiceAccount").
588+
WithAPIGroup("").
589+
WithName(args.depSpec.Template.Spec.ServiceAccountName).
590+
WithNamespace(namespace)).
591+
WithRoleRef(rbacv1ac.RoleRef().
592+
WithAPIGroup("rbac.authorization.k8s.io").
593+
WithKind("Role").
594+
WithName("extension-apiserver-authentication-reader"))
595+
596+
mockOpClient.EXPECT().ApplyRoleBinding(authReaderRoleBindingApplyConfig, metav1.ApplyOptions{Force: true, FieldManager: "olm.install"}).Return(authReaderRoleBinding, nil)
573597
},
574598
state: fakeState{
575599
existingService: &corev1.Service{
@@ -831,7 +855,19 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) {
831855
authReaderRoleBinding.SetNamespace(KubeSystem)
832856
authReaderRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue})
833857

834-
mockOpClient.EXPECT().UpdateRoleBinding(authReaderRoleBinding).Return(authReaderRoleBinding, nil)
858+
authReaderRoleBindingApplyConfig := rbacv1ac.RoleBinding(AuthReaderRoleBindingName(service.GetName()), KubeSystem).
859+
WithLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}).
860+
WithSubjects(rbacv1ac.Subject().
861+
WithKind("ServiceAccount").
862+
WithAPIGroup("").
863+
WithName(args.depSpec.Template.Spec.ServiceAccountName).
864+
WithNamespace(namespace)).
865+
WithRoleRef(rbacv1ac.RoleRef().
866+
WithAPIGroup("rbac.authorization.k8s.io").
867+
WithKind("Role").
868+
WithName("extension-apiserver-authentication-reader"))
869+
870+
mockOpClient.EXPECT().ApplyRoleBinding(authReaderRoleBindingApplyConfig, metav1.ApplyOptions{Force: true, FieldManager: "olm.install"}).Return(authReaderRoleBinding, nil)
835871
},
836872
state: fakeState{
837873
existingService: nil,

staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,7 @@ func TestTransitionCSV(t *testing.T) {
15111511
// Note: Ideally we would not pre-create these objects, but fake client does not support
15121512
// creation through SSA, see issue here: https://github.com/kubernetes/kubernetes/issues/115598
15131513
// Once resolved, these objects and others in this file may be removed.
1514+
roleBinding("a1-service-auth-reader", "kube-system", "extension-apiserver-authentication-reader", "sa", namespace),
15141515
service("a1-service", namespace, "a1", 80),
15151516
clusterRoleBinding("a1-service-system:auth-delegator", "system:auth-delegator", "sa", namespace),
15161517
},
@@ -5985,8 +5986,9 @@ func TestCARotation(t *testing.T) {
59855986
), defaultTemplateAnnotations), apis("a1.v1.a1Kind"), nil),
59865987
},
59875988
clientObjs: []runtime.Object{addAnnotation(defaultOperatorGroup, operatorsv1.OperatorGroupProvidedAPIsAnnotationKey, "c1.v1.g1,a1Kind.v1.a1")},
5988-
// The service and clusterRoleBinding have been added here as a workaround to fake client not supporting SSA
5989+
// The rolebinding, service, and clusterRoleBinding have been added here as a workaround to fake client not supporting SSA
59895990
objs: []runtime.Object{
5991+
roleBinding("a1-service-auth-reader", "kube-system", "extension-apiserver-authentication-reader", "sa", namespace),
59905992
service("a1-service", namespace, "a1", 80, ownerReference),
59915993
clusterRoleBinding("a1-service-system:auth-delegator", "system:auth-delegator", "sa", namespace),
59925994
},

staging/operator-lifecycle-manager/pkg/controller/operators/olm/operatorgroup.go

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,8 @@ func (a *Operator) ensureProvidedAPIClusterRole(namePrefix, suffix string, verbs
408408
return err
409409
}
410410
if apierrors.IsNotFound(err) {
411-
existingCR, err = a.opClient.KubernetesInterface().RbacV1().ClusterRoles().Create(context.TODO(), clusterRole, metav1.CreateOptions{})
412-
if err == nil {
413-
return nil
414-
}
415-
if !apierrors.IsAlreadyExists(err) {
411+
existingCR, err = a.opClient.CreateClusterRole(clusterRole)
412+
if err != nil {
416413
a.logger.WithError(err).Errorf("Create cluster role failed: %v", clusterRole)
417414
return err
418415
}
@@ -546,12 +543,7 @@ func (a *Operator) ensureSingletonRBAC(operatorNamespace string, csv *v1alpha1.C
546543
Resources: []string{"namespaces"},
547544
}),
548545
}
549-
// TODO: this should do something smarter if the cluster role already exists
550-
if cr, err := a.opClient.CreateClusterRole(clusterRole); err != nil {
551-
// If the CR already exists, but the label is correct, the cache is just behind
552-
if apierrors.IsAlreadyExists(err) && cr != nil && ownerutil.IsOwnedByLabel(cr, csv) {
553-
continue
554-
}
546+
if _, err := a.opClient.CreateClusterRole(clusterRole); err != nil {
555547
return err
556548
}
557549
a.logger.Debug("created cluster role")
@@ -585,12 +577,7 @@ func (a *Operator) ensureSingletonRBAC(operatorNamespace string, csv *v1alpha1.C
585577
Name: r.RoleRef.Name,
586578
},
587579
}
588-
// TODO: this should do something smarter if the cluster role binding already exists
589-
if crb, err := a.opClient.CreateClusterRoleBinding(clusterRoleBinding); err != nil {
590-
// If the CRB already exists, but the label is correct, the cache is just behind
591-
if apierrors.IsAlreadyExists(err) && crb != nil && ownerutil.IsOwnedByLabel(crb, csv) {
592-
continue
593-
}
580+
if _, err := a.opClient.CreateClusterRoleBinding(clusterRoleBinding); err != nil {
594581
return err
595582
}
596583
}
@@ -1056,7 +1043,7 @@ func (a *Operator) ensureOpGroupClusterRole(op *operatorsv1.OperatorGroup, suffi
10561043
clusterRole.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue
10571044

10581045
a.logger.Infof("creating cluster role: %s owned by operator group: %s/%s", clusterRole.GetName(), op.GetNamespace(), op.GetName())
1059-
_, err = a.opClient.KubernetesInterface().RbacV1().ClusterRoles().Create(context.TODO(), clusterRole, metav1.CreateOptions{})
1046+
_, err = a.opClient.CreateClusterRole(clusterRole)
10601047
return err
10611048
}
10621049

staging/operator-lifecycle-manager/pkg/controller/operators/operatorcondition_controller.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ func (r *OperatorConditionReconciler) ensureOperatorConditionRole(operatorCondit
150150
if !apierrors.IsNotFound(err) {
151151
return err
152152
}
153-
return r.Client.Create(context.TODO(), role)
153+
err = r.Client.Create(context.TODO(), role)
154+
if apierrors.IsAlreadyExists(err) {
155+
return r.Client.Update(context.TODO(), role)
156+
}
154157
}
155158

156159
if ownerutil.IsOwnedBy(existingRole, operatorCondition) &&
@@ -199,7 +202,10 @@ func (r *OperatorConditionReconciler) ensureOperatorConditionRoleBinding(operato
199202
if !apierrors.IsNotFound(err) {
200203
return err
201204
}
202-
return r.Client.Create(context.TODO(), roleBinding)
205+
err = r.Client.Create(context.TODO(), roleBinding)
206+
if apierrors.IsAlreadyExists(err) {
207+
return r.Client.Update(context.TODO(), roleBinding)
208+
}
203209
}
204210

205211
if ownerutil.IsOwnedBy(existingRoleBinding, operatorCondition) &&

staging/operator-lifecycle-manager/pkg/lib/operatorclient/apiservice.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@ import (
44
"context"
55
"fmt"
66

7+
apierrors "k8s.io/apimachinery/pkg/api/errors"
78
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
89
"k8s.io/apimachinery/pkg/types"
910
"k8s.io/klog"
1011
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
1112
)
1213

13-
// CreateAPIService creates the APIService.
14+
// CreateAPIService creates the APIService or Updates if it already exists.
1415
func (c *Client) CreateAPIService(ig *apiregistrationv1.APIService) (*apiregistrationv1.APIService, error) {
15-
return c.ApiregistrationV1Interface().ApiregistrationV1().APIServices().Create(context.TODO(), ig, metav1.CreateOptions{})
16+
createdAS, err := c.ApiregistrationV1Interface().ApiregistrationV1().APIServices().Create(context.TODO(), ig, metav1.CreateOptions{})
17+
if apierrors.IsAlreadyExists(err) {
18+
return c.UpdateAPIService(ig)
19+
}
20+
return createdAS, err
1621
}
1722

1823
// GetAPIService returns the existing APIService.

staging/operator-lifecycle-manager/pkg/lib/operatorclient/client.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ type RoleClient interface {
9494

9595
// RoleBindingClient contains methods for manipulating RoleBindings.
9696
type RoleBindingClient interface {
97+
ApplyRoleBinding(applyConfig *rbacv1ac.RoleBindingApplyConfiguration, applyOptions metav1.ApplyOptions) (*rbacv1.RoleBinding, error)
9798
CreateRoleBinding(*rbacv1.RoleBinding) (*rbacv1.RoleBinding, error)
9899
GetRoleBinding(namespace, name string) (*rbacv1.RoleBinding, error)
99100
UpdateRoleBinding(modified *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error)

staging/operator-lifecycle-manager/pkg/lib/operatorclient/clusterrole.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@ import (
55
"fmt"
66

77
rbacv1 "k8s.io/api/rbac/v1"
8+
apierrors "k8s.io/apimachinery/pkg/api/errors"
89
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
910
"k8s.io/apimachinery/pkg/types"
1011
"k8s.io/klog"
1112
)
1213

13-
// CreateClusterRole creates the ClusterRole.
14+
// CreateClusterRole creates the ClusterRole or Updates if it already exists.
1415
func (c *Client) CreateClusterRole(r *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) {
15-
return c.RbacV1().ClusterRoles().Create(context.TODO(), r, metav1.CreateOptions{})
16+
createdClusterRole, err := c.RbacV1().ClusterRoles().Create(context.TODO(), r, metav1.CreateOptions{})
17+
if apierrors.IsAlreadyExists(err) {
18+
return c.UpdateClusterRole(r)
19+
}
20+
return createdClusterRole, err
1621
}
1722

1823
// GetClusterRole returns the existing ClusterRole.

staging/operator-lifecycle-manager/pkg/lib/operatorclient/clusterrolebinding.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66

77
rbacv1 "k8s.io/api/rbac/v1"
8+
apierrors "k8s.io/apimachinery/pkg/api/errors"
89
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
910
"k8s.io/apimachinery/pkg/types"
1011
acv1 "k8s.io/client-go/applyconfigurations/rbac/v1"
@@ -16,9 +17,13 @@ func (c *Client) ApplyClusterRoleBinding(applyConfig *acv1.ClusterRoleBindingApp
1617
return c.RbacV1().ClusterRoleBindings().Apply(context.TODO(), applyConfig, applyOptions)
1718
}
1819

19-
// CreateRoleBinding creates the roleBinding.
20+
// CreateRoleBinding creates the roleBinding or Updates if it already exists.
2021
func (c *Client) CreateClusterRoleBinding(ig *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) {
21-
return c.RbacV1().ClusterRoleBindings().Create(context.TODO(), ig, metav1.CreateOptions{})
22+
createdCRB, err := c.RbacV1().ClusterRoleBindings().Create(context.TODO(), ig, metav1.CreateOptions{})
23+
if apierrors.IsAlreadyExists(err) {
24+
return c.UpdateClusterRoleBinding(ig)
25+
}
26+
return createdCRB, err
2227
}
2328

2429
// GetRoleBinding returns the existing roleBinding.

staging/operator-lifecycle-manager/pkg/lib/operatorclient/configmap.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@ import (
55
"fmt"
66

77
corev1 "k8s.io/api/core/v1"
8+
apierrors "k8s.io/apimachinery/pkg/api/errors"
89
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
910
"k8s.io/apimachinery/pkg/types"
1011
"k8s.io/klog"
1112
)
1213

1314
// CreateConfigMap creates the ConfigMap.
1415
func (c *Client) CreateConfigMap(ig *corev1.ConfigMap) (*corev1.ConfigMap, error) {
15-
return c.CoreV1().ConfigMaps(ig.GetNamespace()).Create(context.TODO(), ig, metav1.CreateOptions{})
16+
createdCM, err := c.CoreV1().ConfigMaps(ig.GetNamespace()).Create(context.TODO(), ig, metav1.CreateOptions{})
17+
if apierrors.IsAlreadyExists(err) {
18+
return c.UpdateConfigMap(ig)
19+
}
20+
return createdCM, err
1621
}
1722

1823
// GetConfigMap returns the existing ConfigMap.

staging/operator-lifecycle-manager/pkg/lib/operatorclient/customresources.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"time"
1010

1111
"k8s.io/apimachinery/pkg/api/errors"
12+
apierrors "k8s.io/apimachinery/pkg/api/errors"
1213
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1314
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1415
"k8s.io/apimachinery/pkg/util/wait"
@@ -92,7 +93,7 @@ func (c *Client) CreateCustomResourceRaw(apiGroup, version, namespace, kind stri
9293
return nil
9394
}
9495

95-
// CreateCustomResourceRawIfNotFound creates the raw bytes of the custom resource if it doesn't exist.
96+
// CreateCustomResourceRawIfNotFound creates the raw bytes of the custom resource if it doesn't exist, or Updates if it does exist.
9697
// It also returns a boolean to indicate whether a new custom resource is created.
9798
func (c *Client) CreateCustomResourceRawIfNotFound(apiGroup, version, namespace, kind, name string, data []byte) (bool, error) {
9899
klog.V(4).Infof("[CREATE CUSTOM RESOURCE RAW if not found]: %s:%s", namespace, name)
@@ -104,7 +105,11 @@ func (c *Client) CreateCustomResourceRawIfNotFound(apiGroup, version, namespace,
104105
return false, err
105106
}
106107
err = c.CreateCustomResourceRaw(apiGroup, version, namespace, kind, data)
107-
if err != nil {
108+
if apierrors.IsAlreadyExists(err) {
109+
if err = c.UpdateCustomResourceRaw(apiGroup, version, namespace, kind, name, data); err != nil {
110+
return false, err
111+
}
112+
} else if err != nil {
108113
return false, err
109114
}
110115
return true, nil

0 commit comments

Comments
 (0)