Skip to content

Commit 263ec26

Browse files
Merge pull request #735 from openshift-bot/synchronize-upstream
NO-ISSUE: Synchronize From Upstream Repositories
2 parents 9ad58fa + 7c5825f commit 263ec26

File tree

31 files changed

+304
-116
lines changed

31 files changed

+304
-116
lines changed

staging/operator-lifecycle-manager/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ FROM quay.io/fedora/fedora:37-x86_64 as builder
22
LABEL stage=builder
33
WORKDIR /build
44

5-
# install dependencies and go 1.16
5+
# install dependencies and go 1.21
66

77
# copy just enough of the git repo to parse HEAD, used to record version in OLM binaries
88
RUN dnf update -y && dnf install -y bash make git mercurial jq wget && dnf upgrade -y
9-
RUN curl -sSL https://go.dev/dl/go1.20.linux-amd64.tar.gz | tar -xzf - -C /usr/local
9+
RUN curl -sSL https://go.dev/dl/go1.21.9.linux-amd64.tar.gz | tar -xzf - -C /usr/local
1010
ENV PATH=/usr/local/go/bin:$PATH
1111
COPY .git/HEAD .git/HEAD
1212
COPY .git/refs/heads/. .git/refs/heads

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
@@ -737,6 +737,9 @@ func (c *ConfigMapUnpacker) ensureRole(cmRef *corev1.ObjectReference) (role *rba
737737
if err != nil {
738738
if apierrors.IsNotFound(err) {
739739
role, err = c.client.RbacV1().Roles(fresh.GetNamespace()).Create(context.TODO(), fresh, metav1.CreateOptions{})
740+
if apierrors.IsAlreadyExists(err) {
741+
role, err = c.client.RbacV1().Roles(fresh.GetNamespace()).Update(context.TODO(), fresh, metav1.UpdateOptions{})
742+
}
740743
}
741744

742745
return
@@ -781,6 +784,9 @@ func (c *ConfigMapUnpacker) ensureRoleBinding(cmRef *corev1.ObjectReference) (ro
781784
if err != nil {
782785
if apierrors.IsNotFound(err) {
783786
roleBinding, err = c.client.RbacV1().RoleBindings(fresh.GetNamespace()).Create(context.TODO(), fresh, metav1.CreateOptions{})
787+
if apierrors.IsAlreadyExists(err) {
788+
roleBinding, err = c.client.RbacV1().RoleBindings(fresh.GetNamespace()).Update(context.TODO(), fresh, metav1.UpdateOptions{})
789+
}
784790
}
785791

786792
return

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/controller/registry/reconciler/grpc.go

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@ package reconciler
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
7+
"slices"
68
"strings"
79
"time"
810

911
"github.com/google/go-cmp/cmp"
1012
"github.com/operator-framework/api/pkg/operators/v1alpha1"
11-
"github.com/pkg/errors"
13+
pkgerrors "github.com/pkg/errors"
1214
"github.com/sirupsen/logrus"
1315
corev1 "k8s.io/api/core/v1"
1416
apierrors "k8s.io/apimachinery/pkg/api/errors"
1517
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1618
"k8s.io/apimachinery/pkg/labels"
1719
"k8s.io/apimachinery/pkg/util/intstr"
20+
"k8s.io/utils/ptr"
1821

1922
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
2023
controllerclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client"
@@ -262,7 +265,7 @@ func (c *GrpcRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry, cata
262265
//TODO: if any of these error out, we should write a status back (possibly set RegistryServiceStatus to nil so they get recreated)
263266
sa, err := c.ensureSA(source)
264267
if err != nil && !apierrors.IsAlreadyExists(err) {
265-
return errors.Wrapf(err, "error ensuring service account: %s", source.GetName())
268+
return pkgerrors.Wrapf(err, "error ensuring service account: %s", source.GetName())
266269
}
267270

268271
sa, err = c.OpClient.GetServiceAccount(sa.GetNamespace(), sa.GetName())
@@ -285,20 +288,20 @@ func (c *GrpcRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry, cata
285288
return err
286289
}
287290
if err := c.ensurePod(logger, source, sa, overwritePod); err != nil {
288-
return errors.Wrapf(err, "error ensuring pod: %s", pod.GetName())
291+
return pkgerrors.Wrapf(err, "error ensuring pod: %s", pod.GetName())
289292
}
290293
if err := c.ensureUpdatePod(logger, sa, source); err != nil {
291294
if _, ok := err.(UpdateNotReadyErr); ok {
292295
return err
293296
}
294-
return errors.Wrapf(err, "error ensuring updated catalog source pod: %s", pod.GetName())
297+
return pkgerrors.Wrapf(err, "error ensuring updated catalog source pod: %s", pod.GetName())
295298
}
296299
service, err := source.Service()
297300
if err != nil {
298301
return err
299302
}
300303
if err := c.ensureService(source, overwrite); err != nil {
301-
return errors.Wrapf(err, "error ensuring service: %s", service.GetName())
304+
return pkgerrors.Wrapf(err, "error ensuring service: %s", service.GetName())
302305
}
303306

304307
if overwritePod {
@@ -338,16 +341,35 @@ func isRegistryServiceStatusValid(source *grpcCatalogSourceDecorator) (bool, err
338341
}
339342

340343
func (c *GrpcRegistryReconciler) ensurePod(logger *logrus.Entry, source grpcCatalogSourceDecorator, serviceAccount *corev1.ServiceAccount, overwrite bool) error {
341-
// currentLivePods refers to the currently live instances of the catalog source
342-
currentLivePods := c.currentPods(logger, source)
343-
if len(currentLivePods) > 0 {
344+
// currentPods refers to the current pod instances of the catalog source
345+
currentPods := c.currentPods(logger, source)
346+
347+
var forceDeleteErrs []error
348+
currentPods = slices.DeleteFunc(currentPods, func(pod *corev1.Pod) bool {
349+
if !isPodDead(pod) {
350+
logger.WithFields(logrus.Fields{"pod.namespace": source.GetNamespace(), "pod.name": pod.GetName()}).Debug("pod is alive")
351+
return false
352+
}
353+
logger.WithFields(logrus.Fields{"pod.namespace": source.GetNamespace(), "pod.name": pod.GetName()}).Info("force deleting dead pod")
354+
if err := c.OpClient.KubernetesInterface().CoreV1().Pods(source.GetNamespace()).Delete(context.TODO(), pod.GetName(), metav1.DeleteOptions{
355+
GracePeriodSeconds: ptr.To[int64](0),
356+
}); err != nil && !apierrors.IsNotFound(err) {
357+
forceDeleteErrs = append(forceDeleteErrs, pkgerrors.Wrapf(err, "error deleting old pod: %s", pod.GetName()))
358+
}
359+
return true
360+
})
361+
if len(forceDeleteErrs) > 0 {
362+
return errors.Join(forceDeleteErrs...)
363+
}
364+
365+
if len(currentPods) > 0 {
344366
if !overwrite {
345367
return nil
346368
}
347-
for _, p := range currentLivePods {
369+
for _, p := range currentPods {
348370
logger.WithFields(logrus.Fields{"pod.namespace": source.GetNamespace(), "pod.name": p.GetName()}).Info("deleting current pod")
349371
if err := c.OpClient.KubernetesInterface().CoreV1().Pods(source.GetNamespace()).Delete(context.TODO(), p.GetName(), *metav1.NewDeleteOptions(1)); err != nil && !apierrors.IsNotFound(err) {
350-
return errors.Wrapf(err, "error deleting old pod: %s", p.GetName())
372+
return pkgerrors.Wrapf(err, "error deleting old pod: %s", p.GetName())
351373
}
352374
}
353375
}
@@ -358,7 +380,7 @@ func (c *GrpcRegistryReconciler) ensurePod(logger *logrus.Entry, source grpcCata
358380
logger.WithFields(logrus.Fields{"pod.namespace": desiredPod.GetNamespace(), "pod.name": desiredPod.GetName()}).Info("creating desired pod")
359381
_, err = c.OpClient.KubernetesInterface().CoreV1().Pods(source.GetNamespace()).Create(context.TODO(), desiredPod, metav1.CreateOptions{})
360382
if err != nil {
361-
return errors.Wrapf(err, "error creating new pod: %s", desiredPod.GetGenerateName())
383+
return pkgerrors.Wrapf(err, "error creating new pod: %s", desiredPod.GetGenerateName())
362384
}
363385

364386
return nil
@@ -378,7 +400,7 @@ func (c *GrpcRegistryReconciler) ensureUpdatePod(logger *logrus.Entry, serviceAc
378400
logger.Infof("catalog update required at %s", time.Now().String())
379401
pod, err := c.createUpdatePod(source, serviceAccount)
380402
if err != nil {
381-
return errors.Wrapf(err, "creating update catalog source pod")
403+
return pkgerrors.Wrapf(err, "creating update catalog source pod")
382404
}
383405
source.SetLastUpdateTime()
384406
return UpdateNotReadyErr{catalogName: source.GetName(), podName: pod.GetName()}
@@ -410,7 +432,7 @@ func (c *GrpcRegistryReconciler) ensureUpdatePod(logger *logrus.Entry, serviceAc
410432
for _, p := range currentLivePods {
411433
logger.WithFields(logrus.Fields{"live-pod.namespace": source.GetNamespace(), "live-pod.name": p.Name}).Info("deleting current live pods")
412434
if err := c.OpClient.KubernetesInterface().CoreV1().Pods(source.GetNamespace()).Delete(context.TODO(), p.GetName(), *metav1.NewDeleteOptions(1)); err != nil && !apierrors.IsNotFound(err) {
413-
return errors.Wrapf(errors.Wrapf(err, "error deleting pod: %s", p.GetName()), "detected imageID change: error deleting old catalog source pod")
435+
return pkgerrors.Wrapf(pkgerrors.Wrapf(err, "error deleting pod: %s", p.GetName()), "detected imageID change: error deleting old catalog source pod")
414436
}
415437
}
416438
// done syncing
@@ -420,7 +442,7 @@ func (c *GrpcRegistryReconciler) ensureUpdatePod(logger *logrus.Entry, serviceAc
420442
// delete update pod right away, since the digest match, to prevent long-lived duplicate catalog pods
421443
logger.WithFields(logrus.Fields{"update-pod.namespace": updatePod.Namespace, "update-pod.name": updatePod.Name}).Debug("catalog polling result: no update; removing duplicate update pod")
422444
if err := c.OpClient.KubernetesInterface().CoreV1().Pods(source.GetNamespace()).Delete(context.TODO(), updatePod.GetName(), *metav1.NewDeleteOptions(1)); err != nil && !apierrors.IsNotFound(err) {
423-
return errors.Wrapf(errors.Wrapf(err, "error deleting pod: %s", updatePod.GetName()), "duplicate catalog polling pod")
445+
return pkgerrors.Wrapf(pkgerrors.Wrapf(err, "error deleting pod: %s", updatePod.GetName()), "duplicate catalog polling pod")
424446
}
425447
}
426448

@@ -523,6 +545,29 @@ func imageChanged(logger *logrus.Entry, updatePod *corev1.Pod, servingPods []*co
523545
return false
524546
}
525547

548+
func isPodDead(pod *corev1.Pod) bool {
549+
for _, check := range []func(*corev1.Pod) bool{
550+
isPodDeletedByTaintManager,
551+
} {
552+
if check(pod) {
553+
return true
554+
}
555+
}
556+
return false
557+
}
558+
559+
func isPodDeletedByTaintManager(pod *corev1.Pod) bool {
560+
if pod.DeletionTimestamp == nil {
561+
return false
562+
}
563+
for _, condition := range pod.Status.Conditions {
564+
if condition.Type == corev1.DisruptionTarget && condition.Reason == "DeletionByTaintManager" && condition.Status == corev1.ConditionTrue {
565+
return true
566+
}
567+
}
568+
return false
569+
}
570+
526571
// imageID returns the ImageID of the primary catalog source container or an empty string if the image ID isn't available yet.
527572
// Note: the pod must be running and the container in a ready status to return a valid ImageID.
528573
func imageID(pod *corev1.Pod) string {
@@ -545,7 +590,7 @@ func imageID(pod *corev1.Pod) string {
545590
func (c *GrpcRegistryReconciler) removePods(pods []*corev1.Pod, namespace string) error {
546591
for _, p := range pods {
547592
if err := c.OpClient.KubernetesInterface().CoreV1().Pods(namespace).Delete(context.TODO(), p.GetName(), *metav1.NewDeleteOptions(1)); err != nil && !apierrors.IsNotFound(err) {
548-
return errors.Wrapf(err, "error deleting pod: %s", p.GetName())
593+
return pkgerrors.Wrapf(err, "error deleting pod: %s", p.GetName())
549594
}
550595
}
551596
return nil
@@ -623,7 +668,7 @@ func (c *GrpcRegistryReconciler) podFailed(pod *corev1.Pod) (bool, error) {
623668
logrus.WithField("UpdatePod", pod.GetName()).Infof("catalog polling result: update pod %s failed to start", pod.GetName())
624669
err := c.removePods([]*corev1.Pod{pod}, pod.GetNamespace())
625670
if err != nil {
626-
return true, errors.Wrapf(err, "error deleting failed catalog polling pod: %s", pod.GetName())
671+
return true, pkgerrors.Wrapf(err, "error deleting failed catalog polling pod: %s", pod.GetName())
627672
}
628673
return true, nil
629674
}

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/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.

0 commit comments

Comments
 (0)