Skip to content

Commit

Permalink
Add localmanifests controller to perform bootstrapping for cert-manag…
Browse files Browse the repository at this point in the history
…er certs
  • Loading branch information
munnerz committed Jun 15, 2018
1 parent 09cf785 commit 8a1118e
Show file tree
Hide file tree
Showing 9 changed files with 307 additions and 281 deletions.
6 changes: 1 addition & 5 deletions cmd/controller/app/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,7 @@ func buildControllerContext(opts *options.ControllerOptions) (*controller.Contex
DefaultIssuerKind: opts.DefaultIssuerKind,
DefaultACMEIssuerChallengeType: opts.DefaultACMEIssuerChallengeType,
DefaultACMEIssuerDNS01ProviderName: opts.DefaultACMEIssuerDNS01ProviderName,
WebhookNamespace: opts.WebhookNamespace,
WebhookServiceName: opts.WebhookServiceName,
WebhookIssuerName: opts.WebhookIssuerName,
WebhookCASecret: opts.WebhookCASecret,
WebhookSecretName: opts.WebhookSecretName,
LocalManifestsDir: opts.LocalManifestsDir,
}, kubeCfg, nil
}

Expand Down
39 changes: 6 additions & 33 deletions cmd/controller/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ type ControllerOptions struct {
DefaultACMEIssuerChallengeType string
DefaultACMEIssuerDNS01ProviderName string

WebhookNamespace string
WebhookServiceName string
WebhookIssuerName string
WebhookCASecret string
WebhookSecretName string
LocalManifestsDir string
}

const (
Expand All @@ -56,11 +52,7 @@ const (
defaultACMEIssuerChallengeType = "http01"
defaultACMEIssuerDNS01ProviderName = ""

defaultWebhookNamespace = ""
defaultWebhookServiceName = ""
defaultWebhookIssuerName = ""
defaultWebhookCASecret = ""
defaultWebhookSecretName = ""
defaultLocalManifestsDir = "/etc/cert-manager/manifests"
)

var (
Expand All @@ -82,11 +74,7 @@ func NewControllerOptions() *ControllerOptions {
DefaultIssuerKind: defaultTLSACMEIssuerKind,
DefaultACMEIssuerChallengeType: defaultACMEIssuerChallengeType,
DefaultACMEIssuerDNS01ProviderName: defaultACMEIssuerDNS01ProviderName,
WebhookNamespace: defaultWebhookNamespace,
WebhookServiceName: defaultWebhookServiceName,
WebhookIssuerName: defaultWebhookIssuerName,
WebhookCASecret: defaultWebhookCASecret,
WebhookSecretName: defaultWebhookSecretName,
LocalManifestsDir: defaultLocalManifestsDir,
}
}

Expand Down Expand Up @@ -139,19 +127,9 @@ func (s *ControllerOptions) AddFlags(fs *pflag.FlagSet) {
"Required if --default-acme-issuer-challenge-type is set to dns01. The DNS01 provider to use for ingresses using ACME dns01 "+
"validation that do not explicitly state a dns provider.")

fs.StringVar(&s.WebhookNamespace, "webhook-namespace", defaultWebhookNamespace, ""+
"The namespace that the validating and mutating webhook is running in.")
fs.StringVar(&s.WebhookServiceName, "webhook-service-name", defaultWebhookServiceName, ""+
"The name of the service for the validating and mutating webhook.")
fs.StringVar(&s.WebhookIssuerName, "webhook-issuer-name", defaultWebhookIssuerName, ""+
"The name of the issuer to bootstrap for the webhook TLS configuration.")
fs.StringVar(&s.WebhookCASecret, "webhook-ca-secret", defaultWebhookCASecret, ""+
"The name of the Secret resource containing the signing keypair for the webhook bootstrap issuer. "+
"This must be pre-provisioned by the user using openssl or similar.")
fs.StringVar(&s.WebhookSecretName, "webhook-secret-name", defaultWebhookSecretName, ""+
"The name of the Secret resource the webhook is using to serve with. "+
"During bootstrapping, a Certificate resource will be created to populate this Secret. "+
"It will subsequently be kept up to date by cert-manager after the webhook has finished bootstrapping.")
fs.StringVar(&s.LocalManifestsDir, "local-manifests-dir", defaultLocalManifestsDir, ""+
"Directory containing resources to be synced and mirrored back to the Kubernetes API. "+
"Similar to 'mirror pods' in Kubernetes.")
}

func (o *ControllerOptions) Validate() error {
Expand All @@ -163,11 +141,6 @@ func (o *ControllerOptions) Validate() error {
errs = append(errs, fmt.Errorf("invalid default issuer kind: %v", o.DefaultIssuerKind))
}

err := allOrNone(o.WebhookNamespace, o.WebhookServiceName, o.WebhookIssuerName, o.WebhookCASecret, o.WebhookSecretName)
if err != nil {
errs = append(errs, fmt.Errorf("webhook configuration error: %v", err))
}

return utilerrors.NewAggregate(errs)
}

Expand Down
1 change: 1 addition & 0 deletions cmd/controller/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
_ "github.com/jetstack/cert-manager/pkg/controller/clusterissuers"
_ "github.com/jetstack/cert-manager/pkg/controller/ingress-shim"
_ "github.com/jetstack/cert-manager/pkg/controller/issuers"
_ "github.com/jetstack/cert-manager/pkg/controller/localmanifests"
_ "github.com/jetstack/cert-manager/pkg/issuer/acme"
_ "github.com/jetstack/cert-manager/pkg/issuer/ca"
_ "github.com/jetstack/cert-manager/pkg/issuer/selfsigned"
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/certmanager/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ type ObjectReference struct {
}

const (
CertificateKind = "Certificate"
ClusterIssuerKind = "ClusterIssuer"
IssuerKind = "Issuer"
)
Expand Down
22 changes: 0 additions & 22 deletions pkg/controller/certificates/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ type Controller struct {
scheduledWorkQueue scheduler.ScheduledWorkQueue
workerWg sync.WaitGroup
syncedFuncs []cache.InformerSynced

// this function will be continually run by the controller once it has started up
// until it returns non-error.
webhookBootstrapFn func(context.Context, controllerpkg.CertificateSyncFunc) error
}

// New returns a new Certificates controller. It sets up the informer handler
Expand All @@ -68,7 +64,6 @@ func New(
cmClient clientset.Interface,
issuerFactory issuer.Factory,
recorder record.EventRecorder,
webhookBootstrapFn func(context.Context, controllerpkg.CertificateSyncFunc) error,
) *Controller {
ctrl := &Controller{client: client, cmClient: cmClient, issuerFactory: issuerFactory, recorder: recorder}
ctrl.syncHandler = ctrl.processNextWorkItem
Expand Down Expand Up @@ -110,8 +105,6 @@ func New(
ctrl.syncedFuncs = append(ctrl.syncedFuncs, podsInformer.Informer().HasSynced)
ctrl.syncedFuncs = append(ctrl.syncedFuncs, serviceInformer.Informer().HasSynced)

ctrl.webhookBootstrapFn = webhookBootstrapFn

return ctrl
}

Expand Down Expand Up @@ -148,20 +141,6 @@ func (c *Controller) Run(workers int, stopCh <-chan struct{}) error {

glog.V(4).Infof("Synced all caches for %s control loop", ControllerName)

// start running the bootstrap function
go func() {
ctx := context.TODO()
for {
err := c.webhookBootstrapFn(ctx, c.sync)
if err == nil {
glog.Infof("Webhook Certificate bootstrap finished")
return
}
glog.Infof("Webhook Certificate bootstrap failed, retrying in 5s: %v", err)
time.Sleep(time.Second * 5)
}
}()

for i := 0; i < workers; i++ {
c.workerWg.Add(1)
// TODO (@munnerz): make time.Second duration configurable
Expand Down Expand Up @@ -256,7 +235,6 @@ func init() {
ctx.CMClient,
ctx.IssuerFactory,
ctx.Recorder,
ctx.SyncWebhookCertificate,
).Run
})
}
29 changes: 3 additions & 26 deletions pkg/controller/context.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package controller

import (
"sync"

kubeinformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/record"

"github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
clientset "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"
informers "github.com/jetstack/cert-manager/pkg/client/informers/externalversions"
"github.com/jetstack/cert-manager/pkg/issuer"
Expand Down Expand Up @@ -45,27 +42,7 @@ type Context struct {
DefaultACMEIssuerChallengeType string
DefaultACMEIssuerDNS01ProviderName string

// WebhookNamespace is the namespace the cert-manager webhook component
// is installed into. Controllers will automatically create Issuer and
// Certificate resources in this namespace in order to perform bootstrapping
// of webhook TLS configuration.
WebhookNamespace string
// WebhookServiceName is the name of the service for the webhook component.
WebhookServiceName string
// WebhookIssuerName is the name of an issuer cert-manager should automatically
// create in the webhook namespace.
WebhookIssuerName string
// WebhookCASecret is the name of a secret resource containing a signing keypair
// to be used for the webhook CA issuer.
WebhookCASecret string
// WebhookSecretName is the name of the secret storing the TLS certificate for
// the webhook to serve with.
WebhookSecretName string

// internal fields for resources. This is mostly during the phase where
// webhook bootstrapping is occurring, e.g.
internalWebhookIssuer *v1alpha1.Issuer
internalWebhookCertificate *v1alpha1.Certificate
// webhookLock coordinates changes to the internal webhook fields
webhookLock sync.Mutex
// LocalManifestsDir is the directory containing local manifests that
// should be processed and eventually persisted to the API server.
LocalManifestsDir string
}
22 changes: 0 additions & 22 deletions pkg/controller/issuers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ type Controller struct {

queue workqueue.RateLimitingInterface
workerWg sync.WaitGroup

// this function will be continually run by the controller once it has started up
// until it returns non-error.
webhookBootstrapFn func(context.Context, controllerpkg.IssuerSyncFunc) error
}

func New(
Expand All @@ -56,7 +52,6 @@ func New(
cmClient clientset.Interface,
issuerFactory issuer.Factory,
recorder record.EventRecorder,
webhookBootstrapFn func(context.Context, controllerpkg.IssuerSyncFunc) error,
) *Controller {
ctrl := &Controller{client: cl, cmClient: cmClient, issuerFactory: issuerFactory, recorder: recorder}
ctrl.syncHandler = ctrl.processNextWorkItem
Expand All @@ -70,8 +65,6 @@ func New(
ctrl.secretInformerSynced = secretsInformer.Informer().HasSynced
ctrl.secretLister = secretsInformer.Lister()

ctrl.webhookBootstrapFn = webhookBootstrapFn

return ctrl
}

Expand Down Expand Up @@ -107,20 +100,6 @@ func (c *Controller) Run(workers int, stopCh <-chan struct{}) error {
return fmt.Errorf("error waiting for informer caches to sync")
}

// start running the bootstrap function
go func() {
ctx := context.TODO()
for {
err := c.webhookBootstrapFn(ctx, c.sync)
if err == nil {
glog.Infof("Webhook Issuer bootstrap finished")
return
}
glog.Infof("Webhook Issuer bootstrap failed, retrying in 5s: %v", err)
time.Sleep(time.Second * 5)
}
}()

for i := 0; i < workers; i++ {
c.workerWg.Add(1)
// TODO (@munnerz): make time.Second duration configurable
Expand Down Expand Up @@ -209,7 +188,6 @@ func init() {
ctx.CMClient,
ctx.IssuerFactory,
ctx.Recorder,
ctx.SyncWebhookIssuer,
).Run
})
}

0 comments on commit 8a1118e

Please sign in to comment.