Merge pull request #1560 from munnerz/ctrl-constructor-err

Allow controller constructor to return errors and pass RESTClient on context
This commit is contained in:
jetstack-bot 2019-04-18 14:46:06 +01:00 committed by GitHub
commit c6ebaa7eef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 41 additions and 20 deletions

View File

@ -56,7 +56,7 @@ func Run(opts *options.ControllerOptions, stopCh <-chan struct{}) {
rootCtx = logf.NewContext(rootCtx, nil, "controller")
log := logf.FromContext(rootCtx)
ctx, kubeCfg, err := buildControllerContext(rootCtx, opts)
ctx, kubeCfg, err := buildControllerContext(rootCtx, stopCh, opts)
if err != nil {
log.Error(err, "error building controller context", "options", opts)
@ -88,6 +88,11 @@ func Run(opts *options.ControllerOptions, stopCh <-chan struct{}) {
}
wg.Add(1)
iface, err := fn(ctx)
if err != nil {
log.Error(err, "error starting controller")
os.Exit(1)
}
go func(n string, fn controller.Interface) {
defer wg.Done()
log.Info("starting controller")
@ -99,7 +104,7 @@ func Run(opts *options.ControllerOptions, stopCh <-chan struct{}) {
log.Error(err, "error starting controller")
os.Exit(1)
}
}(n, fn(ctx))
}(n, iface)
}
log.V(4).Info("starting shared informer factories")
@ -126,9 +131,8 @@ func Run(opts *options.ControllerOptions, stopCh <-chan struct{}) {
panic("unreachable")
}
func buildControllerContext(ctx context.Context, opts *options.ControllerOptions) (*controller.Context, *rest.Config, error) {
func buildControllerContext(ctx context.Context, stopCh <-chan struct{}, opts *options.ControllerOptions) (*controller.Context, *rest.Config, error) {
log := logf.FromContext(ctx, "build-context")
// Load the users Kubernetes config
kubeCfg, err := kube.KubeConfig(opts.APIServerHost)
if err != nil {
@ -187,6 +191,8 @@ func buildControllerContext(ctx context.Context, opts *options.ControllerOptions
kubeSharedInformerFactory := kubeinformers.NewFilteredSharedInformerFactory(cl, time.Second*30, opts.Namespace, nil)
return &controller.Context{
RootContext: ctx,
StopCh: stopCh,
RESTConfig: kubeCfg,
Client: cl,
CMClient: intcl,
Recorder: recorder,

View File

@ -18,6 +18,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/k8s.io/client-go/informers:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/client-go/tools/record:go_default_library",
"//vendor/k8s.io/client-go/util/workqueue:go_default_library",

View File

@ -67,7 +67,7 @@ type Controller struct {
scheduler *scheduler.Scheduler
}
func New(ctx *controllerpkg.Context) *Controller {
func New(ctx *controllerpkg.Context) (*Controller, error) {
ctrl := &Controller{Context: *ctx}
ctrl.syncHandler = ctrl.processNextWorkItem
@ -110,7 +110,7 @@ func New(ctx *controllerpkg.Context) *Controller {
ctrl.scheduler = scheduler.New(ctrl.challengeLister)
ctrl.ctx = logf.NewContext(ctx.RootContext, nil, ControllerName)
return ctrl
return ctrl, nil
}
func (c *Controller) Run(workers int, stopCh <-chan struct{}) error {
@ -249,7 +249,11 @@ const (
)
func init() {
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) controllerpkg.Interface {
return New(ctx).Run
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) (controllerpkg.Interface, error) {
i, err := New(ctx)
if err != nil {
return nil, err
}
return i.Run, nil
})
}

View File

@ -97,7 +97,11 @@ func (f *controllerFixture) Finish(t *testing.T, args ...interface{}) {
func (f *controllerFixture) buildFakeController(b *test.Builder, issuer v1alpha1.GenericIssuer) *Controller {
b.Start()
c := New(b.Context)
c, err := New(b.Context)
if err != nil {
b.T.Errorf("error constructing controller: %v", err)
b.T.FailNow()
}
c.acmeHelper = f
c.helper = f
c.httpSolver = f.HTTP01

View File

@ -237,7 +237,7 @@ const (
)
func init() {
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) controllerpkg.Interface {
return New(ctx).Run
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) (controllerpkg.Interface, error) {
return New(ctx).Run, nil
})
}

View File

@ -207,7 +207,7 @@ const (
)
func init() {
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) controllerpkg.Interface {
return New(ctx).Run
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) (controllerpkg.Interface, error) {
return New(ctx).Run, nil
})
}

View File

@ -190,7 +190,7 @@ const (
)
func init() {
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) controllerpkg.Interface {
return New(ctx).Run
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) (controllerpkg.Interface, error) {
return New(ctx).Run, nil
})
}

View File

@ -23,6 +23,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
kubeinformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/record"
clientset "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"
@ -37,6 +38,11 @@ type Context struct {
// RootContext is the root context for the controller
RootContext context.Context
// StopCh is a channel that will be closed when the controller is signalled
// to exit
StopCh <-chan struct{}
// RESTConfig is the loaded Kubernetes apiserver rest client configuration
RESTConfig *rest.Config
// Client is a Kubernetes clientset
Client kubernetes.Interface
// CMClient is a cert-manager clientset

View File

@ -212,7 +212,7 @@ func (c *Controller) processNextWorkItem(ctx context.Context, key string) error
var keyFunc = controllerpkg.KeyFunc
func init() {
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) controllerpkg.Interface {
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) (controllerpkg.Interface, error) {
var clusterIssuerInformer cminformers.ClusterIssuerInformer
if ctx.Namespace == "" {
clusterIssuerInformer = ctx.SharedInformerFactory.Certmanager().V1alpha1().ClusterIssuers()
@ -226,6 +226,6 @@ func init() {
ctx.CMClient,
ctx.Recorder,
defaults{ctx.DefaultAutoCertificateAnnotations, ctx.DefaultIssuerName, ctx.DefaultIssuerKind, ctx.DefaultACMEIssuerChallengeType, ctx.DefaultACMEIssuerDNS01ProviderName},
).Run
).Run, nil
})
}

View File

@ -192,7 +192,7 @@ const (
)
func init() {
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) controllerpkg.Interface {
return New(ctx).Run
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) (controllerpkg.Interface, error) {
return New(ctx).Run, nil
})
}

View File

@ -28,7 +28,7 @@ type Interface func(workers int, stopCh <-chan struct{}) error
// Constructor is a function that creates a new control loop given a
// controller Context.
type Constructor func(ctx *Context) Interface
type Constructor func(ctx *Context) (Interface, error)
var (
known = make(map[string]Constructor, 0)