Skip to content

Re-use the RESTMapper from the ctrl.Manager in the dynamic watcher #171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/addon/walkthrough/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func (r *GuestbookReconciler) SetupWithManager(mgr ctrl.Manager) error {
}

// Watch for changes to deployed objects
_, err = declarative.WatchAll(mgr.GetConfig(), c, r, r.watchLabels)
_, err = declarative.WatchChildren(declarative.WatchChildrenOptions{Manager: mgr, Controller: c, Reconciler: r, LabelMaker: r.watchLabels})
if err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (r *GuestbookReconciler) SetupWithManager(mgr ctrl.Manager) error {
}

// Watch for changes to deployed objects
_, err = declarative.WatchAll(mgr.GetConfig(), c, r, r.watchLabels)
_, err = declarative.WatchChildren(declarative.WatchChildrenOptions{Manager: mgr, Controller: c, Reconciler: r, LabelMaker: r.watchLabels})
if err != nil {
return err
}
Expand Down
24 changes: 7 additions & 17 deletions pkg/patterns/declarative/pkg/watch/dynamic.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,27 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/log"
)

// WatchDelay is the time between a Watch being dropped and attempting to resume it
const WatchDelay = 30 * time.Second

func NewDynamicWatch(config rest.Config) (*dynamicWatch, chan event.GenericEvent, error) {
dw := &dynamicWatch{events: make(chan event.GenericEvent)}

restMapper, err := apiutil.NewDiscoveryRESTMapper(&config)
if err != nil {
return nil, nil, err
}

client, err := dynamic.NewForConfig(&config)
if err != nil {
return nil, nil, err
// NewDynamicWatch constructs a watcher for unstructured objects.
// Deprecated: avoid using directly; will move to internal in future.
func NewDynamicWatch(restMapper meta.RESTMapper, client dynamic.Interface) (*dynamicWatch, chan event.GenericEvent, error) {
dw := &dynamicWatch{
events: make(chan event.GenericEvent),
restMapper: restMapper,
client: client,
}

dw.restMapper = restMapper
dw.config = config
dw.client = client
return dw, dw.events, nil
}

type dynamicWatch struct {
config rest.Config
client dynamic.Interface
restMapper meta.RESTMapper
events chan event.GenericEvent
Expand Down
35 changes: 33 additions & 2 deletions pkg/patterns/declarative/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ import (
"fmt"
"sync"

"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/log"
Expand All @@ -45,7 +49,10 @@ type DynamicWatch interface {

// WatchChildrenOptions configures how we want to watch children.
type WatchChildrenOptions struct {
// RESTConfig is the configuration for connecting to the cluster
// Manager is used as a factory for the default RESTConfig and the RESTMapper.
Manager ctrl.Manager

// RESTConfig is the configuration for connecting to the cluster.
RESTConfig *rest.Config

// LabelMaker is used to build the labels we should watch on.
Expand Down Expand Up @@ -81,7 +88,31 @@ func WatchChildren(options WatchChildrenOptions) (chan struct{}, error) {
return nil, fmt.Errorf("labelMaker is required to scope watches")
}

dw, events, err := watch.NewDynamicWatch(*options.RESTConfig)
if options.RESTConfig == nil {
if options.Manager != nil {
options.RESTConfig = options.Manager.GetConfig()
} else {
return nil, fmt.Errorf("RESTConfig or Manager should be set")
}
}

var restMapper meta.RESTMapper
if options.Manager != nil {
restMapper = options.Manager.GetRESTMapper()
} else {
rm, err := apiutil.NewDiscoveryRESTMapper(options.RESTConfig)
if err != nil {
return nil, err
}
restMapper = rm
}

client, err := dynamic.NewForConfig(options.RESTConfig)
if err != nil {
return nil, err
}

dw, events, err := watch.NewDynamicWatch(restMapper, client)
if err != nil {
return nil, fmt.Errorf("creating dynamic watch: %v", err)
}
Expand Down