Skip to content

Commit 1b20b3e

Browse files
Merge pull request #925 from tkashem/bz-1723818
Bug 1723818: CSV name change should not cause upgrade to fail
2 parents 4b04955 + d3c2b32 commit 1b20b3e

File tree

2 files changed

+72
-35
lines changed

2 files changed

+72
-35
lines changed

pkg/controller/operators/olm/apiservices.go

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package olm
22

33
import (
4+
"errors"
45
"fmt"
56
"strings"
67
"time"
@@ -65,18 +66,6 @@ func (a *Operator) checkAPIServiceResources(csv *v1alpha1.ClusterServiceVersion,
6566
})
6667

6768
errs := []error{}
68-
owners := []ownerutil.Owner{csv}
69-
70-
// Get replacing CSV if exists
71-
replacing, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(csv.GetNamespace()).Get(csv.Spec.Replaces)
72-
if err != nil && !k8serrors.IsNotFound(err) {
73-
logger.WithError(err).Warn("could not get replacement csv")
74-
return err
75-
}
76-
if replacing != nil {
77-
owners = append(owners, replacing)
78-
}
79-
8069
ruleChecker := install.NewCSVRuleChecker(a.lister.RbacV1().RoleLister(), a.lister.RbacV1().RoleBindingLister(), a.lister.RbacV1().ClusterRoleLister(), a.lister.RbacV1().ClusterRoleBindingLister(), csv)
8170
for _, desc := range csv.GetOwnedAPIServiceDescriptions() {
8271
apiServiceName := desc.GetName()
@@ -92,8 +81,15 @@ func (a *Operator) checkAPIServiceResources(csv *v1alpha1.ClusterServiceVersion,
9281
}
9382

9483
// Check if the APIService is adoptable
95-
if !ownerutil.AdoptableLabels(apiService.GetLabels(), true, owners...) {
96-
logger.WithFields(log.Fields{"obj": "apiService", "labels": apiService.GetLabels()}).Debug("adoption failed")
84+
adoptable, err := a.isAPIServiceAdoptable(csv, apiService)
85+
if err != nil {
86+
logger.WithFields(log.Fields{"obj": "apiService", "labels": apiService.GetLabels()}).Errorf("adoption check failed - %v", err)
87+
errs = append(errs, err)
88+
return utilerrors.NewAggregate(errs)
89+
}
90+
91+
if !adoptable {
92+
logger.WithFields(log.Fields{"obj": "apiService", "labels": apiService.GetLabels()}).Errorf("adoption failed")
9793
err := olmerrors.NewUnadoptableError("", apiServiceName)
9894
logger.WithError(err).Warn("found unadoptable apiservice")
9995
errs = append(errs, err)
@@ -707,17 +703,12 @@ func (a *Operator) installAPIServiceRequirements(desc v1alpha1.APIServiceDescrip
707703
}
708704
apiService.SetName(apiServiceName)
709705
} else {
710-
owners := []ownerutil.Owner{csv}
711-
712-
// Get replacing CSV
713-
replaces, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(csv.GetNamespace()).Get(csv.Spec.Replaces)
714-
if err == nil {
715-
owners = append(owners, replaces)
706+
adoptable, err := a.isAPIServiceAdoptable(csv, apiService)
707+
if err != nil {
708+
logger.WithFields(log.Fields{"obj": "apiService", "labels": apiService.GetLabels()}).Errorf("adoption check failed - %v", err)
716709
}
717710

718-
// check if the APIService is adoptable
719-
if !ownerutil.AdoptableLabels(apiService.GetLabels(), true, owners...) {
720-
logger.WithFields(log.Fields{"obj": "apiService", "labels": apiService.GetLabels()}).Debug("adoption failed")
711+
if !adoptable{
721712
return nil, fmt.Errorf("pre-existing APIService %s is not adoptable", apiServiceName)
722713
}
723714
}
@@ -759,3 +750,54 @@ func APIServiceNameToServiceName(apiServiceName string) string {
759750
// Replace all '.'s with "-"s to convert to a DNS-1035 label
760751
return strings.Replace(apiServiceName, ".", "-", -1)
761752
}
753+
754+
func (a *Operator) isAPIServiceAdoptable(target *v1alpha1.ClusterServiceVersion, apiService *apiregistrationv1.APIService) (adoptable bool, err error) {
755+
if apiService == nil || target == nil {
756+
err = errors.New("invalid input")
757+
return
758+
}
759+
760+
labels := apiService.GetLabels()
761+
ownerKind := labels[ownerutil.OwnerKind]
762+
ownerName := labels[ownerutil.OwnerKey]
763+
ownerNamespace := labels[ownerutil.OwnerNamespaceKey]
764+
765+
if ownerKind == "" || ownerNamespace == "" || ownerName == "" {
766+
return
767+
}
768+
769+
if err := ownerutil.InferGroupVersionKind(target); err != nil {
770+
a.logger.Warn(err.Error())
771+
}
772+
773+
targetKind := target.GetObjectKind().GroupVersionKind().Kind
774+
if ownerKind != targetKind {
775+
return
776+
}
777+
778+
// Get the CSV that target replaces
779+
replacing, replaceGetErr := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(target.GetNamespace()).Get(target.Spec.Replaces)
780+
if replaceGetErr != nil && !k8serrors.IsNotFound(replaceGetErr) && !k8serrors.IsGone(replaceGetErr) {
781+
err = replaceGetErr
782+
return
783+
}
784+
785+
// Get the current owner CSV of the APIService
786+
currentOwnerCSV, ownerGetErr := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(ownerNamespace).Get(ownerName)
787+
if ownerGetErr != nil && !k8serrors.IsNotFound(ownerGetErr) && !k8serrors.IsGone(ownerGetErr) {
788+
err = ownerGetErr
789+
return
790+
}
791+
792+
owners := []ownerutil.Owner{target}
793+
if replacing != nil {
794+
owners = append(owners, replacing)
795+
}
796+
if currentOwnerCSV != nil && (
797+
currentOwnerCSV.Status.Phase == v1alpha1.CSVPhaseReplacing || currentOwnerCSV.Status.Phase == v1alpha1.CSVPhaseDeleting) {
798+
owners = append(owners, currentOwnerCSV)
799+
}
800+
801+
adoptable = ownerutil.AdoptableLabels(apiService.GetLabels(), true, owners...)
802+
return
803+
}

pkg/controller/operators/olm/operator.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88
"time"
99

10+
log "github.com/sirupsen/logrus"
1011
v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1"
1112
"github.com/sirupsen/logrus"
1213
corev1 "k8s.io/api/core/v1"
@@ -1410,17 +1411,6 @@ func (a *Operator) getReplacementChain(in *v1alpha1.ClusterServiceVersion, csvsI
14101411
}
14111412

14121413
func (a *Operator) apiServiceOwnerConflicts(csv *v1alpha1.ClusterServiceVersion) error {
1413-
// Get replacing CSV if exists
1414-
replacing, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(csv.GetNamespace()).Get(csv.Spec.Replaces)
1415-
if err != nil && !k8serrors.IsNotFound(err) && !k8serrors.IsGone(err) {
1416-
return err
1417-
}
1418-
1419-
owners := []ownerutil.Owner{csv}
1420-
if replacing != nil {
1421-
owners = append(owners, replacing)
1422-
}
1423-
14241414
for _, desc := range csv.GetOwnedAPIServiceDescriptions() {
14251415
// Check if the APIService exists
14261416
apiService, err := a.lister.APIRegistrationV1().APIServiceLister().Get(desc.GetName())
@@ -1432,7 +1422,12 @@ func (a *Operator) apiServiceOwnerConflicts(csv *v1alpha1.ClusterServiceVersion)
14321422
continue
14331423
}
14341424

1435-
if !ownerutil.AdoptableLabels(apiService.GetLabels(), true, owners...) {
1425+
adoptable, err := a.isAPIServiceAdoptable(csv, apiService)
1426+
if err != nil {
1427+
a.logger.WithFields(log.Fields{"obj": "apiService", "labels": apiService.GetLabels()}).Errorf("adoption check failed - %v", err)
1428+
}
1429+
1430+
if !adoptable {
14361431
return ErrAPIServiceOwnerConflict
14371432
}
14381433
}

0 commit comments

Comments
 (0)