From 8d9967ef2d5c00dc2b73d41544ebc21a1813349e Mon Sep 17 00:00:00 2001 From: Jeff Peeler Date: Wed, 28 Aug 2019 18:35:01 -0400 Subject: [PATCH 1/3] feat(clusteroperator): plumb additional clients --- cmd/catalog/main.go | 7 ++++++- cmd/olm/main.go | 2 +- pkg/lib/operatorstatus/status.go | 7 ++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cmd/catalog/main.go b/cmd/catalog/main.go index 7bf09e5e78..9ad29789f2 100644 --- a/cmd/catalog/main.go +++ b/cmd/catalog/main.go @@ -16,6 +16,7 @@ import ( utilclock "k8s.io/apimachinery/pkg/util/clock" "k8s.io/client-go/tools/clientcmd" + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client" "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus" @@ -155,6 +156,10 @@ func main() { log.Fatalf("error configuring client: %s", err.Error()) } opClient := operatorclient.NewClientFromConfig(*kubeConfigPath, logger) + crClient, err := client.NewClient(*kubeConfigPath) + if err != nil { + log.Fatalf("error configuring client: %s", err.Error()) + } // Create a new instance of the operator. op, err := catalog.NewOperator(ctx, *kubeConfigPath, utilclock.RealClock{}, logger, *wakeupInterval, *configmapServerImage, *catalogNamespace, namespaces...) @@ -166,7 +171,7 @@ func main() { <-op.Ready() if *writeStatusName != "" { - operatorstatus.MonitorClusterStatus(*writeStatusName, *catalogNamespace, op.AtLevel(), op.Done(), opClient, configClient) + operatorstatus.MonitorClusterStatus(*writeStatusName, *catalogNamespace, op.AtLevel(), op.Done(), opClient, configClient, crClient) } <-op.Done() diff --git a/cmd/olm/main.go b/cmd/olm/main.go index 7c29e883b7..a11c28f1aa 100644 --- a/cmd/olm/main.go +++ b/cmd/olm/main.go @@ -196,7 +196,7 @@ func main() { <-op.Ready() if *writeStatusName != "" { - operatorstatus.MonitorClusterStatus(*writeStatusName, *namespace, op.AtLevel(), ctx.Done(), opClient, configClient) + operatorstatus.MonitorClusterStatus(*writeStatusName, *namespace, op.AtLevel(), ctx.Done(), opClient, configClient, crClient) } if *writePackageServerStatusName != "" { diff --git a/pkg/lib/operatorstatus/status.go b/pkg/lib/operatorstatus/status.go index db32b35cd8..fdafe379e0 100644 --- a/pkg/lib/operatorstatus/status.go +++ b/pkg/lib/operatorstatus/status.go @@ -8,6 +8,7 @@ import ( configv1 "github.com/openshift/api/config/v1" configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" log "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -27,7 +28,7 @@ const ( clusterOperatorCatalogSource = "operator-lifecycle-manager-catalog" ) -func MonitorClusterStatus(name, namespace string, syncCh <-chan error, stopCh <-chan struct{}, opClient operatorclient.ClientInterface, configClient configv1client.ConfigV1Interface) { +func MonitorClusterStatus(name, namespace string, syncCh <-chan error, stopCh <-chan struct{}, opClient operatorclient.ClientInterface, configClient configv1client.ConfigV1Interface, crClient versioned.Interface) { var ( syncs int successfulSyncs int @@ -113,7 +114,7 @@ func MonitorClusterStatus(name, namespace string, syncCh <-chan error, stopCh <- }, }, }) - created.Status.RelatedObjects = relatedObjects(name, namespace) + created.Status.RelatedObjects = relatedObjects(name, namespace, opClient, crClient) if createErr != nil { log.Errorf("Failed to create cluster operator: %v\n", createErr) return @@ -246,7 +247,7 @@ func findOperatorStatusCondition(conditions []configv1.ClusterOperatorStatusCond // relatedObjects returns RelatedObjects in the ClusterOperator.Status. // RelatedObjects are consumed by https://github.com/openshift/must-gather -func relatedObjects(name, namespace string) []configv1.ObjectReference { +func relatedObjects(name, namespace string, opClient operatorclient.ClientInterface, crClient versioned.Interface) []configv1.ObjectReference { var objectReferences []configv1.ObjectReference switch name { case clusterOperatorOLM: From ba9049b78059cb917a0edb245cb2adac9125a49e Mon Sep 17 00:00:00 2001 From: Jeff Peeler Date: Wed, 28 Aug 2019 19:06:59 -0400 Subject: [PATCH 2/3] fix(clusteroperator): fix naming of related objects --- cmd/catalog/main.go | 2 +- cmd/olm/main.go | 2 +- pkg/lib/operatorstatus/status.go | 70 ++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/cmd/catalog/main.go b/cmd/catalog/main.go index 9ad29789f2..82a2c4bab1 100644 --- a/cmd/catalog/main.go +++ b/cmd/catalog/main.go @@ -171,7 +171,7 @@ func main() { <-op.Ready() if *writeStatusName != "" { - operatorstatus.MonitorClusterStatus(*writeStatusName, *catalogNamespace, op.AtLevel(), op.Done(), opClient, configClient, crClient) + operatorstatus.MonitorClusterStatus(*writeStatusName, op.AtLevel(), op.Done(), opClient, configClient, crClient) } <-op.Done() diff --git a/cmd/olm/main.go b/cmd/olm/main.go index a11c28f1aa..ad4b9c4429 100644 --- a/cmd/olm/main.go +++ b/cmd/olm/main.go @@ -196,7 +196,7 @@ func main() { <-op.Ready() if *writeStatusName != "" { - operatorstatus.MonitorClusterStatus(*writeStatusName, *namespace, op.AtLevel(), ctx.Done(), opClient, configClient, crClient) + operatorstatus.MonitorClusterStatus(*writeStatusName, op.AtLevel(), ctx.Done(), opClient, configClient, crClient) } if *writePackageServerStatusName != "" { diff --git a/pkg/lib/operatorstatus/status.go b/pkg/lib/operatorstatus/status.go index fdafe379e0..45f46ce9d0 100644 --- a/pkg/lib/operatorstatus/status.go +++ b/pkg/lib/operatorstatus/status.go @@ -17,7 +17,6 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/discovery" - olmv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" olmv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version" @@ -26,9 +25,10 @@ import ( const ( clusterOperatorOLM = "operator-lifecycle-manager" clusterOperatorCatalogSource = "operator-lifecycle-manager-catalog" + openshiftNamespace = "openshift-operator-lifecycle-manager" ) -func MonitorClusterStatus(name, namespace string, syncCh <-chan error, stopCh <-chan struct{}, opClient operatorclient.ClientInterface, configClient configv1client.ConfigV1Interface, crClient versioned.Interface) { +func MonitorClusterStatus(name string, syncCh <-chan error, stopCh <-chan struct{}, opClient operatorclient.ClientInterface, configClient configv1client.ConfigV1Interface, crClient versioned.Interface) { var ( syncs int successfulSyncs int @@ -114,11 +114,14 @@ func MonitorClusterStatus(name, namespace string, syncCh <-chan error, stopCh <- }, }, }) - created.Status.RelatedObjects = relatedObjects(name, namespace, opClient, crClient) if createErr != nil { log.Errorf("Failed to create cluster operator: %v\n", createErr) return } + created.Status.RelatedObjects, err = relatedObjects(name, opClient, crClient) + if err != nil { + log.Errorf("Failed to get related objects: %v", err) + } existing = created err = nil } @@ -247,38 +250,55 @@ func findOperatorStatusCondition(conditions []configv1.ClusterOperatorStatusCond // relatedObjects returns RelatedObjects in the ClusterOperator.Status. // RelatedObjects are consumed by https://github.com/openshift/must-gather -func relatedObjects(name, namespace string, opClient operatorclient.ClientInterface, crClient versioned.Interface) []configv1.ObjectReference { +func relatedObjects(name string, opClient operatorclient.ClientInterface, crClient versioned.Interface) ([]configv1.ObjectReference, error) { var objectReferences []configv1.ObjectReference + log.Infof("Adding related objects for %v", name) + namespace := openshiftNamespace // hard-coded to constant + switch name { case clusterOperatorOLM: - objectReferences = []configv1.ObjectReference{ - { - Group: olmv1.GroupName, - Resource: olmv1.OperatorGroupKind, - Namespace: namespace, - Name: clusterOperatorOLM, - }, - { + csvList, err := crClient.OperatorsV1alpha1().ClusterServiceVersions(namespace).List(metav1.ListOptions{}) + if err != nil { + return nil, err + } + + for _, csv := range csvList.Items { + if csv.IsCopied() { + continue + } + objectReferences = append(objectReferences, configv1.ObjectReference{ Group: olmv1alpha1.GroupName, Resource: olmv1alpha1.ClusterServiceVersionKind, - Namespace: namespace, - Name: clusterOperatorOLM, - }, + Namespace: csv.GetNamespace(), + Name: csv.GetName(), + }) } case clusterOperatorCatalogSource: - objectReferences = []configv1.ObjectReference{ - { + subList, err := crClient.OperatorsV1alpha1().Subscriptions(namespace).List(metav1.ListOptions{}) + if err != nil { + return nil, err + } + + installPlanList, err := crClient.OperatorsV1alpha1().InstallPlans(namespace).List(metav1.ListOptions{}) + if err != nil { + return nil, err + } + + for _, sub := range subList.Items { + objectReferences = append(objectReferences, configv1.ObjectReference{ Group: olmv1alpha1.GroupName, Resource: olmv1alpha1.SubscriptionKind, - Namespace: namespace, - Name: clusterOperatorCatalogSource, - }, - { + Namespace: sub.GetNamespace(), + Name: sub.GetName(), + }) + } + for _, ip := range installPlanList.Items { + objectReferences = append(objectReferences, configv1.ObjectReference{ Group: olmv1alpha1.GroupName, Resource: olmv1alpha1.InstallPlanKind, - Namespace: namespace, - Name: clusterOperatorCatalogSource, - }, + Namespace: ip.GetNamespace(), + Name: ip.GetName(), + }) } } namespaces := configv1.ObjectReference{ @@ -287,5 +307,5 @@ func relatedObjects(name, namespace string, opClient operatorclient.ClientInterf Name: namespace, } objectReferences = append(objectReferences, namespaces) - return objectReferences + return objectReferences, nil } From c799a513c3780ebec9674a85e7e280b7c42db83e Mon Sep 17 00:00:00 2001 From: Jeff Peeler Date: Thu, 29 Aug 2019 16:08:05 -0400 Subject: [PATCH 3/3] fix(clusteroperator): update status after initial creation --- pkg/lib/operatorstatus/status.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/lib/operatorstatus/status.go b/pkg/lib/operatorstatus/status.go index 45f46ce9d0..89ea60be5c 100644 --- a/pkg/lib/operatorstatus/status.go +++ b/pkg/lib/operatorstatus/status.go @@ -14,6 +14,7 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/discovery" @@ -202,6 +203,16 @@ func MonitorClusterStatus(name string, syncCh <-chan error, stopCh <-chan struct // TODO: use % errors within a window to report available } + // always update the related objects in case changes have occurred + existing.Status.RelatedObjects, err = relatedObjects(name, opClient, crClient) + if err != nil { + log.Errorf("Failed to get related objects: %v", err) + } + if !reflect.DeepEqual(previousStatus.RelatedObjects, existing.Status.RelatedObjects) { + diffString := diff.ObjectDiff(previousStatus.RelatedObjects, existing.Status.RelatedObjects) + log.Debugf("Update required for related objects: %v", diffString) + } + // update the status if !reflect.DeepEqual(previousStatus, &existing.Status) { if _, err := configClient.ClusterOperators().UpdateStatus(existing); err != nil {