mirror of
https://github.com/wahyd4/cert-manager.git
synced 2026-08-09 05:06:38 +10:00
Merge pull request #4546 from munnerz/webhook-config-api
Support loading webhook config from versioned file
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
@@ -8,17 +8,21 @@ go_library(
|
||||
deps = [
|
||||
"//cmd/util:go_default_library",
|
||||
"//cmd/webhook/app/options:go_default_library",
|
||||
"//internal/apis/config/webhook:go_default_library",
|
||||
"//pkg/logs:go_default_library",
|
||||
"//pkg/util:go_default_library",
|
||||
"//pkg/webhook:go_default_library",
|
||||
"//pkg/webhook/authority:go_default_library",
|
||||
"//pkg/webhook/configfile:go_default_library",
|
||||
"//pkg/webhook/handlers:go_default_library",
|
||||
"//pkg/webhook/server:go_default_library",
|
||||
"//pkg/webhook/server/tls:go_default_library",
|
||||
"@com_github_go_logr_logr//:go_default_library",
|
||||
"@com_github_spf13_cobra//:go_default_library",
|
||||
"@com_github_spf13_pflag//:go_default_library",
|
||||
"@io_k8s_client_go//kubernetes:go_default_library",
|
||||
"@io_k8s_client_go//tools/clientcmd:go_default_library",
|
||||
"@io_k8s_component_base//cli/flag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -39,3 +43,10 @@ filegroup(
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["webhook_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//cmd/webhook/app/options:go_default_library"],
|
||||
)
|
||||
|
||||
@@ -2,11 +2,17 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["options.go"],
|
||||
srcs = [
|
||||
"globalflags.go",
|
||||
"options.go",
|
||||
],
|
||||
importpath = "github.com/jetstack/cert-manager/cmd/webhook/app/options",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//cmd/util:go_default_library",
|
||||
"//internal/apis/config/webhook:go_default_library",
|
||||
"//internal/apis/config/webhook/scheme:go_default_library",
|
||||
"//pkg/apis/config/webhook/v1alpha1:go_default_library",
|
||||
"//pkg/logs:go_default_library",
|
||||
"@com_github_spf13_pflag//:go_default_library",
|
||||
"@io_k8s_component_base//cli/flag:go_default_library",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/jetstack/cert-manager/pkg/logs"
|
||||
)
|
||||
|
||||
func AddGlobalFlags(fs *pflag.FlagSet) {
|
||||
addKlogFlags(fs)
|
||||
}
|
||||
|
||||
func addKlogFlags(fs *pflag.FlagSet) {
|
||||
local := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
|
||||
logs.InitLogs(local)
|
||||
fs.AddGoFlagSet(local)
|
||||
}
|
||||
@@ -22,97 +22,71 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
|
||||
cmdutil "github.com/jetstack/cert-manager/cmd/util"
|
||||
config "github.com/jetstack/cert-manager/internal/apis/config/webhook"
|
||||
configscheme "github.com/jetstack/cert-manager/internal/apis/config/webhook/scheme"
|
||||
configv1alpha1 "github.com/jetstack/cert-manager/pkg/apis/config/webhook/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
// Default port on which /validate, /mutate, /convert endpoints will be served
|
||||
defaultListeningPort = 6443
|
||||
// Default health check port
|
||||
defaultHealthPort = 6080
|
||||
)
|
||||
|
||||
type WebhookOptions struct {
|
||||
ListenPort int
|
||||
HealthzPort int
|
||||
|
||||
// Path to TLS certificate and private key on disk.
|
||||
// Both must be specified if either is.
|
||||
// May not be specified if DynamicServingCASecretNamespace and
|
||||
// DynamicServingCASecretName are set.
|
||||
TLSCertFile string
|
||||
TLSKeyFile string
|
||||
|
||||
// Namespace and name of the Secret resource containing the TLS certificate
|
||||
// used as a CA to sign dynamic serving certificates.
|
||||
// Both must be specified if either is.
|
||||
// May not be specified if TLSCertFile and TLSKeyFile are set.
|
||||
DynamicServingCASecretNamespace string
|
||||
DynamicServingCASecretName string
|
||||
// List of DNSNames that must be present on serving certificates.
|
||||
DynamicServingDNSNames []string
|
||||
|
||||
// Optional path to the kubeconfig used to connect to the apiserver when
|
||||
// using the 'dynamic serving' certificate sources.
|
||||
// If not specified, in cluster config will be used.
|
||||
Kubeconfig string
|
||||
APIServerHost string
|
||||
|
||||
// TLSCipherSuites is the list of allowed cipher suites for the server.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
TLSCipherSuites []string
|
||||
|
||||
// MinTLSVersion is the minimum TLS version supported.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
MinTLSVersion string
|
||||
|
||||
// EnablePprof determines whether pprof is enabled.
|
||||
EnablePprof bool
|
||||
|
||||
// Address on which /debug/pprof endpoint will be served if enabled. Default is
|
||||
// localhost:6060.
|
||||
PprofAddress string
|
||||
// WebhookFlags defines options that can only be configured via flags.
|
||||
type WebhookFlags struct {
|
||||
// Path to a file containing a WebhookConfiguration resource
|
||||
Config string
|
||||
}
|
||||
|
||||
func (o *WebhookOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
// TODO: rename secure-port to listen-port
|
||||
fs.IntVar(&o.ListenPort, "secure-port", defaultListeningPort, "port number to listen on for secure TLS connections")
|
||||
fs.IntVar(&o.HealthzPort, "healthz-port", defaultHealthPort, "port number to listen on for insecure healthz connections")
|
||||
fs.StringVar(&o.TLSCertFile, "tls-cert-file", "", "path to the file containing the TLS certificate to serve with")
|
||||
fs.StringVar(&o.TLSKeyFile, "tls-private-key-file", "", "path to the file containing the TLS private key to serve with")
|
||||
fs.StringVar(&o.DynamicServingCASecretNamespace, "dynamic-serving-ca-secret-namespace", "", "namespace of the secret used to store the CA that signs serving certificates")
|
||||
fs.StringVar(&o.DynamicServingCASecretName, "dynamic-serving-ca-secret-name", "", "name of the secret used to store the CA that signs serving certificates certificates")
|
||||
fs.StringSliceVar(&o.DynamicServingDNSNames, "dynamic-serving-dns-names", []string{""}, "DNS names that should be present on certificates generated by the dynamic serving CA")
|
||||
fs.StringVar(&o.Kubeconfig, "kubeconfig", "", "optional path to the kubeconfig used to connect to the apiserver. If not specified, in-cluster-config will be used")
|
||||
fs.StringVar(&o.APIServerHost, "api-server-host", "", ""+
|
||||
func NewWebhookFlags() *WebhookFlags {
|
||||
return &WebhookFlags{}
|
||||
}
|
||||
|
||||
func (f *WebhookFlags) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&f.Config, "config", "", "Path to a file containing a WebhookConfiguration object used to configure the webhook")
|
||||
}
|
||||
|
||||
func ValidateWebhookFlags(f *WebhookFlags) error {
|
||||
// No validation needed today
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewWebhookConfiguration() (*config.WebhookConfiguration, error) {
|
||||
scheme, _, err := configscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
versioned := &configv1alpha1.WebhookConfiguration{}
|
||||
scheme.Default(versioned)
|
||||
config := &config.WebhookConfiguration{}
|
||||
if err := scheme.Convert(versioned, config, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func AddConfigFlags(fs *pflag.FlagSet, c *config.WebhookConfiguration) {
|
||||
fs.IntVar(c.SecurePort, "secure-port", *c.SecurePort, "port number to listen on for secure TLS connections")
|
||||
fs.IntVar(c.HealthzPort, "healthz-port", *c.HealthzPort, "port number to listen on for insecure healthz connections")
|
||||
|
||||
fs.StringVar(&c.TLSConfig.Filesystem.CertFile, "tls-cert-file", c.TLSConfig.Filesystem.CertFile, "path to the file containing the TLS certificate to serve with")
|
||||
fs.StringVar(&c.TLSConfig.Filesystem.KeyFile, "tls-private-key-file", c.TLSConfig.Filesystem.KeyFile, "path to the file containing the TLS private key to serve with")
|
||||
|
||||
fs.StringVar(&c.TLSConfig.Dynamic.SecretNamespace, "dynamic-serving-ca-secret-namespace", c.TLSConfig.Dynamic.SecretNamespace, "namespace of the secret used to store the CA that signs serving certificates")
|
||||
fs.StringVar(&c.TLSConfig.Dynamic.SecretName, "dynamic-serving-ca-secret-name", c.TLSConfig.Dynamic.SecretName, "name of the secret used to store the CA that signs serving certificates certificates")
|
||||
fs.StringSliceVar(&c.TLSConfig.Dynamic.DNSNames, "dynamic-serving-dns-names", c.TLSConfig.Dynamic.DNSNames, "DNS names that should be present on certificates generated by the dynamic serving CA")
|
||||
|
||||
fs.StringVar(&c.KubeConfig, "kubeconfig", c.KubeConfig, "optional path to the kubeconfig used to connect to the apiserver. If not specified, in-cluster-config will be used")
|
||||
fs.StringVar(&c.APIServerHost, "api-server-host", c.APIServerHost, ""+
|
||||
"Optional apiserver host address to connect to. If not specified, autoconfiguration "+
|
||||
"will be attempted.")
|
||||
fs.BoolVar(&o.EnablePprof, "enable-profiling", cmdutil.DefaultEnableProfiling, ""+
|
||||
fs.BoolVar(&c.EnablePprof, "enable-profiling", c.EnablePprof, ""+
|
||||
"Enable profiling for controller.")
|
||||
fs.StringVar(&o.PprofAddress, "profiler-address", cmdutil.DefaultProfilerAddr,
|
||||
fs.StringVar(&c.PprofAddress, "profiler-address", c.PprofAddress,
|
||||
"Address of the Go profiler (pprof). This should never be exposed on a public interface. If this flag is not set, the profiler is not run.")
|
||||
tlsCipherPossibleValues := cliflag.TLSCipherPossibleValues()
|
||||
fs.StringSliceVar(&o.TLSCipherSuites, "tls-cipher-suites", o.TLSCipherSuites,
|
||||
fs.StringSliceVar(&c.TLSConfig.CipherSuites, "tls-cipher-suites", c.TLSConfig.CipherSuites,
|
||||
"Comma-separated list of cipher suites for the server. "+
|
||||
"If omitted, the default Go cipher suites will be use. "+
|
||||
"Possible values: "+strings.Join(tlsCipherPossibleValues, ","))
|
||||
tlsPossibleVersions := cliflag.TLSPossibleVersions()
|
||||
fs.StringVar(&o.MinTLSVersion, "tls-min-version", o.MinTLSVersion,
|
||||
fs.StringVar(&c.TLSConfig.MinTLSVersion, "tls-min-version", c.TLSConfig.MinTLSVersion,
|
||||
"Minimum TLS version supported. "+
|
||||
"Possible values: "+strings.Join(tlsPossibleVersions, ", "))
|
||||
|
||||
}
|
||||
|
||||
func FileTLSSourceEnabled(o WebhookOptions) bool {
|
||||
if o.TLSCertFile != "" || o.TLSKeyFile != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func DynamicTLSSourceEnabled(o WebhookOptions) bool {
|
||||
if o.DynamicServingCASecretNamespace != "" || o.DynamicServingCASecretName != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ go_library(
|
||||
"//pkg/webhook/server:go_default_library",
|
||||
"@com_github_spf13_pflag//:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/util/wait:go_default_library",
|
||||
"@io_k8s_utils//pointer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/jetstack/cert-manager/cmd/webhook/app"
|
||||
"github.com/jetstack/cert-manager/cmd/webhook/app/options"
|
||||
@@ -58,10 +59,14 @@ type ServerOptions struct {
|
||||
}
|
||||
|
||||
func StartWebhookServer(t *testing.T, ctx context.Context, args []string) (ServerOptions, StopFunc) {
|
||||
// Allow user to override options using flags
|
||||
var opts options.WebhookOptions
|
||||
fs := pflag.NewFlagSet("testset", pflag.ExitOnError)
|
||||
opts.AddFlags(fs)
|
||||
webhookFlags := options.NewWebhookFlags()
|
||||
webhookConfig, err := options.NewWebhookConfiguration()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed building test webhook config: %v", err)
|
||||
}
|
||||
webhookFlags.AddFlags(fs)
|
||||
options.AddConfigFlags(fs, webhookConfig)
|
||||
// Parse the arguments passed in into the WebhookOptions struct
|
||||
fs.Parse(args)
|
||||
|
||||
@@ -70,7 +75,7 @@ func StartWebhookServer(t *testing.T, ctx context.Context, args []string) (Serve
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !options.FileTLSSourceEnabled(opts) && !options.DynamicTLSSourceEnabled(opts) {
|
||||
if !webhookConfig.TLSConfig.FilesystemConfigProvided() && !webhookConfig.TLSConfig.DynamicConfigProvided() {
|
||||
// Generate a CA and serving certificate
|
||||
ca, certificatePEM, privateKeyPEM, err := generateTLSAssets()
|
||||
if err != nil {
|
||||
@@ -85,17 +90,17 @@ func StartWebhookServer(t *testing.T, ctx context.Context, args []string) (Serve
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
opts.TLSKeyFile = filepath.Join(tempDir, "tls.key")
|
||||
opts.TLSCertFile = filepath.Join(tempDir, "tls.crt")
|
||||
webhookConfig.TLSConfig.Filesystem.KeyFile = filepath.Join(tempDir, "tls.key")
|
||||
webhookConfig.TLSConfig.Filesystem.CertFile = filepath.Join(tempDir, "tls.crt")
|
||||
}
|
||||
|
||||
// Listen on a random port number
|
||||
opts.ListenPort = 0
|
||||
opts.HealthzPort = 0
|
||||
webhookConfig.SecurePort = pointer.Int(0)
|
||||
webhookConfig.HealthzPort = pointer.Int(0)
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
errCh := make(chan error)
|
||||
srv, err := app.NewServerWithOptions(log, opts)
|
||||
srv, err := app.NewServerWithOptions(log, *webhookFlags, *webhookConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
+172
-30
@@ -19,18 +19,24 @@ package app
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
|
||||
cmdutil "github.com/jetstack/cert-manager/cmd/util"
|
||||
"github.com/jetstack/cert-manager/cmd/webhook/app/options"
|
||||
config "github.com/jetstack/cert-manager/internal/apis/config/webhook"
|
||||
logf "github.com/jetstack/cert-manager/pkg/logs"
|
||||
"github.com/jetstack/cert-manager/pkg/util"
|
||||
"github.com/jetstack/cert-manager/pkg/webhook"
|
||||
"github.com/jetstack/cert-manager/pkg/webhook/authority"
|
||||
"github.com/jetstack/cert-manager/pkg/webhook/configfile"
|
||||
"github.com/jetstack/cert-manager/pkg/webhook/handlers"
|
||||
"github.com/jetstack/cert-manager/pkg/webhook/server"
|
||||
"github.com/jetstack/cert-manager/pkg/webhook/server/tls"
|
||||
@@ -40,8 +46,8 @@ var validationHook handlers.ValidatingAdmissionHook = handlers.NewRegistryBacked
|
||||
var mutationHook handlers.MutatingAdmissionHook = handlers.NewRegistryBackedMutator(logf.Log, webhook.Scheme, webhook.MutationRegistry)
|
||||
var conversionHook handlers.ConversionHook = handlers.NewSchemeBackedConverter(logf.Log, webhook.Scheme)
|
||||
|
||||
func NewServerWithOptions(log logr.Logger, opts options.WebhookOptions) (*server.Server, error) {
|
||||
restcfg, err := clientcmd.BuildConfigFromFlags(opts.APIServerHost, opts.Kubeconfig)
|
||||
func NewServerWithOptions(log logr.Logger, _ options.WebhookFlags, opts config.WebhookConfiguration) (*server.Server, error) {
|
||||
restcfg, err := clientcmd.BuildConfigFromFlags(opts.APIServerHost, opts.KubeConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -54,25 +60,25 @@ func NewServerWithOptions(log logr.Logger, opts options.WebhookOptions) (*server
|
||||
|
||||
var source tls.CertificateSource
|
||||
switch {
|
||||
case options.FileTLSSourceEnabled(opts):
|
||||
log.V(logf.InfoLevel).Info("using TLS certificate from local filesystem", "private_key_path", opts.TLSKeyFile, "certificate", opts.TLSCertFile)
|
||||
case opts.TLSConfig.FilesystemConfigProvided():
|
||||
log.V(logf.InfoLevel).Info("using TLS certificate from local filesystem", "private_key_path", opts.TLSConfig.Filesystem.KeyFile, "certificate", opts.TLSConfig.Filesystem.CertFile)
|
||||
source = &tls.FileCertificateSource{
|
||||
CertPath: opts.TLSCertFile,
|
||||
KeyPath: opts.TLSKeyFile,
|
||||
CertPath: opts.TLSConfig.Filesystem.CertFile,
|
||||
KeyPath: opts.TLSConfig.Filesystem.KeyFile,
|
||||
Log: log,
|
||||
}
|
||||
case options.DynamicTLSSourceEnabled(opts):
|
||||
restcfg, err := clientcmd.BuildConfigFromFlags("", opts.Kubeconfig)
|
||||
case opts.TLSConfig.DynamicConfigProvided():
|
||||
restcfg, err := clientcmd.BuildConfigFromFlags("", opts.KubeConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.V(logf.InfoLevel).Info("using dynamic certificate generating using CA stored in Secret resource", "secret_namespace", opts.DynamicServingCASecretNamespace, "secret_name", opts.DynamicServingCASecretName)
|
||||
log.V(logf.InfoLevel).Info("using dynamic certificate generating using CA stored in Secret resource", "secret_namespace", opts.TLSConfig.Dynamic.SecretNamespace, "secret_name", opts.TLSConfig.Dynamic.SecretName)
|
||||
source = &tls.DynamicSource{
|
||||
DNSNames: opts.DynamicServingDNSNames,
|
||||
DNSNames: opts.TLSConfig.Dynamic.DNSNames,
|
||||
Authority: &authority.DynamicAuthority{
|
||||
SecretNamespace: opts.DynamicServingCASecretNamespace,
|
||||
SecretName: opts.DynamicServingCASecretName,
|
||||
SecretNamespace: opts.TLSConfig.Dynamic.SecretNamespace,
|
||||
SecretName: opts.TLSConfig.Dynamic.SecretName,
|
||||
RESTConfig: restcfg,
|
||||
Log: log,
|
||||
},
|
||||
@@ -83,13 +89,13 @@ func NewServerWithOptions(log logr.Logger, opts options.WebhookOptions) (*server
|
||||
}
|
||||
|
||||
return &server.Server{
|
||||
ListenAddr: fmt.Sprintf(":%d", opts.ListenPort),
|
||||
HealthzAddr: fmt.Sprintf(":%d", opts.HealthzPort),
|
||||
PprofAddr: opts.PprofAddress,
|
||||
ListenAddr: fmt.Sprintf(":%d", *opts.SecurePort),
|
||||
HealthzAddr: fmt.Sprintf(":%d", *opts.HealthzPort),
|
||||
EnablePprof: opts.EnablePprof,
|
||||
PprofAddr: opts.PprofAddress,
|
||||
CertificateSource: source,
|
||||
CipherSuites: opts.TLSCipherSuites,
|
||||
MinTLSVersion: opts.MinTLSVersion,
|
||||
CipherSuites: opts.TLSConfig.CipherSuites,
|
||||
MinTLSVersion: opts.TLSConfig.MinTLSVersion,
|
||||
ValidationWebhook: validationHook,
|
||||
MutationWebhook: mutationHook,
|
||||
ConversionWebhook: conversionHook,
|
||||
@@ -97,27 +103,163 @@ func NewServerWithOptions(log logr.Logger, opts options.WebhookOptions) (*server
|
||||
}, nil
|
||||
}
|
||||
|
||||
const componentWebhook = "webhook"
|
||||
|
||||
func NewServerCommand(stopCh <-chan struct{}) *cobra.Command {
|
||||
var opts options.WebhookOptions
|
||||
ctx := cmdutil.ContextWithStopCh(context.Background(), stopCh)
|
||||
ctx = logf.NewContext(ctx, nil, "webhook")
|
||||
log := logf.FromContext(ctx)
|
||||
|
||||
cleanFlagSet := pflag.NewFlagSet(componentWebhook, pflag.ContinueOnError)
|
||||
// Replaces all instances of `_` in flag names with `-`
|
||||
cleanFlagSet.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
|
||||
webhookFlags := options.NewWebhookFlags()
|
||||
webhookConfig, err := options.NewWebhookConfiguration()
|
||||
if err != nil {
|
||||
log.Error(err, "Failed to create new webhook configuration")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "webhook",
|
||||
Short: fmt.Sprintf("Webhook component providing API validation, mutation and conversion functionality for cert-manager (%s) (%s)", util.AppVersion, util.AppGitCommit),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmdutil.ContextWithStopCh(context.Background(), stopCh)
|
||||
ctx = logf.NewContext(ctx, nil, "webhook")
|
||||
log := logf.FromContext(ctx)
|
||||
|
||||
srv, err := NewServerWithOptions(log, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
Use: componentWebhook,
|
||||
Long: fmt.Sprintf("Webhook component providing API validation, mutation and conversion functionality for cert-manager (%s) (%s)", util.AppVersion, util.AppGitCommit),
|
||||
// The webhook has special flag parsing requirements to handle precedence of providing
|
||||
// configuration via versioned configuration files and flag values.
|
||||
// Setting DisableFlagParsing=true prevents Cobra from interfering with flag parsing
|
||||
// at all, and instead we handle it all in the RunE below.
|
||||
DisableFlagParsing: true,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// initial flag parse, since we disable cobra's flag parsing
|
||||
if err := cleanFlagSet.Parse(args); err != nil {
|
||||
log.Error(err, "Failed to parse webhook flag")
|
||||
cmd.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return srv.Run(stopCh)
|
||||
// check if there are non-flag arguments in the command line
|
||||
cmds := cleanFlagSet.Args()
|
||||
if len(cmds) > 0 {
|
||||
log.Error(nil, "Unknown command", "command", cmds[0])
|
||||
cmd.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// short-circuit on help
|
||||
help, err := cleanFlagSet.GetBool("help")
|
||||
if err != nil {
|
||||
log.Info(`"help" flag is non-bool, programmer error, please correct`)
|
||||
os.Exit(1)
|
||||
}
|
||||
if help {
|
||||
cmd.Help()
|
||||
return
|
||||
}
|
||||
|
||||
if err := options.ValidateWebhookFlags(webhookFlags); err != nil {
|
||||
log.Error(err, "Failed to validate webhook flags")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if configFile := webhookFlags.Config; len(configFile) > 0 {
|
||||
webhookConfig, err = loadConfigFile(configFile)
|
||||
if err != nil {
|
||||
log.Error(err, "Failed to load webhook config file", "path", configFile)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := webhookConfigFlagPrecedence(webhookConfig, args); err != nil {
|
||||
log.Error(err, "Failed to merge flags with config file values")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
srv, err := NewServerWithOptions(log, *webhookFlags, *webhookConfig)
|
||||
if err != nil {
|
||||
log.Error(err, "Failed initialising server")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := srv.Run(stopCh); err != nil {
|
||||
log.Error(err, "Failed running server")
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
opts.AddFlags(cmd.Flags())
|
||||
webhookFlags.AddFlags(cleanFlagSet)
|
||||
options.AddConfigFlags(cleanFlagSet, webhookConfig)
|
||||
options.AddGlobalFlags(cleanFlagSet)
|
||||
|
||||
cleanFlagSet.BoolP("help", "h", false, fmt.Sprintf("help for %s", cmd.Name()))
|
||||
|
||||
// ugly, but necessary, because Cobra's default UsageFunc and HelpFunc pollute the flagset with global flags
|
||||
const usageFmt = "Usage:\n %s\n\nFlags:\n%s"
|
||||
cmd.SetUsageFunc(func(cmd *cobra.Command) error {
|
||||
fmt.Fprintf(cmd.OutOrStderr(), usageFmt, cmd.UseLine(), cleanFlagSet.FlagUsagesWrapped(2))
|
||||
return nil
|
||||
})
|
||||
cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine(), cleanFlagSet.FlagUsagesWrapped(2))
|
||||
})
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// newFlagSetWithGlobals constructs a new pflag.FlagSet with global flags registered
|
||||
// on it.
|
||||
func newFlagSetWithGlobals() *pflag.FlagSet {
|
||||
fs := pflag.NewFlagSet("", pflag.ExitOnError)
|
||||
// set the normalize func, similar to k8s.io/component-base/cli//flags.go:InitFlags
|
||||
fs.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
|
||||
// explicitly add flags from libs that register global flags
|
||||
options.AddGlobalFlags(fs)
|
||||
return fs
|
||||
}
|
||||
|
||||
// newFakeFlagSet constructs a pflag.FlagSet with the same flags as fs, but where
|
||||
// all values have noop Set implementations
|
||||
func newFakeFlagSet(fs *pflag.FlagSet) *pflag.FlagSet {
|
||||
ret := pflag.NewFlagSet("", pflag.ExitOnError)
|
||||
ret.SetNormalizeFunc(fs.GetNormalizeFunc())
|
||||
fs.VisitAll(func(f *pflag.Flag) {
|
||||
ret.VarP(cliflag.NoOp{}, f.Name, f.Shorthand, f.Usage)
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
// webhookConfigFlagPrecedence re-parses flags over the WebhookConfiguration object.
|
||||
// We must enforce flag precedence by re-parsing the command line into the new object.
|
||||
// This is necessary to preserve backwards-compatibility across binary upgrades.
|
||||
// See issue #56171 for more details.
|
||||
func webhookConfigFlagPrecedence(cfg *config.WebhookConfiguration, args []string) error {
|
||||
// We use a throwaway webhookFlags and a fake global flagset to avoid double-parses,
|
||||
// as some Set implementations accumulate values from multiple flag invocations.
|
||||
fs := newFakeFlagSet(newFlagSetWithGlobals())
|
||||
// register throwaway KubeletFlags
|
||||
options.NewWebhookFlags().AddFlags(fs)
|
||||
// register new WebhookConfiguration
|
||||
options.AddConfigFlags(fs, cfg)
|
||||
// re-parse flags
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadConfigFile(name string) (*config.WebhookConfiguration, error) {
|
||||
const errFmt = "failed to load webhook config file %s, error %v"
|
||||
// compute absolute path based on current working dir
|
||||
webhookConfigFile, err := filepath.Abs(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errFmt, name, err)
|
||||
}
|
||||
loader, err := configfile.NewFSLoader(configfile.NewRealFS(), webhookConfigFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errFmt, name, err)
|
||||
}
|
||||
cfg, err := loader.Load()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errFmt, name, err)
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jetstack/cert-manager/cmd/webhook/app/options"
|
||||
)
|
||||
|
||||
// Test to ensure flags take precedence over config options.
|
||||
func TestWebhookConfigFlagPrecedence_FlagsTakePrecedence(t *testing.T) {
|
||||
cfg, err := options.NewWebhookConfiguration()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg.KubeConfig = "<invalid>"
|
||||
if err := webhookConfigFlagPrecedence(cfg, []string{"--kubeconfig=valid"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if cfg.KubeConfig != "valid" {
|
||||
t.Errorf("unexpected field value %q, expected %q", cfg.KubeConfig, "valid")
|
||||
}
|
||||
}
|
||||
|
||||
// Test to ensure that when flags are not provided, config provided values are preserved.
|
||||
func TestWebhookConfigFlagPrecedence_ConfigPersistsWithoutFlags(t *testing.T) {
|
||||
cfg, err := options.NewWebhookConfiguration()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg.KubeConfig = "valid"
|
||||
if err := webhookConfigFlagPrecedence(cfg, []string{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if cfg.KubeConfig != "valid" {
|
||||
t.Errorf("unexpected field value %q, expected %q", cfg.KubeConfig, "valid")
|
||||
}
|
||||
}
|
||||
@@ -137,6 +137,7 @@ The following table lists the configurable parameters of the cert-manager chart
|
||||
| `webhook.mutatingWebhookConfigurationAnnotations` | Annotations to add to the mutating webhook configuration | `{}` |
|
||||
| `webhook.validatingWebhookConfigurationAnnotations` | Annotations to add to the validating webhook configuration | `{}` |
|
||||
| `webhook.serviceAnnotations` | Annotations to add to the webhook service | `{}` |
|
||||
| `webhook.config` | WebhookConfiguration YAML used to configure flags for the webhook. Generates a ConfigMap containing contents of the field. See `values.yaml` for example. | `{}` |
|
||||
| `webhook.extraArgs` | Optional flags for cert-manager webhook component | `[]` |
|
||||
| `webhook.serviceAccount.create` | If `true`, create a new service account for the webhook component | `true` |
|
||||
| `webhook.serviceAccount.name` | Service account for the webhook component to be used. If not set and `webhook.serviceAccount.create` is `true`, a name is generated using the fullname template | |
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{{- if .Values.webhook.config -}}
|
||||
{{- if not .Values.webhook.config.apiVersion -}}
|
||||
{{- fail "webhook.config.apiVersion must be set" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if not .Values.webhook.config.kind -}}
|
||||
{{- fail "webhook.config.kind must be set" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "webhook.fullname" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
app: {{ include "webhook.name" . }}
|
||||
app.kubernetes.io/name: {{ include "webhook.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: "webhook"
|
||||
data:
|
||||
{{- if .Values.webhook.config }}
|
||||
config.yaml: |
|
||||
{{ .Values.webhook.config | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -61,21 +61,40 @@ spec:
|
||||
{{- if .Values.global.logLevel }}
|
||||
- --v={{ .Values.global.logLevel }}
|
||||
{{- end }}
|
||||
{{- if .Values.webhook.config }}
|
||||
- --config=/var/cert-manager/config/config.yaml
|
||||
{{- end }}
|
||||
{{- $config := default .Values.webhook.config "" }}
|
||||
{{ if not $config.securePort -}}
|
||||
- --secure-port={{ .Values.webhook.securePort }}
|
||||
{{- end }}
|
||||
{{- $tlsConfig := default $config.tlsConfig "" }}
|
||||
{{ if or (not $config.tlsConfig) (and (not $tlsConfig.dynamic) (not $tlsConfig.filesystem) ) -}}
|
||||
- --dynamic-serving-ca-secret-namespace=$(POD_NAMESPACE)
|
||||
- --dynamic-serving-ca-secret-name={{ template "webhook.fullname" . }}-ca
|
||||
- --dynamic-serving-dns-names={{ template "webhook.fullname" . }},{{ template "webhook.fullname" . }}.{{ .Release.Namespace }},{{ template "webhook.fullname" . }}.{{ .Release.Namespace }}.svc{{ if .Values.webhook.url.host }},{{ .Values.webhook.url.host }}{{ end }}
|
||||
{{- end }}
|
||||
{{- with .Values.webhook.extraArgs }}
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: https
|
||||
protocol: TCP
|
||||
{{- if $config.securePort }}
|
||||
containerPort: {{ $config.securePort }}
|
||||
{{- else if .Values.webhook.securePort }}
|
||||
containerPort: {{ .Values.webhook.securePort }}
|
||||
{{- else }}
|
||||
containerPort: 6443
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /livez
|
||||
{{- if $config.healthzPort }}
|
||||
port: {{ $config.healthzPort }}
|
||||
{{- else }}
|
||||
port: 6080
|
||||
{{- end }}
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.webhook.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.webhook.livenessProbe.periodSeconds }}
|
||||
@@ -85,7 +104,11 @@ spec:
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
{{- if $config.healthzPort }}
|
||||
port: {{ $config.healthzPort }}
|
||||
{{- else }}
|
||||
port: 6080
|
||||
{{- end }}
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: {{ .Values.webhook.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.webhook.readinessProbe.periodSeconds }}
|
||||
@@ -105,6 +128,11 @@ spec:
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.webhook.config }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /var/cert-manager/config
|
||||
{{- end }}
|
||||
{{- with .Values.webhook.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
@@ -117,4 +145,9 @@ spec:
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.webhook.config }}
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "webhook.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
@@ -25,7 +25,7 @@ spec:
|
||||
- name: https
|
||||
port: 443
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.webhook.securePort }}
|
||||
targetPort: "https"
|
||||
selector:
|
||||
app.kubernetes.io/name: {{ include "webhook.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
|
||||
@@ -207,6 +207,23 @@ webhook:
|
||||
replicaCount: 1
|
||||
timeoutSeconds: 10
|
||||
|
||||
# Used to configure options for the webhook pod.
|
||||
# This allows setting options that'd usually be provided via flags.
|
||||
# An APIVersion and Kind must be specified in your values.yaml file.
|
||||
# Flags will override options that are set here.
|
||||
config:
|
||||
# apiVersion: webhook.config.cert-manager.io/v1alpha1
|
||||
# kind: WebhookConfiguration
|
||||
|
||||
# The port that the webhook should listen on for requests.
|
||||
# In GKE private clusters, by default kubernetes apiservers are allowed to
|
||||
# talk to the cluster nodes only on 443 and 10250. so configuring
|
||||
# securePort: 10250, will work out of the box without needing to add firewall
|
||||
# rules or requiring NET_BIND_SERVICE capabilities to bind port numbers <1000.
|
||||
# This should be uncommented and set as a default by the chart once we graduate
|
||||
# the apiVersion of WebhookConfiguration past v1alpha1.
|
||||
# securePort: 10250
|
||||
|
||||
strategy: {}
|
||||
# type: RollingUpdate
|
||||
# rollingUpdate:
|
||||
|
||||
@@ -44,6 +44,8 @@ deepcopy_inputs=(
|
||||
pkg/apis/acme/v1beta1 \
|
||||
pkg/apis/acme/v1 \
|
||||
internal/apis/acme \
|
||||
pkg/apis/config/webhook/v1alpha1 \
|
||||
internal/apis/config/webhook \
|
||||
pkg/apis/meta/v1 \
|
||||
internal/apis/meta \
|
||||
pkg/webhook/handlers/testdata/apis/testgroup/v2 \
|
||||
@@ -76,6 +78,7 @@ defaulter_inputs=(
|
||||
internal/apis/acme/v1alpha3 \
|
||||
internal/apis/acme/v1beta1 \
|
||||
internal/apis/acme/v1 \
|
||||
internal/apis/config/webhook/v1alpha1 \
|
||||
internal/apis/meta/v1 \
|
||||
pkg/webhook/handlers/testdata/apis/testgroup/v2 \
|
||||
pkg/webhook/handlers/testdata/apis/testgroup/v1 \
|
||||
@@ -91,6 +94,7 @@ conversion_inputs=(
|
||||
internal/apis/acme/v1alpha3 \
|
||||
internal/apis/acme/v1beta1 \
|
||||
internal/apis/acme/v1 \
|
||||
internal/apis/config/webhook/v1alpha1 \
|
||||
internal/apis/meta/v1 \
|
||||
pkg/webhook/handlers/testdata/apis/testgroup/v2 \
|
||||
pkg/webhook/handlers/testdata/apis/testgroup/v1 \
|
||||
|
||||
@@ -13,6 +13,7 @@ filegroup(
|
||||
"//internal/api/validation:all-srcs",
|
||||
"//internal/apis/acme:all-srcs",
|
||||
"//internal/apis/certmanager:all-srcs",
|
||||
"//internal/apis/config/webhook:all-srcs",
|
||||
"//internal/apis/meta:all-srcs",
|
||||
"//internal/ingress:all-srcs",
|
||||
"//internal/vault:all-srcs",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "github.com/jetstack/cert-manager/internal/apis/config/webhook",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//pkg/apis/config/webhook:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//internal/apis/config/webhook/fuzzer:all-srcs",
|
||||
"//internal/apis/config/webhook/install:all-srcs",
|
||||
"//internal/apis/config/webhook/scheme:all-srcs",
|
||||
"//internal/apis/config/webhook/v1alpha1:all-srcs",
|
||||
"//internal/apis/config/webhook/validation:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
|
||||
// Package webhook is the internal version of the webhook config API.
|
||||
// +groupName=webhook.config.cert-manager.io
|
||||
package webhook
|
||||
@@ -0,0 +1,28 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["fuzzer.go"],
|
||||
importpath = "github.com/jetstack/cert-manager/internal/apis/config/webhook/fuzzer",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/apis/config/webhook:go_default_library",
|
||||
"@com_github_google_gofuzz//:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime/serializer:go_default_library",
|
||||
"@io_k8s_utils//pointer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fuzzer
|
||||
|
||||
import (
|
||||
fuzz "github.com/google/gofuzz"
|
||||
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/jetstack/cert-manager/internal/apis/config/webhook"
|
||||
)
|
||||
|
||||
// Funcs returns the fuzzer functions for the webhook config api group.
|
||||
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
return []interface{}{
|
||||
func(s *webhook.WebhookConfiguration, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(s) // fuzz self without calling this function again
|
||||
|
||||
if s.HealthzPort == nil {
|
||||
s.HealthzPort = pointer.Int(12)
|
||||
}
|
||||
if s.SecurePort == nil {
|
||||
s.SecurePort = pointer.Int(123)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["install.go"],
|
||||
importpath = "github.com/jetstack/cert-manager/internal/apis/config/webhook/install",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/apis/config/webhook:go_default_library",
|
||||
"//internal/apis/config/webhook/v1alpha1:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/util/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["roundtrip_test.go"],
|
||||
data = [
|
||||
"//deploy/crds:templated_files",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//internal/apis/config/webhook/fuzzer:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/api/apitesting/roundtrip:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package install installs the API group, making it available as an option to
|
||||
// all of the API encoding/decoding machinery.
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
|
||||
"github.com/jetstack/cert-manager/internal/apis/config/webhook"
|
||||
"github.com/jetstack/cert-manager/internal/apis/config/webhook/v1alpha1"
|
||||
)
|
||||
|
||||
// Install registers the API group and adds types to a scheme
|
||||
func Install(scheme *runtime.Scheme) {
|
||||
utilruntime.Must(webhook.AddToScheme(scheme))
|
||||
utilruntime.Must(v1alpha1.AddToScheme(scheme))
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package install
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/apitesting/roundtrip"
|
||||
|
||||
configfuzzer "github.com/jetstack/cert-manager/internal/apis/config/webhook/fuzzer"
|
||||
)
|
||||
|
||||
func TestRoundTripTypes(t *testing.T) {
|
||||
roundtrip.RoundTripTestForAPIGroup(t, Install, configfuzzer.Funcs)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/jetstack/cert-manager/pkg/apis/config/webhook"
|
||||
)
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: webhook.GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&WebhookConfiguration{},
|
||||
// Add new kinds to be registered here
|
||||
)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["scheme.go"],
|
||||
importpath = "github.com/jetstack/cert-manager/internal/apis/config/webhook/scheme",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/apis/config/webhook:go_default_library",
|
||||
"//internal/apis/config/webhook/v1alpha1:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime/serializer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scheme
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
|
||||
config "github.com/jetstack/cert-manager/internal/apis/config/webhook"
|
||||
configv1alpha1 "github.com/jetstack/cert-manager/internal/apis/config/webhook/v1alpha1"
|
||||
)
|
||||
|
||||
// NewSchemeAndCodecs is a utility function that returns a Scheme and CodecFactory
|
||||
// that understand the types in the config.cert-manager.io API group. Passing mutators allows
|
||||
// for adjusting the behavior of the CodecFactory, for example enable strict decoding.
|
||||
func NewSchemeAndCodecs(mutators ...serializer.CodecFactoryOptionsMutator) (*runtime.Scheme, *serializer.CodecFactory, error) {
|
||||
scheme := runtime.NewScheme()
|
||||
if err := config.AddToScheme(scheme); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := configv1alpha1.AddToScheme(scheme); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
codecs := serializer.NewCodecFactory(scheme, mutators...)
|
||||
return scheme, &codecs, nil
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package webhook
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type WebhookConfiguration struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
// securePort is the port number to listen on for secure TLS connections from the kube-apiserver.
|
||||
// Defaults to 6443.
|
||||
SecurePort *int
|
||||
|
||||
// healthzPort is the port number to listen on (using plaintext HTTP) for healthz connections.
|
||||
// Defaults to 6080.
|
||||
HealthzPort *int
|
||||
|
||||
// tlsConfig is used to configure the secure listener's TLS settings.
|
||||
TLSConfig TLSConfig
|
||||
|
||||
// kubeConfig is the kubeconfig file used to connect to the Kubernetes apiserver.
|
||||
// If not specified, the webhook will attempt to load the in-cluster-config.
|
||||
KubeConfig string
|
||||
|
||||
// apiServerHost is used to override the API server connection address.
|
||||
// Deprecated: use `kubeConfig` instead.
|
||||
APIServerHost string
|
||||
|
||||
// enablePprof configures whether pprof is enabled.
|
||||
EnablePprof bool
|
||||
|
||||
// pprofAddress configures the address on which /debug/pprof endpoint will be served if enabled.
|
||||
// Defaults to 'localhost:6060'.
|
||||
PprofAddress string
|
||||
}
|
||||
|
||||
// TLSConfig configures how TLS certificates are sourced for serving.
|
||||
// Only one of 'filesystem' or 'dynamic' may be specified.
|
||||
type TLSConfig struct {
|
||||
// cipherSuites is the list of allowed cipher suites for the server.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
// If not specified, the default for the Go version will be used and may change over time.
|
||||
CipherSuites []string
|
||||
|
||||
// minTLSVersion is the minimum TLS version supported.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
// If not specified, the default for the Go version will be used and may change over time.
|
||||
MinTLSVersion string
|
||||
|
||||
// Filesystem enables using a certificate and private key found on the local filesystem.
|
||||
// These files will be periodically polled in case they have changed, and dynamically reloaded.
|
||||
Filesystem FilesystemServingConfig
|
||||
|
||||
// When Dynamic serving is enabled, the webhook will generate a CA used to sign webhook
|
||||
// certificates and persist it into a Kubernetes Secret resource (for other replicas of the
|
||||
// webhook to consume).
|
||||
// It will then generate a certificate in-memory for itself using this CA to serve with.
|
||||
// The CAs certificate can then be copied into the appropriate Validating, Mutating and Conversion
|
||||
// webhook configuration objects (typically by cainjector).
|
||||
Dynamic DynamicServingConfig
|
||||
}
|
||||
|
||||
func (c *TLSConfig) FilesystemConfigProvided() bool {
|
||||
if c.Filesystem.KeyFile != "" || c.Filesystem.CertFile != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *TLSConfig) DynamicConfigProvided() bool {
|
||||
if c.Dynamic.SecretNamespace != "" || c.Dynamic.SecretName != "" || len(c.Dynamic.DNSNames) > 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// DynamicServingConfig makes the webhook generate a CA and persist it into Secret resources.
|
||||
// This CA will be used by all instances of the webhook for signing serving certificates.
|
||||
type DynamicServingConfig struct {
|
||||
// Namespace of the Kubernetes Secret resource containing the TLS certificate
|
||||
// used as a CA to sign dynamic serving certificates.
|
||||
SecretNamespace string
|
||||
|
||||
// Namespace of the Kubernetes Secret resource containing the TLS certificate
|
||||
// used as a CA to sign dynamic serving certificates.
|
||||
SecretName string
|
||||
|
||||
// DNSNames that must be present on serving certificates signed by the CA.
|
||||
DNSNames []string
|
||||
}
|
||||
|
||||
// FilesystemServingConfig enables using a certificate and private key found on the local filesystem.
|
||||
// These files will be periodically polled in case they have changed, and dynamically reloaded.
|
||||
type FilesystemServingConfig struct {
|
||||
// Path to a file containing TLS certificate & chain to serve with
|
||||
CertFile string
|
||||
|
||||
// Path to a file containing a TLS private key to server with
|
||||
KeyFile string
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conversion.go",
|
||||
"defaults.go",
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"zz_generated.conversion.go",
|
||||
"zz_generated.defaults.go",
|
||||
],
|
||||
importpath = "github.com/jetstack/cert-manager/internal/apis/config/webhook/v1alpha1",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/apis/config/webhook:go_default_library",
|
||||
"//pkg/apis/config/webhook:go_default_library",
|
||||
"//pkg/apis/config/webhook/v1alpha1:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/conversion:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime/schema:go_default_library",
|
||||
"@io_k8s_utils//pointer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/jetstack/cert-manager/pkg/apis/config/webhook/v1alpha1"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_WebhookConfiguration(obj *v1alpha1.WebhookConfiguration) {
|
||||
if obj.SecurePort == nil {
|
||||
obj.SecurePort = pointer.Int(6443)
|
||||
}
|
||||
if obj.HealthzPort == nil {
|
||||
obj.HealthzPort = pointer.Int(6080)
|
||||
}
|
||||
if obj.PprofAddress == "" {
|
||||
obj.PprofAddress = "localhost:6060"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:conversion-gen=github.com/jetstack/cert-manager/internal/apis/config/webhook
|
||||
// +k8s:conversion-gen-external-types=github.com/jetstack/cert-manager/pkg/apis/config/webhook/v1alpha1
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:defaulter-gen-input=../../../../../pkg/apis/config/webhook/v1alpha1
|
||||
|
||||
// +groupName=webhook.config.cert-manager.io
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/jetstack/cert-manager/pkg/apis/config/webhook"
|
||||
"github.com/jetstack/cert-manager/pkg/apis/config/webhook/v1alpha1"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: webhook.GroupName, Version: "v1alpha1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
localSchemeBuilder = &v1alpha1.SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addDefaultingFuncs)
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by conversion-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
unsafe "unsafe"
|
||||
|
||||
webhook "github.com/jetstack/cert-manager/internal/apis/config/webhook"
|
||||
v1alpha1 "github.com/jetstack/cert-manager/pkg/apis/config/webhook/v1alpha1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*v1alpha1.DynamicServingConfig)(nil), (*webhook.DynamicServingConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_DynamicServingConfig_To_webhook_DynamicServingConfig(a.(*v1alpha1.DynamicServingConfig), b.(*webhook.DynamicServingConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*webhook.DynamicServingConfig)(nil), (*v1alpha1.DynamicServingConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_webhook_DynamicServingConfig_To_v1alpha1_DynamicServingConfig(a.(*webhook.DynamicServingConfig), b.(*v1alpha1.DynamicServingConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1alpha1.FilesystemServingConfig)(nil), (*webhook.FilesystemServingConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_FilesystemServingConfig_To_webhook_FilesystemServingConfig(a.(*v1alpha1.FilesystemServingConfig), b.(*webhook.FilesystemServingConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*webhook.FilesystemServingConfig)(nil), (*v1alpha1.FilesystemServingConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_webhook_FilesystemServingConfig_To_v1alpha1_FilesystemServingConfig(a.(*webhook.FilesystemServingConfig), b.(*v1alpha1.FilesystemServingConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1alpha1.TLSConfig)(nil), (*webhook.TLSConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_TLSConfig_To_webhook_TLSConfig(a.(*v1alpha1.TLSConfig), b.(*webhook.TLSConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*webhook.TLSConfig)(nil), (*v1alpha1.TLSConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_webhook_TLSConfig_To_v1alpha1_TLSConfig(a.(*webhook.TLSConfig), b.(*v1alpha1.TLSConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1alpha1.WebhookConfiguration)(nil), (*webhook.WebhookConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_WebhookConfiguration_To_webhook_WebhookConfiguration(a.(*v1alpha1.WebhookConfiguration), b.(*webhook.WebhookConfiguration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*webhook.WebhookConfiguration)(nil), (*v1alpha1.WebhookConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_webhook_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(a.(*webhook.WebhookConfiguration), b.(*v1alpha1.WebhookConfiguration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_DynamicServingConfig_To_webhook_DynamicServingConfig(in *v1alpha1.DynamicServingConfig, out *webhook.DynamicServingConfig, s conversion.Scope) error {
|
||||
out.SecretNamespace = in.SecretNamespace
|
||||
out.SecretName = in.SecretName
|
||||
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_DynamicServingConfig_To_webhook_DynamicServingConfig is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_DynamicServingConfig_To_webhook_DynamicServingConfig(in *v1alpha1.DynamicServingConfig, out *webhook.DynamicServingConfig, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_DynamicServingConfig_To_webhook_DynamicServingConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_webhook_DynamicServingConfig_To_v1alpha1_DynamicServingConfig(in *webhook.DynamicServingConfig, out *v1alpha1.DynamicServingConfig, s conversion.Scope) error {
|
||||
out.SecretNamespace = in.SecretNamespace
|
||||
out.SecretName = in.SecretName
|
||||
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_webhook_DynamicServingConfig_To_v1alpha1_DynamicServingConfig is an autogenerated conversion function.
|
||||
func Convert_webhook_DynamicServingConfig_To_v1alpha1_DynamicServingConfig(in *webhook.DynamicServingConfig, out *v1alpha1.DynamicServingConfig, s conversion.Scope) error {
|
||||
return autoConvert_webhook_DynamicServingConfig_To_v1alpha1_DynamicServingConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_FilesystemServingConfig_To_webhook_FilesystemServingConfig(in *v1alpha1.FilesystemServingConfig, out *webhook.FilesystemServingConfig, s conversion.Scope) error {
|
||||
out.CertFile = in.CertFile
|
||||
out.KeyFile = in.KeyFile
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_FilesystemServingConfig_To_webhook_FilesystemServingConfig is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_FilesystemServingConfig_To_webhook_FilesystemServingConfig(in *v1alpha1.FilesystemServingConfig, out *webhook.FilesystemServingConfig, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_FilesystemServingConfig_To_webhook_FilesystemServingConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_webhook_FilesystemServingConfig_To_v1alpha1_FilesystemServingConfig(in *webhook.FilesystemServingConfig, out *v1alpha1.FilesystemServingConfig, s conversion.Scope) error {
|
||||
out.CertFile = in.CertFile
|
||||
out.KeyFile = in.KeyFile
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_webhook_FilesystemServingConfig_To_v1alpha1_FilesystemServingConfig is an autogenerated conversion function.
|
||||
func Convert_webhook_FilesystemServingConfig_To_v1alpha1_FilesystemServingConfig(in *webhook.FilesystemServingConfig, out *v1alpha1.FilesystemServingConfig, s conversion.Scope) error {
|
||||
return autoConvert_webhook_FilesystemServingConfig_To_v1alpha1_FilesystemServingConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_TLSConfig_To_webhook_TLSConfig(in *v1alpha1.TLSConfig, out *webhook.TLSConfig, s conversion.Scope) error {
|
||||
out.CipherSuites = *(*[]string)(unsafe.Pointer(&in.CipherSuites))
|
||||
out.MinTLSVersion = in.MinTLSVersion
|
||||
if err := Convert_v1alpha1_FilesystemServingConfig_To_webhook_FilesystemServingConfig(&in.Filesystem, &out.Filesystem, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1alpha1_DynamicServingConfig_To_webhook_DynamicServingConfig(&in.Dynamic, &out.Dynamic, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_TLSConfig_To_webhook_TLSConfig is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_TLSConfig_To_webhook_TLSConfig(in *v1alpha1.TLSConfig, out *webhook.TLSConfig, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_TLSConfig_To_webhook_TLSConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_webhook_TLSConfig_To_v1alpha1_TLSConfig(in *webhook.TLSConfig, out *v1alpha1.TLSConfig, s conversion.Scope) error {
|
||||
out.CipherSuites = *(*[]string)(unsafe.Pointer(&in.CipherSuites))
|
||||
out.MinTLSVersion = in.MinTLSVersion
|
||||
if err := Convert_webhook_FilesystemServingConfig_To_v1alpha1_FilesystemServingConfig(&in.Filesystem, &out.Filesystem, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_webhook_DynamicServingConfig_To_v1alpha1_DynamicServingConfig(&in.Dynamic, &out.Dynamic, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_webhook_TLSConfig_To_v1alpha1_TLSConfig is an autogenerated conversion function.
|
||||
func Convert_webhook_TLSConfig_To_v1alpha1_TLSConfig(in *webhook.TLSConfig, out *v1alpha1.TLSConfig, s conversion.Scope) error {
|
||||
return autoConvert_webhook_TLSConfig_To_v1alpha1_TLSConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_WebhookConfiguration_To_webhook_WebhookConfiguration(in *v1alpha1.WebhookConfiguration, out *webhook.WebhookConfiguration, s conversion.Scope) error {
|
||||
out.SecurePort = (*int)(unsafe.Pointer(in.SecurePort))
|
||||
out.HealthzPort = (*int)(unsafe.Pointer(in.HealthzPort))
|
||||
if err := Convert_v1alpha1_TLSConfig_To_webhook_TLSConfig(&in.TLSConfig, &out.TLSConfig, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.KubeConfig = in.KubeConfig
|
||||
out.APIServerHost = in.APIServerHost
|
||||
out.EnablePprof = in.EnablePprof
|
||||
out.PprofAddress = in.PprofAddress
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_WebhookConfiguration_To_webhook_WebhookConfiguration is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_WebhookConfiguration_To_webhook_WebhookConfiguration(in *v1alpha1.WebhookConfiguration, out *webhook.WebhookConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_WebhookConfiguration_To_webhook_WebhookConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_webhook_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in *webhook.WebhookConfiguration, out *v1alpha1.WebhookConfiguration, s conversion.Scope) error {
|
||||
out.SecurePort = (*int)(unsafe.Pointer(in.SecurePort))
|
||||
out.HealthzPort = (*int)(unsafe.Pointer(in.HealthzPort))
|
||||
if err := Convert_webhook_TLSConfig_To_v1alpha1_TLSConfig(&in.TLSConfig, &out.TLSConfig, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.KubeConfig = in.KubeConfig
|
||||
out.APIServerHost = in.APIServerHost
|
||||
out.EnablePprof = in.EnablePprof
|
||||
out.PprofAddress = in.PprofAddress
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_webhook_WebhookConfiguration_To_v1alpha1_WebhookConfiguration is an autogenerated conversion function.
|
||||
func Convert_webhook_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in *webhook.WebhookConfiguration, out *v1alpha1.WebhookConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_webhook_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in, out, s)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/jetstack/cert-manager/pkg/apis/config/webhook/v1alpha1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&v1alpha1.WebhookConfiguration{}, func(obj interface{}) { SetObjectDefaults_WebhookConfiguration(obj.(*v1alpha1.WebhookConfiguration)) })
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetObjectDefaults_WebhookConfiguration(in *v1alpha1.WebhookConfiguration) {
|
||||
SetDefaults_WebhookConfiguration(in)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["validation.go"],
|
||||
importpath = "github.com/jetstack/cert-manager/internal/apis/config/webhook/validation",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/apis/config/webhook:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/util/errors:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
|
||||
config "github.com/jetstack/cert-manager/internal/apis/config/webhook"
|
||||
)
|
||||
|
||||
func ValidateWebhookConfiguration(cfg *config.WebhookConfiguration) error {
|
||||
var allErrors []error
|
||||
if cfg.TLSConfig.FilesystemConfigProvided() && cfg.TLSConfig.DynamicConfigProvided() {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: cannot specify both filesystem based and dynamic TLS configuration"))
|
||||
} else {
|
||||
if cfg.TLSConfig.FilesystemConfigProvided() {
|
||||
if cfg.TLSConfig.Filesystem.KeyFile == "" {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: tlsConfig.filesystem.keyFile (--tls-private-key-file) must be specified when using filesystem based TLS config"))
|
||||
}
|
||||
if cfg.TLSConfig.Filesystem.CertFile == "" {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: tlsConfig.filesystem.certFile (--tls-cert-file) must be specified when using filesystem based TLS config"))
|
||||
}
|
||||
} else if cfg.TLSConfig.DynamicConfigProvided() {
|
||||
if cfg.TLSConfig.Dynamic.SecretNamespace == "" {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: tlsConfig.dynamic.secretNamespace (--dynamic-serving-ca-secret-namespace) must be specified when using dynamic TLS config"))
|
||||
}
|
||||
if cfg.TLSConfig.Dynamic.SecretName == "" {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: tlsConfig.dynamic.secretName (--dynamic-serving-ca-secret-name) must be specified when using dynamic TLS config"))
|
||||
}
|
||||
if len(cfg.TLSConfig.Dynamic.DNSNames) == 0 {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: tlsConfig.dynamic.dnsNames (--dynamic-serving-dns-names) must be specified when using dynamic TLS config"))
|
||||
}
|
||||
}
|
||||
}
|
||||
if cfg.HealthzPort == nil {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: healthzPort must be specified"))
|
||||
}
|
||||
if cfg.SecurePort == nil {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: securePort must be specified"))
|
||||
}
|
||||
return utilerrors.NewAggregate(allErrors)
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package webhook
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DynamicServingConfig) DeepCopyInto(out *DynamicServingConfig) {
|
||||
*out = *in
|
||||
if in.DNSNames != nil {
|
||||
in, out := &in.DNSNames, &out.DNSNames
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicServingConfig.
|
||||
func (in *DynamicServingConfig) DeepCopy() *DynamicServingConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DynamicServingConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FilesystemServingConfig) DeepCopyInto(out *FilesystemServingConfig) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemServingConfig.
|
||||
func (in *FilesystemServingConfig) DeepCopy() *FilesystemServingConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FilesystemServingConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TLSConfig) DeepCopyInto(out *TLSConfig) {
|
||||
*out = *in
|
||||
if in.CipherSuites != nil {
|
||||
in, out := &in.CipherSuites, &out.CipherSuites
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.Filesystem = in.Filesystem
|
||||
in.Dynamic.DeepCopyInto(&out.Dynamic)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig.
|
||||
func (in *TLSConfig) DeepCopy() *TLSConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TLSConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.SecurePort != nil {
|
||||
in, out := &in.SecurePort, &out.SecurePort
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.HealthzPort != nil {
|
||||
in, out := &in.HealthzPort, &out.HealthzPort
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
in.TLSConfig.DeepCopyInto(&out.TLSConfig)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration.
|
||||
func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WebhookConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WebhookConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -20,6 +20,7 @@ filegroup(
|
||||
":package-srcs",
|
||||
"//pkg/apis/acme:all-srcs",
|
||||
"//pkg/apis/certmanager:all-srcs",
|
||||
"//pkg/apis/config/webhook:all-srcs",
|
||||
"//pkg/apis/experimental:all-srcs",
|
||||
"//pkg/apis/meta:all-srcs",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["doc.go"],
|
||||
importpath = "github.com/jetstack/cert-manager/pkg/apis/config/webhook",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/apis/config/webhook/v1alpha1:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +groupName=webhook.config.cert-manager.io
|
||||
|
||||
// Package webhook contains types used to configure the webhook
|
||||
package webhook
|
||||
|
||||
const GroupName = "webhook.config.cert-manager.io"
|
||||
@@ -0,0 +1,33 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "github.com/jetstack/cert-manager/pkg/apis/config/webhook/v1alpha1",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/apis/config/webhook:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the webhook config API.
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
// +groupName=webhook.config.cert-manager.io
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/jetstack/cert-manager/pkg/apis/config/webhook"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: webhook.GroupName, Version: "v1alpha1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&WebhookConfiguration{},
|
||||
// Add new kinds to be registered here
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type WebhookConfiguration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// securePort is the port number to listen on for secure TLS connections from the kube-apiserver.
|
||||
// Defaults to 6443.
|
||||
SecurePort *int `json:"securePort,omitempty"`
|
||||
|
||||
// healthzPort is the port number to listen on (using plaintext HTTP) for healthz connections.
|
||||
// Defaults to 6080.
|
||||
HealthzPort *int `json:"healthzPort,omitempty"`
|
||||
|
||||
// tlsConfig is used to configure the secure listener's TLS settings.
|
||||
TLSConfig TLSConfig `json:"tlsConfig"`
|
||||
|
||||
// kubeConfig is the kubeconfig file used to connect to the Kubernetes apiserver.
|
||||
// If not specified, the webhook will attempt to load the in-cluster-config.
|
||||
KubeConfig string `json:"kubeConfig,omitempty"`
|
||||
|
||||
// apiServerHost is used to override the API server connection address.
|
||||
// Deprecated: use `kubeConfig` instead.
|
||||
APIServerHost string `json:"apiServerHost,omitempty"`
|
||||
|
||||
// enablePprof configures whether pprof is enabled.
|
||||
EnablePprof bool `json:"enablePprof"`
|
||||
|
||||
// pprofAddress configures the address on which /debug/pprof endpoint will be served if enabled.
|
||||
// Defaults to 'localhost:6060'.
|
||||
PprofAddress string `json:"pprofAddress,omitempty"`
|
||||
}
|
||||
|
||||
// TLSConfig configures how TLS certificates are sourced for serving.
|
||||
// Only one of 'filesystem' or 'dynamic' may be specified.
|
||||
type TLSConfig struct {
|
||||
// cipherSuites is the list of allowed cipher suites for the server.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
// If not specified, the default for the Go version will be used and may change over time.
|
||||
CipherSuites []string `json:"cipherSuites,omitempty"`
|
||||
|
||||
// minTLSVersion is the minimum TLS version supported.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
// If not specified, the default for the Go version will be used and may change over time.
|
||||
MinTLSVersion string `json:"minTLSVersion,omitempty"`
|
||||
|
||||
// Filesystem enables using a certificate and private key found on the local filesystem.
|
||||
// These files will be periodically polled in case they have changed, and dynamically reloaded.
|
||||
Filesystem FilesystemServingConfig `json:"filesystem"`
|
||||
|
||||
// When Dynamic serving is enabled, the webhook will generate a CA used to sign webhook
|
||||
// certificates and persist it into a Kubernetes Secret resource (for other replicas of the
|
||||
// webhook to consume).
|
||||
// It will then generate a certificate in-memory for itself using this CA to serve with.
|
||||
// The CAs certificate can then be copied into the appropriate Validating, Mutating and Conversion
|
||||
// webhook configuration objects (typically by cainjector).
|
||||
Dynamic DynamicServingConfig `json:"dynamic"`
|
||||
}
|
||||
|
||||
// DynamicServingConfig makes the webhook generate a CA and persist it into Secret resources.
|
||||
// This CA will be used by all instances of the webhook for signing serving certificates.
|
||||
type DynamicServingConfig struct {
|
||||
// Namespace of the Kubernetes Secret resource containing the TLS certificate
|
||||
// used as a CA to sign dynamic serving certificates.
|
||||
SecretNamespace string `json:"secretNamespace,omitempty"`
|
||||
|
||||
// Namespace of the Kubernetes Secret resource containing the TLS certificate
|
||||
// used as a CA to sign dynamic serving certificates.
|
||||
SecretName string `json:"secretName,omitempty"`
|
||||
|
||||
// DNSNames that must be present on serving certificates signed by the CA.
|
||||
DNSNames []string `json:"dnsNames,omitempty"`
|
||||
}
|
||||
|
||||
// FilesystemServingConfig enables using a certificate and private key found on the local filesystem.
|
||||
// These files will be periodically polled in case they have changed, and dynamically reloaded.
|
||||
type FilesystemServingConfig struct {
|
||||
// Path to a file containing TLS certificate & chain to serve with
|
||||
CertFile string `json:"certFile,omitempty"`
|
||||
|
||||
// Path to a file containing a TLS private key to server with
|
||||
KeyFile string `json:"keyFile,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DynamicServingConfig) DeepCopyInto(out *DynamicServingConfig) {
|
||||
*out = *in
|
||||
if in.DNSNames != nil {
|
||||
in, out := &in.DNSNames, &out.DNSNames
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicServingConfig.
|
||||
func (in *DynamicServingConfig) DeepCopy() *DynamicServingConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DynamicServingConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FilesystemServingConfig) DeepCopyInto(out *FilesystemServingConfig) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemServingConfig.
|
||||
func (in *FilesystemServingConfig) DeepCopy() *FilesystemServingConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FilesystemServingConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TLSConfig) DeepCopyInto(out *TLSConfig) {
|
||||
*out = *in
|
||||
if in.CipherSuites != nil {
|
||||
in, out := &in.CipherSuites, &out.CipherSuites
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.Filesystem = in.Filesystem
|
||||
in.Dynamic.DeepCopyInto(&out.Dynamic)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig.
|
||||
func (in *TLSConfig) DeepCopy() *TLSConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TLSConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.SecurePort != nil {
|
||||
in, out := &in.SecurePort, &out.SecurePort
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.HealthzPort != nil {
|
||||
in, out := &in.HealthzPort, &out.HealthzPort
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
in.TLSConfig.DeepCopyInto(&out.TLSConfig)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration.
|
||||
func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WebhookConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WebhookConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -27,6 +27,7 @@ filegroup(
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/webhook/authority:all-srcs",
|
||||
"//pkg/webhook/configfile:all-srcs",
|
||||
"//pkg/webhook/handlers:all-srcs",
|
||||
"//pkg/webhook/server:all-srcs",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["configfile.go"],
|
||||
importpath = "github.com/jetstack/cert-manager/pkg/webhook/configfile",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//internal/apis/config/webhook:go_default_library",
|
||||
"//internal/apis/config/webhook/scheme:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/runtime/serializer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["configfile_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configfile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
|
||||
config "github.com/jetstack/cert-manager/internal/apis/config/webhook"
|
||||
"github.com/jetstack/cert-manager/internal/apis/config/webhook/scheme"
|
||||
)
|
||||
|
||||
// Filesystem is an interface used to mock out calls to ReadFile
|
||||
type Filesystem interface {
|
||||
ReadFile(filename string) ([]byte, error)
|
||||
}
|
||||
|
||||
type realFS struct{}
|
||||
|
||||
func (fs realFS) ReadFile(filename string) ([]byte, error) {
|
||||
return ioutil.ReadFile(filename)
|
||||
}
|
||||
|
||||
// NewRealFS builds a Filesystem that wraps around `ioutil.ReadFile`.
|
||||
func NewRealFS() Filesystem {
|
||||
return realFS{}
|
||||
}
|
||||
|
||||
type Loader interface {
|
||||
Load() (*config.WebhookConfiguration, error)
|
||||
}
|
||||
|
||||
type fsLoader struct {
|
||||
fs Filesystem
|
||||
filename string
|
||||
codec *serializer.CodecFactory
|
||||
}
|
||||
|
||||
var _ Loader = &fsLoader{}
|
||||
|
||||
func (f *fsLoader) Load() (*config.WebhookConfiguration, error) {
|
||||
data, err := f.fs.ReadFile(f.filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read webhook config file %q, error: %v", f.filename, err)
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
return nil, fmt.Errorf("webhook config file %q was empty", f.filename)
|
||||
}
|
||||
|
||||
cfg, err := decodeWebhookConfiguration(f.codec, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// make all paths absolute
|
||||
resolveRelativePaths(webhookConfigurationPathRefs(cfg), filepath.Dir(f.filename))
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func NewFSLoader(fs Filesystem, name string) (Loader, error) {
|
||||
_, webhookCodec, err := scheme.NewSchemeAndCodecs(serializer.EnableStrict)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &fsLoader{
|
||||
fs: fs,
|
||||
filename: name,
|
||||
codec: webhookCodec,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func resolveRelativePaths(paths []*string, root string) {
|
||||
for _, path := range paths {
|
||||
// leave empty paths alone, "no path" is a valid input
|
||||
// do not attempt to resolve paths that are already absolute
|
||||
if len(*path) > 0 && !filepath.IsAbs(*path) {
|
||||
*path = filepath.Join(root, *path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func decodeWebhookConfiguration(codec *serializer.CodecFactory, data []byte) (*config.WebhookConfiguration, error) {
|
||||
obj, gvk, err := codec.UniversalDecoder().Decode(data, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode: %w", err)
|
||||
}
|
||||
|
||||
internalObj, ok := obj.(*config.WebhookConfiguration)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to cast object to WebhookConfiguration, unexpected type: %v", gvk)
|
||||
}
|
||||
|
||||
return internalObj, nil
|
||||
}
|
||||
|
||||
// webhookConfigurationPathRefs returns pointers to all the WebhookConfiguration fields that contain filepaths.
|
||||
// You might use this, for example, to resolve all relative paths against some common root before
|
||||
// passing the configuration to the application. This method must be kept up to date as new fields are added.
|
||||
func webhookConfigurationPathRefs(cfg *config.WebhookConfiguration) []*string {
|
||||
return []*string{
|
||||
&cfg.TLSConfig.Filesystem.KeyFile,
|
||||
&cfg.TLSConfig.Filesystem.CertFile,
|
||||
&cfg.KubeConfig,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright 2021 The cert-manager Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configfile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFSLoader_Load(t *testing.T) {
|
||||
const expectedFilename = "/path/to/config/file"
|
||||
const kubeConfigPath = "path/to/kubeconfig/file"
|
||||
|
||||
loader, err := NewFSLoader(newFakeFS(func(filename string) ([]byte, error) {
|
||||
if filename != expectedFilename {
|
||||
t.Fatalf("unexpected filename %q passed to ReadFile", filename)
|
||||
return nil, fmt.Errorf("unexpected filename %q", filename)
|
||||
}
|
||||
return []byte(fmt.Sprintf(`apiVersion: webhook.config.cert-manager.io/v1alpha1
|
||||
kind: WebhookConfiguration
|
||||
kubeConfig: %s`, kubeConfigPath)), nil
|
||||
}), expectedFilename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg, err := loader.Load()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// the config loader will force paths to be 'absolute' if they are provided as relative.
|
||||
absKubeConfigPath := "/path/to/config/path/to/kubeconfig/file"
|
||||
if cfg.KubeConfig != absKubeConfigPath {
|
||||
t.Errorf("expected kubeConfig to be set to %q but got %q", absKubeConfigPath, cfg.KubeConfig)
|
||||
}
|
||||
}
|
||||
|
||||
func newFakeFS(readFileFunc func(string) ([]byte, error)) Filesystem {
|
||||
return fakeFS{readFileFunc: readFileFunc}
|
||||
}
|
||||
|
||||
type fakeFS struct {
|
||||
readFileFunc func(string) ([]byte, error)
|
||||
}
|
||||
|
||||
func (f fakeFS) ReadFile(filename string) ([]byte, error) {
|
||||
return f.readFileFunc(filename)
|
||||
}
|
||||
Reference in New Issue
Block a user