Skip to content

Commit

Permalink
Fix controllers and run codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
awgreene committed Dec 16, 2020
1 parent 5b3355a commit bf8d84a
Show file tree
Hide file tree
Showing 10 changed files with 427 additions and 246 deletions.
73 changes: 43 additions & 30 deletions pkg/controller/operators/adoption_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package operators

import (
"context"
"fmt"
"sync"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -45,9 +46,7 @@ type AdoptionReconciler struct {
// SetupWithManager adds the operator reconciler to the given controller manager.
func (r *AdoptionReconciler) SetupWithManager(mgr ctrl.Manager) error {
// Trigger operator events from the events of their compoenents.
enqueueSub := &handler.EnqueueRequestsFromMapFunc{
ToRequests: handler.ToRequestsFunc(r.mapToSubscriptions),
}
enqueueSub := handler.EnqueueRequestsFromMapFunc(r.mapToSubscriptions)

// Create multiple controllers for resource types that require automatic adoption
err := ctrl.NewControllerManagedBy(mgr).
Expand All @@ -60,12 +59,8 @@ func (r *AdoptionReconciler) SetupWithManager(mgr ctrl.Manager) error {
}

var (
enqueueCSV = &handler.EnqueueRequestsFromMapFunc{
ToRequests: handler.ToRequestsFunc(r.mapToClusterServiceVersions),
}
enqueueProviders = &handler.EnqueueRequestsFromMapFunc{
ToRequests: handler.ToRequestsFunc(r.mapToProviders),
}
enqueueCSV = handler.EnqueueRequestsFromMapFunc(r.mapToClusterServiceVersions)
enqueueProviders = handler.EnqueueRequestsFromMapFunc(r.mapToProviders)
)
err = ctrl.NewControllerManagedBy(mgr).
For(&operatorsv1alpha1.ClusterServiceVersion{}).
Expand Down Expand Up @@ -113,13 +108,12 @@ func NewAdoptionReconciler(cli client.Client, log logr.Logger, scheme *runtime.S
}

// ReconcileSubscription labels the CSVs installed by a Subscription as components of an operator named after the subscribed package and install namespace.
func (r *AdoptionReconciler) ReconcileSubscription(req ctrl.Request) (reconcile.Result, error) {
func (r *AdoptionReconciler) ReconcileSubscription(ctx context.Context, req ctrl.Request) (reconcile.Result, error) {
// Set up a convenient log object so we don't have to type request over and over again
log := r.log.WithValues("request", req)
log.V(4).Info("reconciling subscription")

// Fetch the Subscription from the cache
ctx := context.TODO()
in := &operatorsv1alpha1.Subscription{}
if err := r.Get(ctx, req.NamespacedName, in); err != nil {
if apierrors.IsNotFound(err) {
Expand Down Expand Up @@ -176,13 +170,12 @@ func (r *AdoptionReconciler) ReconcileSubscription(req ctrl.Request) (reconcile.
}

// ReconcileClusterServiceVersion projects the component labels of a given CSV onto all resources owned by it.
func (r *AdoptionReconciler) ReconcileClusterServiceVersion(req ctrl.Request) (reconcile.Result, error) {
func (r *AdoptionReconciler) ReconcileClusterServiceVersion(ctx context.Context, req ctrl.Request) (reconcile.Result, error) {
// Set up a convenient log object so we don't have to type request over and over again
log := r.log.WithValues("request", req)
log.V(4).Info("reconciling csv")

// Fetch the CSV from the cache
ctx := context.TODO()
in := &operatorsv1alpha1.ClusterServiceVersion{}
if err := r.Get(ctx, req.NamespacedName, in); err != nil {
if apierrors.IsNotFound(err) {
Expand Down Expand Up @@ -265,15 +258,20 @@ func (r *AdoptionReconciler) adopt(ctx context.Context, operator *decorators.Ope
return nil
}

if err := r.Get(ctx, types.NamespacedName{Namespace: m.GetNamespace(), Name: m.GetName()}, component); err != nil {
cObj, ok := component.(client.Object)
if !ok {
return fmt.Errorf("Unable to typecast runtime.Object to client.Object")
}

if err := r.Get(ctx, types.NamespacedName{Namespace: m.GetNamespace(), Name: m.GetName()}, cObj); err != nil {
if apierrors.IsNotFound(err) {
r.log.Error(err, "component not found")
err = nil
}

return err
}
candidate := component.DeepCopyObject()
candidate := cObj.DeepCopyObject()

adopted, err := operator.AdoptComponent(candidate)
if err != nil {
Expand All @@ -282,14 +280,21 @@ func (r *AdoptionReconciler) adopt(ctx context.Context, operator *decorators.Ope

if adopted {
// Only update if freshly adopted
r.log.Info("component adopted", "component", candidate)
return r.Patch(ctx, candidate, client.MergeFrom(component))
pCObj, ok := candidate.(client.Object)
if !ok {
return fmt.Errorf("Unable to typecast runtime.Object to client.Object")
}
return r.Patch(ctx, pCObj, client.MergeFrom(cObj))
}

return nil
}

func (r *AdoptionReconciler) disown(ctx context.Context, operator *decorators.Operator, component runtime.Object) error {
cObj, ok := component.(client.Object)
if !ok {
return fmt.Errorf("Unable to typecast runtime.Object to client.Object")
}
candidate := component.DeepCopyObject()
disowned, err := operator.DisownComponent(candidate)
if err != nil {
Expand All @@ -303,7 +308,11 @@ func (r *AdoptionReconciler) disown(ctx context.Context, operator *decorators.Op

// Only update if freshly disowned
r.log.V(4).Info("component disowned", "component", candidate)
return r.Patch(ctx, candidate, client.MergeFrom(component))
uCObj, ok := candidate.(client.Object)
if !ok {
return fmt.Errorf("Unable to typecast runtime.Object to client.Object")
}
return r.Patch(ctx, uCObj, client.MergeFrom(cObj))
}

func (r *AdoptionReconciler) adoptees(ctx context.Context, operator decorators.Operator, csv *operatorsv1alpha1.ClusterServiceVersion) ([]runtime.Object, error) {
Expand Down Expand Up @@ -335,7 +344,11 @@ func (r *AdoptionReconciler) adoptees(ctx context.Context, operator decorators.O
}
opt := client.MatchingLabelsSelector{Selector: selector}
for _, list := range componentLists {
if err := r.List(ctx, list, opt); err != nil {
cList, ok := list.(client.ObjectList)
if !ok {
return nil, fmt.Errorf("Unable to typecast runtime.Object to client.ObjectList")
}
if err := r.List(ctx, cList, opt); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -415,16 +428,16 @@ func (r *AdoptionReconciler) adoptInstallPlan(ctx context.Context, operator *dec
return utilerrors.NewAggregate(errs)
}

func (r *AdoptionReconciler) mapToSubscriptions(obj handler.MapObject) (requests []reconcile.Request) {
if obj.Meta == nil {
func (r *AdoptionReconciler) mapToSubscriptions(obj client.Object) (requests []reconcile.Request) {
if obj == nil {
return
}

// Requeue all Subscriptions in the resource namespace
// The Subscription reconciler will sort out the important changes
ctx := context.TODO()
subs := &operatorsv1alpha1.SubscriptionList{}
if err := r.List(ctx, subs, client.InNamespace(obj.Meta.GetNamespace())); err != nil {
if err := r.List(ctx, subs, client.InNamespace(obj.GetNamespace())); err != nil {
r.log.Error(err, "error listing subscriptions")
}

Expand All @@ -444,15 +457,15 @@ func (r *AdoptionReconciler) mapToSubscriptions(obj handler.MapObject) (requests
return
}

func (r *AdoptionReconciler) mapToClusterServiceVersions(obj handler.MapObject) (requests []reconcile.Request) {
if obj.Meta == nil {
func (r *AdoptionReconciler) mapToClusterServiceVersions(obj client.Object) (requests []reconcile.Request) {
if obj == nil {
return
}

// Get all owner CSV from owner labels if cluster scoped
namespace := obj.Meta.GetNamespace()
namespace := obj.GetNamespace()
if namespace == metav1.NamespaceAll {
name, ns, ok := ownerutil.GetOwnerByKindLabel(obj.Meta, operatorsv1alpha1.ClusterServiceVersionKind)
name, ns, ok := ownerutil.GetOwnerByKindLabel(obj, operatorsv1alpha1.ClusterServiceVersionKind)
if ok {
nsn := types.NamespacedName{Namespace: ns, Name: name}
requests = append(requests, reconcile.Request{NamespacedName: nsn})
Expand All @@ -461,7 +474,7 @@ func (r *AdoptionReconciler) mapToClusterServiceVersions(obj handler.MapObject)
}

// Get all owner CSVs from OwnerReferences
owners := ownerutil.GetOwnersByKind(obj.Meta, operatorsv1alpha1.ClusterServiceVersionKind)
owners := ownerutil.GetOwnersByKind(obj, operatorsv1alpha1.ClusterServiceVersionKind)
for _, owner := range owners {
nsn := types.NamespacedName{Namespace: namespace, Name: owner.Name}
requests = append(requests, reconcile.Request{NamespacedName: nsn})
Expand All @@ -470,8 +483,8 @@ func (r *AdoptionReconciler) mapToClusterServiceVersions(obj handler.MapObject)
return
}

func (r *AdoptionReconciler) mapToProviders(obj handler.MapObject) (requests []reconcile.Request) {
if obj.Meta == nil {
func (r *AdoptionReconciler) mapToProviders(obj client.Object) (requests []reconcile.Request) {
if obj == nil {
return nil
}

Expand All @@ -489,7 +502,7 @@ func (r *AdoptionReconciler) mapToProviders(obj handler.MapObject) (requests []r
NamespacedName: types.NamespacedName{Namespace: csv.GetNamespace(), Name: csv.GetName()},
}
for _, provided := range csv.Spec.CustomResourceDefinitions.Owned {
if provided.Name == obj.Meta.GetName() {
if provided.Name == obj.GetName() {
requests = append(requests, request)
break
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/controller/operators/adoption_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/reference"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/decorators"
Expand All @@ -33,11 +33,11 @@ var _ = Describe("Adoption Controller", func() {

Describe("Component label generation", func() {
var (
created []runtime.Object
created []client.Object
)

BeforeEach(func() {
created = []runtime.Object{}
created = []client.Object{}
})

JustAfterEach(func() {
Expand Down
22 changes: 12 additions & 10 deletions pkg/controller/operators/operator_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package operators

import (
"context"
"fmt"
"sync"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -58,10 +59,7 @@ type OperatorReconciler struct {
// SetupWithManager adds the operator reconciler to the given controller manager.
func (r *OperatorReconciler) SetupWithManager(mgr ctrl.Manager) error {
// Trigger operator events from the events of their compoenents.
enqueueOperator := &handler.EnqueueRequestsFromMapFunc{
ToRequests: handler.ToRequestsFunc(r.mapComponentRequests),
}

enqueueOperator := handler.EnqueueRequestsFromMapFunc(r.mapComponentRequests)
// Note: If we want to support resources composed of custom resources, we need to figure out how
// to dynamically add resource types to watch.
return ctrl.NewControllerManagedBy(mgr).
Expand Down Expand Up @@ -110,13 +108,12 @@ func NewOperatorReconciler(cli client.Client, log logr.Logger, scheme *runtime.S
// Implement reconcile.Reconciler so the controller can reconcile objects
var _ reconcile.Reconciler = &OperatorReconciler{}

func (r *OperatorReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
func (r *OperatorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
// Set up a convenient log object so we don't have to type request over and over again
log := r.log.WithValues("request", req)
log.V(1).Info("reconciling operator")

// Get the Operator
ctx := context.TODO()
create := false
name := req.NamespacedName.Name
in := &operatorsv1.Operator{}
Expand Down Expand Up @@ -210,7 +207,11 @@ func (r *OperatorReconciler) listComponents(ctx context.Context, selector labels

opt := client.MatchingLabelsSelector{Selector: selector}
for _, list := range componentLists {
if err := r.List(ctx, list, opt); err != nil {
cList, ok := list.(client.ObjectList)
if !ok {
return nil, fmt.Errorf("Unable to typecast runtime.Object to client.ObjectList")
}
if err := r.List(ctx, cList, opt); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -245,13 +246,14 @@ func (r *OperatorReconciler) unsetLastResourceVersion(name types.NamespacedName)
delete(r.lastResourceVersion, name)
}

func (r *OperatorReconciler) mapComponentRequests(obj handler.MapObject) []reconcile.Request {
func (r *OperatorReconciler) mapComponentRequests(obj client.Object) []reconcile.Request {
var requests []reconcile.Request
if obj.Meta == nil {
if obj == nil {
return requests
}

for _, name := range decorators.OperatorNames(obj.Meta.GetLabels()) {
labels := decorators.OperatorNames(obj.GetLabels())
for _, name := range labels {
// unset the last recorded resource version so the Operator will reconcile
r.unsetLastResourceVersion(name)
requests = append(requests, reconcile.Request{NamespacedName: name})
Expand Down
11 changes: 6 additions & 5 deletions pkg/controller/operators/operator_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"

operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/decorators"
Expand Down Expand Up @@ -83,16 +84,16 @@ var _ = Describe("Operator Controller", func() {
)

for _, obj := range objs {
Expect(k8sClient.Create(ctx, obj)).To(Succeed())
Expect(k8sClient.Create(ctx, obj.(client.Object))).To(Succeed())
}

expectedRefs = toRefs(scheme, objs...)
})

AfterEach(func() {
for _, obj := range objs {
Expect(k8sClient.Get(ctx, testobj.NamespacedName(obj), obj)).To(Succeed())
Expect(k8sClient.Delete(ctx, obj, deleteOpts)).To(Succeed())
Expect(k8sClient.Get(ctx, testobj.NamespacedName(obj), obj.(client.Object))).To(Succeed())
Expect(k8sClient.Delete(ctx, obj.(client.Object), deleteOpts)).To(Succeed())
}
})

Expand Down Expand Up @@ -125,7 +126,7 @@ var _ = Describe("Operator Controller", func() {
)

for _, obj := range newObjs {
Expect(k8sClient.Create(ctx, obj)).To(Succeed())
Expect(k8sClient.Create(ctx, obj.(client.Object))).To(Succeed())
}

objs = append(objs, newObjs...)
Expand All @@ -143,7 +144,7 @@ var _ = Describe("Operator Controller", func() {
Context("when component labels are removed", func() {
BeforeEach(func() {
for _, obj := range testobj.StripLabel(expectedKey, objs...) {
Expect(k8sClient.Update(ctx, obj)).To(Succeed())
Expect(k8sClient.Update(ctx, obj.(client.Object))).To(Succeed())
}
})

Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/operators/operatorcondition_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func NewOperatorConditionReconciler(cli client.Client, log logr.Logger, scheme *
// Implement reconcile.Reconciler so the controller can reconcile objects
var _ reconcile.Reconciler = &OperatorConditionReconciler{}

func (r *OperatorConditionReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
func (r *OperatorConditionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
// Set up a convenient log object so we don't have to type request over and over again
log := r.log.WithValues("request", req)
log.V(2).Info("reconciling operatorcondition")
Expand Down
Loading

0 comments on commit bf8d84a

Please sign in to comment.