Link ingress-shim into main controller binary
This commit is contained in:
parent
b43f294a0a
commit
fdb8f2bf40
@ -124,7 +124,11 @@ func buildControllerContext(opts *options.ControllerOptions) (*controller.Contex
|
||||
ClusterIssuerAmbientCredentials: opts.ClusterIssuerAmbientCredentials,
|
||||
IssuerAmbientCredentials: opts.IssuerAmbientCredentials,
|
||||
}),
|
||||
ClusterResourceNamespace: opts.ClusterResourceNamespace,
|
||||
ClusterResourceNamespace: opts.ClusterResourceNamespace,
|
||||
DefaultIssuerName: opts.DefaultIssuerName,
|
||||
DefaultIssuerKind: opts.DefaultIssuerKind,
|
||||
DefaultACMEIssuerChallengeType: opts.DefaultACMEIssuerChallengeType,
|
||||
DefaultACMEIssuerDNS01ProviderName: opts.DefaultACMEIssuerDNS01ProviderName,
|
||||
}, kubeCfg, nil
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,12 @@ type ControllerOptions struct {
|
||||
|
||||
ClusterIssuerAmbientCredentials bool
|
||||
IssuerAmbientCredentials bool
|
||||
|
||||
// Default issuer/certificates details consumed by ingress-shim
|
||||
DefaultIssuerName string
|
||||
DefaultIssuerKind string
|
||||
DefaultACMEIssuerChallengeType string
|
||||
DefaultACMEIssuerDNS01ProviderName string
|
||||
}
|
||||
|
||||
const (
|
||||
@ -37,6 +43,11 @@ const (
|
||||
|
||||
defaultClusterIssuerAmbientCredentials = true
|
||||
defaultIssuerAmbientCredentials = false
|
||||
|
||||
defaultTLSACMEIssuerName = ""
|
||||
defaultTLSACMEIssuerKind = "Issuer"
|
||||
defaultACMEIssuerChallengeType = "http01"
|
||||
defaultACMEIssuerDNS01ProviderName = ""
|
||||
)
|
||||
|
||||
var (
|
||||
@ -45,15 +56,19 @@ var (
|
||||
|
||||
func NewControllerOptions() *ControllerOptions {
|
||||
return &ControllerOptions{
|
||||
APIServerHost: defaultAPIServerHost,
|
||||
ClusterResourceNamespace: defaultClusterResourceNamespace,
|
||||
LeaderElect: defaultLeaderElect,
|
||||
LeaderElectionNamespace: defaultLeaderElectionNamespace,
|
||||
LeaderElectionLeaseDuration: defaultLeaderElectionLeaseDuration,
|
||||
LeaderElectionRenewDeadline: defaultLeaderElectionRenewDeadline,
|
||||
LeaderElectionRetryPeriod: defaultLeaderElectionRetryPeriod,
|
||||
ClusterIssuerAmbientCredentials: defaultClusterIssuerAmbientCredentials,
|
||||
IssuerAmbientCredentials: defaultIssuerAmbientCredentials,
|
||||
APIServerHost: defaultAPIServerHost,
|
||||
ClusterResourceNamespace: defaultClusterResourceNamespace,
|
||||
LeaderElect: defaultLeaderElect,
|
||||
LeaderElectionNamespace: defaultLeaderElectionNamespace,
|
||||
LeaderElectionLeaseDuration: defaultLeaderElectionLeaseDuration,
|
||||
LeaderElectionRenewDeadline: defaultLeaderElectionRenewDeadline,
|
||||
LeaderElectionRetryPeriod: defaultLeaderElectionRetryPeriod,
|
||||
ClusterIssuerAmbientCredentials: defaultClusterIssuerAmbientCredentials,
|
||||
IssuerAmbientCredentials: defaultIssuerAmbientCredentials,
|
||||
DefaultIssuerName: defaultTLSACMEIssuerName,
|
||||
DefaultIssuerKind: defaultTLSACMEIssuerKind,
|
||||
DefaultACMEIssuerChallengeType: defaultACMEIssuerChallengeType,
|
||||
DefaultACMEIssuerDNS01ProviderName: defaultACMEIssuerDNS01ProviderName,
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,8 +111,23 @@ func (s *ControllerOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
"When this flag is enabled, the following sources for credentials are also used: "+
|
||||
"AWS - All sources the Go SDK defaults to, notably including any EC2 IAM roles available via instance metadata.")
|
||||
|
||||
fs.StringVar(&s.DefaultIssuerName, "default-issuer-name", defaultTLSACMEIssuerName, ""+
|
||||
"Name of the Issuer to use when the tls is requested but issuer name is not specified on the ingress resource.")
|
||||
fs.StringVar(&s.DefaultIssuerKind, "default-issuer-kind", defaultTLSACMEIssuerKind, ""+
|
||||
"Kind of the Issuer to use when the tls is requested but issuer kind is not specified on the ingress resource.")
|
||||
fs.StringVar(&s.DefaultACMEIssuerChallengeType, "default-acme-issuer-challenge-type", defaultACMEIssuerChallengeType, ""+
|
||||
"The ACME challenge type to use when tls is requested for an ACME Issuer but is not specified on the ingress resource.")
|
||||
fs.StringVar(&s.DefaultACMEIssuerDNS01ProviderName, "default-acme-issuer-dns01-provider-name", defaultACMEIssuerDNS01ProviderName, ""+
|
||||
"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.")
|
||||
}
|
||||
|
||||
func (o *ControllerOptions) Validate() error {
|
||||
switch o.DefaultIssuerKind {
|
||||
case "Issuer":
|
||||
case "ClusterIssuer":
|
||||
default:
|
||||
return fmt.Errorf("invalid default issuer kind: %v", o.DefaultIssuerKind)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"github.com/jetstack/cert-manager/cmd/controller/app/options"
|
||||
_ "github.com/jetstack/cert-manager/pkg/controller/certificates"
|
||||
_ "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/issuer/acme"
|
||||
_ "github.com/jetstack/cert-manager/pkg/issuer/ca"
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
# ingress-shim
|
||||
|
||||
This is a small binary that can be run alongside any cert-manager deployment
|
||||
in order to automatically create Certificate resources for Ingresses when a
|
||||
particular annotation is found on an ingress resource.
|
||||
|
||||
This allows users to consume certificates from cert-manager without having to
|
||||
manually create Certificate resources, i.e. in a similar fashion to [kube-lego](https://github.com/jetstack/kube-lego).
|
||||
|
||||
It has been developed outside of the core of cert-manager as it is an
|
||||
experiment to assess the best way to implement this sort of functionality.
|
||||
|
||||
## Project status
|
||||
|
||||
This project is experimental, and thus should not be relied upon in a
|
||||
production environment. This tool may change in backwards incompatible ways.
|
||||
|
||||
In the future, the functionality of this tool may be merged into cert-manager
|
||||
itself to provide a more seamless experience for users.
|
||||
@ -1,158 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"k8s.io/client-go/tools/record"
|
||||
|
||||
"github.com/jetstack/cert-manager/cmd/ingress-shim/controller"
|
||||
"github.com/jetstack/cert-manager/cmd/ingress-shim/options"
|
||||
clientset "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"
|
||||
intscheme "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/scheme"
|
||||
informers "github.com/jetstack/cert-manager/pkg/client/informers/externalversions"
|
||||
"github.com/jetstack/cert-manager/pkg/util/kube"
|
||||
kubeinformers "k8s.io/client-go/informers"
|
||||
)
|
||||
|
||||
const controllerAgentName = "ingress-shim-controller"
|
||||
|
||||
func Run(opts *options.ControllerOptions, stopCh <-chan struct{}) {
|
||||
ctrl, kubeCfg, err := buildController(opts, stopCh)
|
||||
|
||||
if err != nil {
|
||||
glog.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
run := func(_ <-chan struct{}) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
err := ctrl.Run(2, stopCh)
|
||||
if err != nil {
|
||||
glog.Fatalf("error running controller: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
<-stopCh
|
||||
glog.Infof("Waiting for controller to exit...")
|
||||
wg.Wait()
|
||||
glog.Fatalf("Control loops exited")
|
||||
}
|
||||
|
||||
if !opts.LeaderElect {
|
||||
run(stopCh)
|
||||
return
|
||||
}
|
||||
|
||||
leaderElectionClient, err := kubernetes.NewForConfig(rest.AddUserAgent(kubeCfg, "leader-election"))
|
||||
|
||||
if err != nil {
|
||||
glog.Fatalf("error creating leader election client: %s", err.Error())
|
||||
}
|
||||
|
||||
startLeaderElection(opts, leaderElectionClient, ctrl.Recorder, run)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func buildController(opts *options.ControllerOptions, stopCh <-chan struct{}) (*controller.Controller, *rest.Config, error) {
|
||||
// Load the users Kubernetes config
|
||||
kubeCfg, err := kube.KubeConfig(opts.APIServerHost)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating rest config: %s", err.Error())
|
||||
}
|
||||
|
||||
// Create a Navigator api client
|
||||
intcl, err := clientset.NewForConfig(kubeCfg)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating internal group client: %s", err.Error())
|
||||
}
|
||||
|
||||
// Create a Kubernetes api client
|
||||
cl, err := kubernetes.NewForConfig(kubeCfg)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating kubernetes client: %s", err.Error())
|
||||
}
|
||||
|
||||
// Create event broadcaster
|
||||
// Add cert-manager types to the default Kubernetes Scheme so Events can be
|
||||
// logged properly
|
||||
intscheme.AddToScheme(scheme.Scheme)
|
||||
glog.V(4).Info("Creating event broadcaster")
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(glog.V(4).Infof)
|
||||
eventBroadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: cl.CoreV1().Events("")})
|
||||
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: controllerAgentName})
|
||||
|
||||
// We only create SharedInformerFactories for the --namespace specified to
|
||||
// watch. If this namespace is blank (i.e. the default, watch all
|
||||
// namespaces) then the factories will watch all namespaces.
|
||||
// If it is specified, all operations relating to ClusterIssuer resources
|
||||
// should be disabled and thus we don't need to also create factories for
|
||||
// the --cluster-resource-namespace.
|
||||
sharedInformerFactory := informers.NewSharedInformerFactory(intcl, time.Second*30)
|
||||
kubeSharedInformerFactory := kubeinformers.NewSharedInformerFactory(cl, time.Second*30)
|
||||
ctrl := controller.New(
|
||||
sharedInformerFactory.Certmanager().V1alpha1().Certificates(),
|
||||
kubeSharedInformerFactory.Extensions().V1beta1().Ingresses(),
|
||||
sharedInformerFactory.Certmanager().V1alpha1().Issuers(),
|
||||
sharedInformerFactory.Certmanager().V1alpha1().ClusterIssuers(),
|
||||
cl,
|
||||
intcl,
|
||||
recorder,
|
||||
opts,
|
||||
)
|
||||
sharedInformerFactory.Start(stopCh)
|
||||
kubeSharedInformerFactory.Start(stopCh)
|
||||
return ctrl, kubeCfg, nil
|
||||
}
|
||||
|
||||
func startLeaderElection(opts *options.ControllerOptions, leaderElectionClient kubernetes.Interface, recorder record.EventRecorder, run func(<-chan struct{})) {
|
||||
// Identity used to distinguish between multiple controller manager instances
|
||||
id, err := os.Hostname()
|
||||
if err != nil {
|
||||
glog.Fatalf("error getting hostname: %s", err.Error())
|
||||
}
|
||||
|
||||
// Lock required for leader election
|
||||
rl := resourcelock.ConfigMapLock{
|
||||
ConfigMapMeta: metav1.ObjectMeta{
|
||||
Namespace: opts.LeaderElectionNamespace,
|
||||
Name: "ingress-shim-controller",
|
||||
},
|
||||
Client: leaderElectionClient.CoreV1(),
|
||||
LockConfig: resourcelock.ResourceLockConfig{
|
||||
Identity: id + "-external-ingress-shim-controller",
|
||||
EventRecorder: recorder,
|
||||
},
|
||||
}
|
||||
|
||||
// Try and become the leader and start controller manager loops
|
||||
leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{
|
||||
Lock: &rl,
|
||||
LeaseDuration: opts.LeaderElectionLeaseDuration,
|
||||
RenewDeadline: opts.LeaderElectionRenewDeadline,
|
||||
RetryPeriod: opts.LeaderElectionRetryPeriod,
|
||||
Callbacks: leaderelection.LeaderCallbacks{
|
||||
OnStartedLeading: run,
|
||||
OnStoppedLeading: func() {
|
||||
glog.Fatalf("leaderelection lost")
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"github.com/jetstack/cert-manager/pkg/logs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logs.InitLogs()
|
||||
defer logs.FlushLogs()
|
||||
stopCh := SetupSignalHandler()
|
||||
|
||||
cmd := NewCommandStartController(stopCh)
|
||||
cmd.Flags().AddGoFlagSet(flag.CommandLine)
|
||||
flag.CommandLine.Parse([]string{})
|
||||
if err := cmd.Execute(); err != nil {
|
||||
glog.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM}
|
||||
var onlyOneSignalHandler = make(chan struct{})
|
||||
|
||||
// SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned
|
||||
// which is closed on one of these signals. If a second signal is caught, the program
|
||||
// is terminated with exit code 1.
|
||||
func SetupSignalHandler() (stopCh <-chan struct{}) {
|
||||
close(onlyOneSignalHandler) // panics when called twice
|
||||
|
||||
stop := make(chan struct{})
|
||||
c := make(chan os.Signal, 2)
|
||||
signal.Notify(c, shutdownSignals...)
|
||||
go func() {
|
||||
<-c
|
||||
close(stop)
|
||||
<-c
|
||||
os.Exit(1) // second signal. Exit directly.
|
||||
}()
|
||||
|
||||
return stop
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
type ControllerOptions struct {
|
||||
APIServerHost string
|
||||
|
||||
LeaderElect bool
|
||||
LeaderElectionNamespace string
|
||||
LeaderElectionLeaseDuration time.Duration
|
||||
LeaderElectionRenewDeadline time.Duration
|
||||
LeaderElectionRetryPeriod time.Duration
|
||||
|
||||
DefaultIssuerName string
|
||||
DefaultIssuerKind string
|
||||
DefaultACMEIssuerChallengeType string
|
||||
DefaultACMEIssuerDNS01ProviderName string
|
||||
}
|
||||
|
||||
const (
|
||||
defaultAPIServerHost = ""
|
||||
|
||||
defaultLeaderElect = true
|
||||
defaultLeaderElectionNamespace = "kube-system"
|
||||
defaultLeaderElectionLeaseDuration = 15 * time.Second
|
||||
defaultLeaderElectionRenewDeadline = 10 * time.Second
|
||||
defaultLeaderElectionRetryPeriod = 2 * time.Second
|
||||
|
||||
defaultTLSACMEIssuerName = ""
|
||||
defaultTLSACMEIssuerKind = "Issuer"
|
||||
defaultACMEIssuerChallengeType = "http01"
|
||||
defaultACMEIssuerDNS01ProviderName = ""
|
||||
)
|
||||
|
||||
func NewControllerOptions() *ControllerOptions {
|
||||
return &ControllerOptions{
|
||||
APIServerHost: defaultAPIServerHost,
|
||||
LeaderElect: defaultLeaderElect,
|
||||
LeaderElectionNamespace: defaultLeaderElectionNamespace,
|
||||
LeaderElectionLeaseDuration: defaultLeaderElectionLeaseDuration,
|
||||
LeaderElectionRenewDeadline: defaultLeaderElectionRenewDeadline,
|
||||
LeaderElectionRetryPeriod: defaultLeaderElectionRetryPeriod,
|
||||
DefaultIssuerName: defaultTLSACMEIssuerName,
|
||||
DefaultIssuerKind: defaultTLSACMEIssuerKind,
|
||||
DefaultACMEIssuerChallengeType: defaultACMEIssuerChallengeType,
|
||||
DefaultACMEIssuerDNS01ProviderName: defaultACMEIssuerDNS01ProviderName,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ControllerOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&s.APIServerHost, "master", defaultAPIServerHost, ""+
|
||||
"Optional apiserver host address to connect to. If not specified, autoconfiguration "+
|
||||
"will be attempted.")
|
||||
fs.BoolVar(&s.LeaderElect, "leader-elect", true, ""+
|
||||
"If true, ingress-annotation-controller will perform leader election between instances to ensure no more "+
|
||||
"than one instance of cert-manager operates at a time.")
|
||||
fs.StringVar(&s.LeaderElectionNamespace, "leader-election-namespace", defaultLeaderElectionNamespace, ""+
|
||||
"Namespace used to perform leader election. Only used if leader election is enabled.")
|
||||
fs.DurationVar(&s.LeaderElectionLeaseDuration, "leader-election-lease-duration", defaultLeaderElectionLeaseDuration, ""+
|
||||
"The duration that non-leader candidates will wait after observing a leadership "+
|
||||
"renewal until attempting to acquire leadership of a led but unrenewed leader "+
|
||||
"slot. This is effectively the maximum duration that a leader can be stopped "+
|
||||
"before it is replaced by another candidate. This is only applicable if leader "+
|
||||
"election is enabled.")
|
||||
fs.DurationVar(&s.LeaderElectionRenewDeadline, "leader-election-renew-deadline", defaultLeaderElectionRenewDeadline, ""+
|
||||
"The interval between attempts by the acting master to renew a leadership slot "+
|
||||
"before it stops leading. This must be less than or equal to the lease duration. "+
|
||||
"This is only applicable if leader election is enabled.")
|
||||
fs.DurationVar(&s.LeaderElectionRetryPeriod, "leader-election-retry-period", defaultLeaderElectionRetryPeriod, ""+
|
||||
"The duration the clients should wait between attempting acquisition and renewal "+
|
||||
"of a leadership. This is only applicable if leader election is enabled.")
|
||||
|
||||
fs.StringVar(&s.DefaultIssuerName, "default-issuer-name", defaultTLSACMEIssuerName, ""+
|
||||
"Name of the Issuer to use when the tls is requested but issuer name is not specified on the ingress resource.")
|
||||
fs.StringVar(&s.DefaultIssuerKind, "default-issuer-kind", defaultTLSACMEIssuerKind, ""+
|
||||
"Kind of the Issuer to use when the tls is requested but issuer kind is not specified on the ingress resource.")
|
||||
fs.StringVar(&s.DefaultACMEIssuerChallengeType, "default-acme-issuer-challenge-type", defaultACMEIssuerChallengeType, ""+
|
||||
"The ACME challenge type to use when tls is requested for an ACME Issuer but is not specified on the ingress resource.")
|
||||
fs.StringVar(&s.DefaultACMEIssuerDNS01ProviderName, "default-acme-issuer-dns01-provider-name", defaultACMEIssuerDNS01ProviderName, ""+
|
||||
"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.")
|
||||
}
|
||||
|
||||
func (o *ControllerOptions) Validate() error {
|
||||
var errs []error
|
||||
|
||||
switch o.DefaultACMEIssuerChallengeType {
|
||||
case "dns01", "http01", "":
|
||||
default:
|
||||
errs = append(errs, fmt.Errorf("--default-acme-issuer-challenge-type must be one of 'http01', 'dns01' or not set"))
|
||||
}
|
||||
|
||||
if o.DefaultACMEIssuerChallengeType == "dns01" {
|
||||
if o.DefaultACMEIssuerDNS01ProviderName == "" {
|
||||
errs = append(errs, fmt.Errorf("--default-acme-issuer-dns01-provider-name must be set when --default-acme-issuer-challenge-type is set to dns01"))
|
||||
}
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
|
||||
"github.com/jetstack/cert-manager/cmd/ingress-shim/options"
|
||||
"github.com/jetstack/cert-manager/pkg/util"
|
||||
)
|
||||
|
||||
// NewCommandStartController is a CLI handler for starting ingress-shim-controller
|
||||
func NewCommandStartController(stopCh <-chan struct{}) *cobra.Command {
|
||||
o := options.NewControllerOptions()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "ingress-shim-controller",
|
||||
Short: fmt.Sprintf("Automate creation of Certificate resources for Ingress (%s) (%s)", util.AppVersion, util.AppGitCommit),
|
||||
Long: `
|
||||
This is a small binary that can be run alongside any cert-manager deployment
|
||||
in order to automatically create Certificate resources for Ingresses when a
|
||||
particular annotation is found on an ingress resource.
|
||||
|
||||
This allows users to consume certificates from cert-manager without having to
|
||||
manually create Certificate resources`,
|
||||
|
||||
// TODO: Refactor this function from this package
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := o.Validate(); err != nil {
|
||||
glog.Fatalf("error validating options: %s", err.Error())
|
||||
}
|
||||
Run(o, stopCh)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
o.AddFlags(flags)
|
||||
|
||||
return cmd
|
||||
}
|
||||
@ -35,4 +35,10 @@ type Context struct {
|
||||
// ClusterResourceNamespace is the namespace to store resources created by
|
||||
// non-namespaced resources (e.g. ClusterIssuer) in.
|
||||
ClusterResourceNamespace string
|
||||
|
||||
// Default issuer/certificates details consumed by ingress-shim
|
||||
DefaultIssuerName string
|
||||
DefaultIssuerKind string
|
||||
DefaultACMEIssuerChallengeType string
|
||||
DefaultACMEIssuerDNS01ProviderName string
|
||||
}
|
||||
|
||||
@ -16,7 +16,6 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
|
||||
"github.com/jetstack/cert-manager/cmd/ingress-shim/options"
|
||||
cmv1alpha1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
|
||||
clientset "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"
|
||||
cminformers "github.com/jetstack/cert-manager/pkg/client/informers/externalversions/certmanager/v1alpha1"
|
||||
@ -30,6 +29,12 @@ const (
|
||||
ControllerName = "ingress-shim"
|
||||
)
|
||||
|
||||
type defaults struct {
|
||||
issuerName, issuerKind string
|
||||
acmeIssuerChallengeType string
|
||||
acmeIssuerDNS01ProviderName string
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
Client kubernetes.Interface
|
||||
CMClient clientset.Interface
|
||||
@ -46,7 +51,7 @@ type Controller struct {
|
||||
queue workqueue.RateLimitingInterface
|
||||
workerWg sync.WaitGroup
|
||||
syncedFuncs []cache.InformerSynced
|
||||
options *options.ControllerOptions
|
||||
defaults defaults
|
||||
}
|
||||
|
||||
// New returns a new Certificates controller. It sets up the informer handler
|
||||
@ -59,9 +64,9 @@ func New(
|
||||
client kubernetes.Interface,
|
||||
cmClient clientset.Interface,
|
||||
recorder record.EventRecorder,
|
||||
options *options.ControllerOptions,
|
||||
defaults defaults,
|
||||
) *Controller {
|
||||
ctrl := &Controller{Client: client, CMClient: cmClient, Recorder: recorder, options: options}
|
||||
ctrl := &Controller{Client: client, CMClient: cmClient, Recorder: recorder, defaults: defaults}
|
||||
ctrl.syncHandler = ctrl.processNextWorkItem
|
||||
ctrl.queue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "ingresses")
|
||||
|
||||
@ -183,3 +188,20 @@ func (c *Controller) processNextWorkItem(ctx context.Context, key string) error
|
||||
|
||||
return c.Sync(ctx, crt)
|
||||
}
|
||||
|
||||
var keyFunc = controllerpkg.KeyFunc
|
||||
|
||||
func init() {
|
||||
controllerpkg.Register(ControllerName, func(ctx *controllerpkg.Context) controllerpkg.Interface {
|
||||
return New(
|
||||
ctx.SharedInformerFactory.Certmanager().V1alpha1().Certificates(),
|
||||
ctx.KubeSharedInformerFactory.Extensions().V1beta1().Ingresses(),
|
||||
ctx.SharedInformerFactory.Certmanager().V1alpha1().Issuers(),
|
||||
ctx.SharedInformerFactory.Certmanager().V1alpha1().ClusterIssuers(),
|
||||
ctx.Client,
|
||||
ctx.CMClient,
|
||||
ctx.Recorder,
|
||||
defaults{ctx.DefaultIssuerName, ctx.DefaultIssuerKind, ctx.DefaultACMEIssuerChallengeType, ctx.DefaultACMEIssuerDNS01ProviderName},
|
||||
).Run
|
||||
})
|
||||
}
|
||||
@ -181,7 +181,7 @@ func (c *Controller) setIssuerSpecificConfig(crt *v1alpha1.Certificate, issuer v
|
||||
if issuer.GetSpec().ACME != nil {
|
||||
challengeType, ok := ingAnnotations[acmeIssuerChallengeTypeAnnotation]
|
||||
if !ok {
|
||||
challengeType = c.options.DefaultACMEIssuerChallengeType
|
||||
challengeType = c.defaults.acmeIssuerChallengeType
|
||||
}
|
||||
domainCfg := v1alpha1.ACMECertificateDomainConfig{
|
||||
Domains: tls.Hosts,
|
||||
@ -202,7 +202,7 @@ func (c *Controller) setIssuerSpecificConfig(crt *v1alpha1.Certificate, issuer v
|
||||
case "dns01":
|
||||
dnsProvider, ok := ingAnnotations[acmeIssuerDNS01ProviderNameAnnotation]
|
||||
if !ok {
|
||||
dnsProvider = c.options.DefaultACMEIssuerDNS01ProviderName
|
||||
dnsProvider = c.defaults.acmeIssuerDNS01ProviderName
|
||||
}
|
||||
if dnsProvider == "" {
|
||||
return fmt.Errorf("no acme issuer dns01 challenge provider specified")
|
||||
@ -247,8 +247,8 @@ func shouldSync(ing *extv1beta1.Ingress) bool {
|
||||
// Certificate created for the given Ingress resource. If one is not set, the
|
||||
// default issuer given to the controller will be used.
|
||||
func (c *Controller) issuerForIngress(ing *extv1beta1.Ingress) (name string, kind string) {
|
||||
name = c.options.DefaultIssuerName
|
||||
kind = c.options.DefaultIssuerKind
|
||||
name = c.defaults.issuerName
|
||||
kind = c.defaults.issuerKind
|
||||
annotations := ing.Annotations
|
||||
if annotations == nil {
|
||||
annotations = map[string]string{}
|
||||
Loading…
Reference in New Issue
Block a user