Support file path as input param for Kubernetes token value
This commit is contained in:
parent
ff7966f9cd
commit
980dac4572
37 changed files with 292 additions and 256 deletions
|
@ -152,8 +152,8 @@ func createMessage(certs map[string]*Certificate) dynamic.Message {
|
|||
for _, cert := range certs {
|
||||
certConf := &traefiktls.CertAndStores{
|
||||
Certificate: traefiktls.Certificate{
|
||||
CertFile: traefiktls.FileOrContent(cert.Certificate),
|
||||
KeyFile: traefiktls.FileOrContent(cert.Key),
|
||||
CertFile: types.FileOrContent(cert.Certificate),
|
||||
KeyFile: types.FileOrContent(cert.Key),
|
||||
},
|
||||
Stores: []string{tlsalpn01.ACMETLS1Protocol},
|
||||
}
|
||||
|
|
|
@ -783,8 +783,8 @@ func (p *Provider) buildMessage() dynamic.Message {
|
|||
for _, cert := range p.certificates {
|
||||
certConf := &traefiktls.CertAndStores{
|
||||
Certificate: traefiktls.Certificate{
|
||||
CertFile: traefiktls.FileOrContent(cert.Certificate.Certificate),
|
||||
KeyFile: traefiktls.FileOrContent(cert.Key),
|
||||
CertFile: types.FileOrContent(cert.Certificate.Certificate),
|
||||
KeyFile: types.FileOrContent(cert.Key),
|
||||
},
|
||||
Stores: []string{cert.Store},
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
ptypes "github.com/traefik/paerser/types"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/tls"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
func Int(v int) *int { return &v }
|
||||
|
@ -428,7 +429,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"tls-ns-dc1-dev-Test": {
|
||||
ServerName: "ns-dc1-dev/Test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []tls.FileOrContent{
|
||||
RootCAs: []types.FileOrContent{
|
||||
"root",
|
||||
},
|
||||
Certificates: []tls.Certificate{
|
||||
|
@ -519,7 +520,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"tls-ns-dc1-dev-Test": {
|
||||
ServerName: "ns-dc1-dev/Test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []tls.FileOrContent{
|
||||
RootCAs: []types.FileOrContent{
|
||||
"root",
|
||||
},
|
||||
Certificates: []tls.Certificate{
|
||||
|
@ -2280,7 +2281,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
TLS: &dynamic.TLSClientConfig{
|
||||
ServerName: "ns-dc1-Test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []tls.FileOrContent{
|
||||
RootCAs: []types.FileOrContent{
|
||||
"root",
|
||||
},
|
||||
Certificates: []tls.Certificate{
|
||||
|
@ -2899,7 +2900,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"tls-ns-dc1-Test": {
|
||||
ServerName: "ns-dc1-Test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []tls.FileOrContent{
|
||||
RootCAs: []types.FileOrContent{
|
||||
"root",
|
||||
},
|
||||
Certificates: []tls.Certificate{
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
traefiktls "github.com/traefik/traefik/v3/pkg/tls"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
// connectCert holds our certificates as a client of the Consul Connect protocol.
|
||||
|
@ -13,18 +14,18 @@ type connectCert struct {
|
|||
leaf keyPair
|
||||
}
|
||||
|
||||
func (c *connectCert) getRoot() []traefiktls.FileOrContent {
|
||||
var result []traefiktls.FileOrContent
|
||||
func (c *connectCert) getRoot() []types.FileOrContent {
|
||||
var result []types.FileOrContent
|
||||
for _, r := range c.root {
|
||||
result = append(result, traefiktls.FileOrContent(r))
|
||||
result = append(result, types.FileOrContent(r))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (c *connectCert) getLeaf() traefiktls.Certificate {
|
||||
return traefiktls.Certificate{
|
||||
CertFile: traefiktls.FileOrContent(c.leaf.cert),
|
||||
KeyFile: traefiktls.FileOrContent(c.leaf.key),
|
||||
CertFile: types.FileOrContent(c.leaf.cert),
|
||||
KeyFile: types.FileOrContent(c.leaf.key),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/provider"
|
||||
"github.com/traefik/traefik/v3/pkg/safe"
|
||||
"github.com/traefik/traefik/v3/pkg/tls"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
const providerName = "file"
|
||||
|
@ -180,7 +181,7 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem
|
|||
// TLS Options
|
||||
if configuration.TLS.Options != nil {
|
||||
for name, options := range configuration.TLS.Options {
|
||||
var caCerts []tls.FileOrContent
|
||||
var caCerts []types.FileOrContent
|
||||
|
||||
for _, caFile := range options.ClientAuth.CAFiles {
|
||||
content, err := caFile.Read()
|
||||
|
@ -189,7 +190,7 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem
|
|||
continue
|
||||
}
|
||||
|
||||
caCerts = append(caCerts, tls.FileOrContent(content))
|
||||
caCerts = append(caCerts, types.FileOrContent(content))
|
||||
}
|
||||
options.ClientAuth.CAFiles = caCerts
|
||||
|
||||
|
@ -209,14 +210,14 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem
|
|||
log.Ctx(ctx).Error().Err(err).Send()
|
||||
continue
|
||||
}
|
||||
store.DefaultCertificate.CertFile = tls.FileOrContent(content)
|
||||
store.DefaultCertificate.CertFile = types.FileOrContent(content)
|
||||
|
||||
content, err = store.DefaultCertificate.KeyFile.Read()
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Error().Err(err).Send()
|
||||
continue
|
||||
}
|
||||
store.DefaultCertificate.KeyFile = tls.FileOrContent(content)
|
||||
store.DefaultCertificate.KeyFile = types.FileOrContent(content)
|
||||
|
||||
configuration.TLS.Stores[name] = store
|
||||
}
|
||||
|
@ -233,21 +234,21 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem
|
|||
log.Ctx(ctx).Error().Err(err).Send()
|
||||
continue
|
||||
}
|
||||
cert.CertFile = tls.FileOrContent(content)
|
||||
cert.CertFile = types.FileOrContent(content)
|
||||
|
||||
content, err = cert.KeyFile.Read()
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Error().Err(err).Send()
|
||||
continue
|
||||
}
|
||||
cert.KeyFile = tls.FileOrContent(content)
|
||||
cert.KeyFile = types.FileOrContent(content)
|
||||
|
||||
certificates = append(certificates, cert)
|
||||
}
|
||||
|
||||
configuration.HTTP.ServersTransports[name].Certificates = certificates
|
||||
|
||||
var rootCAs []tls.FileOrContent
|
||||
var rootCAs []types.FileOrContent
|
||||
for _, rootCA := range st.RootCAs {
|
||||
content, err := rootCA.Read()
|
||||
if err != nil {
|
||||
|
@ -255,7 +256,7 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem
|
|||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, tls.FileOrContent(content))
|
||||
rootCAs = append(rootCAs, types.FileOrContent(content))
|
||||
}
|
||||
|
||||
st.RootCAs = rootCAs
|
||||
|
@ -275,21 +276,21 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem
|
|||
log.Ctx(ctx).Error().Err(err).Send()
|
||||
continue
|
||||
}
|
||||
cert.CertFile = tls.FileOrContent(content)
|
||||
cert.CertFile = types.FileOrContent(content)
|
||||
|
||||
content, err = cert.KeyFile.Read()
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Error().Err(err).Send()
|
||||
continue
|
||||
}
|
||||
cert.KeyFile = tls.FileOrContent(content)
|
||||
cert.KeyFile = types.FileOrContent(content)
|
||||
|
||||
certificates = append(certificates, cert)
|
||||
}
|
||||
|
||||
configuration.TCP.ServersTransports[name].TLS.Certificates = certificates
|
||||
|
||||
var rootCAs []tls.FileOrContent
|
||||
var rootCAs []types.FileOrContent
|
||||
for _, rootCA := range st.TLS.RootCAs {
|
||||
content, err := rootCA.Read()
|
||||
if err != nil {
|
||||
|
@ -297,7 +298,7 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem
|
|||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, tls.FileOrContent(content))
|
||||
rootCAs = append(rootCAs, types.FileOrContent(content))
|
||||
}
|
||||
|
||||
st.TLS.RootCAs = rootCAs
|
||||
|
@ -315,14 +316,14 @@ func flattenCertificates(ctx context.Context, tlsConfig *dynamic.TLSConfiguratio
|
|||
log.Ctx(ctx).Error().Err(err).Send()
|
||||
continue
|
||||
}
|
||||
cert.Certificate.CertFile = tls.FileOrContent(string(content))
|
||||
cert.Certificate.CertFile = types.FileOrContent(string(content))
|
||||
|
||||
content, err = cert.Certificate.KeyFile.Read()
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Error().Err(err).Send()
|
||||
continue
|
||||
}
|
||||
cert.Certificate.KeyFile = tls.FileOrContent(string(content))
|
||||
cert.Certificate.KeyFile = types.FileOrContent(string(content))
|
||||
|
||||
certs = append(certs, cert)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
traefikinformers "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions"
|
||||
traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
"github.com/traefik/traefik/v3/pkg/version"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kerror "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
@ -120,14 +121,19 @@ func newExternalClusterClientFromFile(file string) (*clientWrapper, error) {
|
|||
// newExternalClusterClient returns a new Provider client that may run outside
|
||||
// of the cluster.
|
||||
// The endpoint parameter must not be empty.
|
||||
func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrapper, error) {
|
||||
func newExternalClusterClient(endpoint, caFilePath string, token types.FileOrContent) (*clientWrapper, error) {
|
||||
if endpoint == "" {
|
||||
return nil, errors.New("endpoint missing for external cluster client")
|
||||
}
|
||||
|
||||
tokenData, err := token.Read()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read token: %w", err)
|
||||
}
|
||||
|
||||
config := &rest.Config{
|
||||
Host: endpoint,
|
||||
BearerToken: token,
|
||||
BearerToken: string(tokenData),
|
||||
}
|
||||
|
||||
if caFilePath != "" {
|
||||
|
|
|
@ -48,16 +48,16 @@ const (
|
|||
|
||||
// Provider holds configurations of the provider.
|
||||
type Provider struct {
|
||||
Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
||||
Token string `description:"Kubernetes bearer token (not needed for in-cluster client)." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
|
||||
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)." json:"certAuthFilePath,omitempty" toml:"certAuthFilePath,omitempty" yaml:"certAuthFilePath,omitempty"`
|
||||
Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"`
|
||||
AllowCrossNamespace bool `description:"Allow cross namespace resource reference." json:"allowCrossNamespace,omitempty" toml:"allowCrossNamespace,omitempty" yaml:"allowCrossNamespace,omitempty" export:"true"`
|
||||
AllowExternalNameServices bool `description:"Allow ExternalName services." json:"allowExternalNameServices,omitempty" toml:"allowExternalNameServices,omitempty" yaml:"allowExternalNameServices,omitempty" export:"true"`
|
||||
LabelSelector string `description:"Kubernetes label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
|
||||
IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"`
|
||||
ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"`
|
||||
AllowEmptyServices bool `description:"Allow the creation of services without endpoints." json:"allowEmptyServices,omitempty" toml:"allowEmptyServices,omitempty" yaml:"allowEmptyServices,omitempty" export:"true"`
|
||||
Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
||||
Token types.FileOrContent `description:"Kubernetes bearer token (not needed for in-cluster client). It accepts either a token value or a file path to the token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
|
||||
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)." json:"certAuthFilePath,omitempty" toml:"certAuthFilePath,omitempty" yaml:"certAuthFilePath,omitempty"`
|
||||
Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"`
|
||||
AllowCrossNamespace bool `description:"Allow cross namespace resource reference." json:"allowCrossNamespace,omitempty" toml:"allowCrossNamespace,omitempty" yaml:"allowCrossNamespace,omitempty" export:"true"`
|
||||
AllowExternalNameServices bool `description:"Allow ExternalName services." json:"allowExternalNameServices,omitempty" toml:"allowExternalNameServices,omitempty" yaml:"allowExternalNameServices,omitempty" export:"true"`
|
||||
LabelSelector string `description:"Kubernetes label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
|
||||
IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"`
|
||||
ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"`
|
||||
AllowEmptyServices bool `description:"Allow the creation of services without endpoints." json:"allowEmptyServices,omitempty" toml:"allowEmptyServices,omitempty" yaml:"allowEmptyServices,omitempty" export:"true"`
|
||||
|
||||
lastConfiguration safe.Safe
|
||||
|
||||
|
@ -101,7 +101,7 @@ func (p *Provider) newK8sClient(ctx context.Context) (*clientWrapper, error) {
|
|||
client, err = newExternalClusterClientFromFile(os.Getenv("KUBECONFIG"))
|
||||
default:
|
||||
log.Ctx(ctx).Info().Msgf("Creating cluster-external Provider client%s", withEndpoint)
|
||||
client, err = newExternalClusterClient(p.Endpoint, p.Token, p.CertAuthFilePath)
|
||||
client, err = newExternalClusterClient(p.Endpoint, p.CertAuthFilePath, p.Token)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -339,7 +339,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
|||
for _, serversTransport := range client.GetServersTransports() {
|
||||
logger := log.Ctx(ctx).With().Str(logs.ServersTransportName, serversTransport.Name).Logger()
|
||||
|
||||
var rootCAs []tls.FileOrContent
|
||||
var rootCAs []types.FileOrContent
|
||||
for _, secret := range serversTransport.Spec.RootCAsSecrets {
|
||||
caSecret, err := loadCASecret(serversTransport.Namespace, secret, client)
|
||||
if err != nil {
|
||||
|
@ -347,7 +347,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
|||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, tls.FileOrContent(caSecret))
|
||||
rootCAs = append(rootCAs, types.FileOrContent(caSecret))
|
||||
}
|
||||
|
||||
var certs tls.Certificates
|
||||
|
@ -359,8 +359,8 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
|||
}
|
||||
|
||||
certs = append(certs, tls.Certificate{
|
||||
CertFile: tls.FileOrContent(tlsSecret),
|
||||
KeyFile: tls.FileOrContent(tlsKey),
|
||||
CertFile: types.FileOrContent(tlsSecret),
|
||||
KeyFile: types.FileOrContent(tlsKey),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
|||
}
|
||||
|
||||
if serversTransportTCP.Spec.TLS != nil {
|
||||
var rootCAs []tls.FileOrContent
|
||||
var rootCAs []types.FileOrContent
|
||||
for _, secret := range serversTransportTCP.Spec.TLS.RootCAsSecrets {
|
||||
caSecret, err := loadCASecret(serversTransportTCP.Namespace, secret, client)
|
||||
if err != nil {
|
||||
|
@ -457,7 +457,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
|||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, tls.FileOrContent(caSecret))
|
||||
rootCAs = append(rootCAs, types.FileOrContent(caSecret))
|
||||
}
|
||||
|
||||
var certs tls.Certificates
|
||||
|
@ -472,8 +472,8 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
|||
}
|
||||
|
||||
certs = append(certs, tls.Certificate{
|
||||
CertFile: tls.FileOrContent(tlsCert),
|
||||
KeyFile: tls.FileOrContent(tlsKey),
|
||||
CertFile: types.FileOrContent(tlsCert),
|
||||
KeyFile: types.FileOrContent(tlsKey),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -963,7 +963,7 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options
|
|||
|
||||
for _, tlsOption := range tlsOptionsCRD {
|
||||
logger := log.Ctx(ctx).With().Str("tlsOption", tlsOption.Name).Str("namespace", tlsOption.Namespace).Logger()
|
||||
var clientCAs []tls.FileOrContent
|
||||
var clientCAs []types.FileOrContent
|
||||
|
||||
for _, secretName := range tlsOption.Spec.ClientAuth.SecretNames {
|
||||
secret, exists, err := client.GetSecret(tlsOption.Namespace, secretName)
|
||||
|
@ -983,7 +983,7 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options
|
|||
continue
|
||||
}
|
||||
|
||||
clientCAs = append(clientCAs, tls.FileOrContent(cert))
|
||||
clientCAs = append(clientCAs, types.FileOrContent(cert))
|
||||
}
|
||||
|
||||
id := makeID(tlsOption.Namespace, tlsOption.Name)
|
||||
|
@ -1063,8 +1063,8 @@ func buildTLSStores(ctx context.Context, client Client) (map[string]tls.Store, m
|
|||
}
|
||||
|
||||
tlsStore.DefaultCertificate = &tls.Certificate{
|
||||
CertFile: tls.FileOrContent(cert),
|
||||
KeyFile: tls.FileOrContent(key),
|
||||
CertFile: types.FileOrContent(cert),
|
||||
KeyFile: types.FileOrContent(key),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1149,8 +1149,8 @@ func getTLS(k8sClient Client, secretName, namespace string) (*tls.CertAndStores,
|
|||
|
||||
return &tls.CertAndStores{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent(cert),
|
||||
KeyFile: tls.FileOrContent(key),
|
||||
CertFile: types.FileOrContent(cert),
|
||||
KeyFile: types.FileOrContent(key),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -571,8 +571,8 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -673,9 +673,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
|||
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
|
@ -741,9 +741,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
|||
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
|
@ -809,8 +809,8 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
|||
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
|
@ -1064,8 +1064,8 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
|||
Stores: map[string]tls.Store{
|
||||
"default": {
|
||||
DefaultCertificate: &tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1405,7 +1405,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
|||
TLS: &dynamic.TLSClientConfig{
|
||||
ServerName: "test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []tls.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS"},
|
||||
RootCAs: []types.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS"},
|
||||
Certificates: tls.Certificates{
|
||||
{CertFile: "TESTCERT1", KeyFile: "TESTKEY1"},
|
||||
{CertFile: "TESTCERT2", KeyFile: "TESTKEY2"},
|
||||
|
@ -2917,8 +2917,8 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -2979,9 +2979,9 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
|
@ -3100,9 +3100,9 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
|
@ -3178,9 +3178,9 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
|
@ -3251,8 +3251,8 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
|
@ -3881,8 +3881,8 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
Stores: map[string]tls.Store{
|
||||
"default": {
|
||||
DefaultCertificate: &tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3938,8 +3938,8 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
Stores: []string{"default"},
|
||||
},
|
||||
|
@ -4215,7 +4215,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
"foo-test": {
|
||||
ServerName: "test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []tls.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS"},
|
||||
RootCAs: []types.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS"},
|
||||
Certificates: tls.Certificates{
|
||||
{CertFile: "TESTCERT1", KeyFile: "TESTKEY1"},
|
||||
{CertFile: "TESTCERT2", KeyFile: "TESTKEY2"},
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kerror "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -129,14 +130,19 @@ func newExternalClusterClientFromFile(file string) (*clientWrapper, error) {
|
|||
|
||||
// newExternalClusterClient returns a new Provider client that may run outside of the cluster.
|
||||
// The endpoint parameter must not be empty.
|
||||
func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrapper, error) {
|
||||
func newExternalClusterClient(endpoint, caFilePath string, token types.FileOrContent) (*clientWrapper, error) {
|
||||
if endpoint == "" {
|
||||
return nil, errors.New("endpoint missing for external cluster client")
|
||||
}
|
||||
|
||||
tokenData, err := token.Read()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read token: %w", err)
|
||||
}
|
||||
|
||||
config := &rest.Config{
|
||||
Host: endpoint,
|
||||
BearerToken: token,
|
||||
BearerToken: string(tokenData),
|
||||
}
|
||||
|
||||
if caFilePath != "" {
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s"
|
||||
"github.com/traefik/traefik/v3/pkg/safe"
|
||||
"github.com/traefik/traefik/v3/pkg/tls"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
@ -48,7 +49,7 @@ const (
|
|||
// Provider holds configurations of the provider.
|
||||
type Provider struct {
|
||||
Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
||||
Token string `description:"Kubernetes bearer token (not needed for in-cluster client)." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
|
||||
Token types.FileOrContent `description:"Kubernetes bearer token (not needed for in-cluster client). It accepts either a token value or a file path to the token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
|
||||
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)." json:"certAuthFilePath,omitempty" toml:"certAuthFilePath,omitempty" yaml:"certAuthFilePath,omitempty"`
|
||||
Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"`
|
||||
LabelSelector string `description:"Kubernetes label selector to select specific GatewayClasses." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
|
||||
|
@ -101,7 +102,7 @@ func (p *Provider) newK8sClient(ctx context.Context) (*clientWrapper, error) {
|
|||
client, err = newExternalClusterClientFromFile(os.Getenv("KUBECONFIG"))
|
||||
default:
|
||||
logger.Info().Str("endpoint", p.Endpoint).Msg("Creating cluster-external Provider client")
|
||||
client, err = newExternalClusterClient(p.Endpoint, p.Token, p.CertAuthFilePath)
|
||||
client, err = newExternalClusterClient(p.Endpoint, p.CertAuthFilePath, p.Token)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -1428,8 +1429,8 @@ func getTLS(k8sClient Client, secretName gatev1.ObjectName, namespace string) (*
|
|||
|
||||
return &tls.CertAndStores{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent(cert),
|
||||
KeyFile: tls.FileOrContent(key),
|
||||
CertFile: types.FileOrContent(cert),
|
||||
KeyFile: types.FileOrContent(key),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/provider"
|
||||
"github.com/traefik/traefik/v3/pkg/tls"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/utils/ptr"
|
||||
gatev1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
|
@ -492,8 +493,8 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -741,8 +742,8 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1176,8 +1177,8 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1265,8 +1266,8 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -2240,8 +2241,8 @@ func TestLoadTCPRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -2735,8 +2736,8 @@ func TestLoadTLSRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -2947,8 +2948,8 @@ func TestLoadTLSRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3016,8 +3017,8 @@ func TestLoadTLSRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3823,8 +3824,8 @@ func TestLoadMixedRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -4002,8 +4003,8 @@ func TestLoadMixedRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -4243,8 +4244,8 @@ func TestLoadMixedRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -4394,8 +4395,8 @@ func TestLoadMixedRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -4526,8 +4527,8 @@ func TestLoadMixedRoutes(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/hashicorp/go-version"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
traefikversion "github.com/traefik/traefik/v3/pkg/version"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
netv1 "k8s.io/api/networking/v1"
|
||||
|
@ -81,14 +82,19 @@ func newExternalClusterClientFromFile(file string) (*clientWrapper, error) {
|
|||
// newExternalClusterClient returns a new Provider client that may run outside
|
||||
// of the cluster.
|
||||
// The endpoint parameter must not be empty.
|
||||
func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrapper, error) {
|
||||
func newExternalClusterClient(endpoint, caFilePath string, token types.FileOrContent) (*clientWrapper, error) {
|
||||
if endpoint == "" {
|
||||
return nil, errors.New("endpoint missing for external cluster client")
|
||||
}
|
||||
|
||||
tokenData, err := token.Read()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read token: %w", err)
|
||||
}
|
||||
|
||||
config := &rest.Config{
|
||||
Host: endpoint,
|
||||
BearerToken: token,
|
||||
BearerToken: string(tokenData),
|
||||
}
|
||||
|
||||
if caFilePath != "" {
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s"
|
||||
"github.com/traefik/traefik/v3/pkg/safe"
|
||||
"github.com/traefik/traefik/v3/pkg/tls"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
netv1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
@ -39,17 +40,17 @@ const (
|
|||
|
||||
// Provider holds configurations of the provider.
|
||||
type Provider struct {
|
||||
Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
||||
Token string `description:"Kubernetes bearer token (not needed for in-cluster client)." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
|
||||
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)." json:"certAuthFilePath,omitempty" toml:"certAuthFilePath,omitempty" yaml:"certAuthFilePath,omitempty"`
|
||||
Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"`
|
||||
LabelSelector string `description:"Kubernetes Ingress label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
|
||||
IngressClass string `description:"Value of kubernetes.io/ingress.class annotation or IngressClass name to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"`
|
||||
IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint." json:"ingressEndpoint,omitempty" toml:"ingressEndpoint,omitempty" yaml:"ingressEndpoint,omitempty" export:"true"`
|
||||
ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"`
|
||||
AllowEmptyServices bool `description:"Allow creation of services without endpoints." json:"allowEmptyServices,omitempty" toml:"allowEmptyServices,omitempty" yaml:"allowEmptyServices,omitempty" export:"true"`
|
||||
AllowExternalNameServices bool `description:"Allow ExternalName services." json:"allowExternalNameServices,omitempty" toml:"allowExternalNameServices,omitempty" yaml:"allowExternalNameServices,omitempty" export:"true"`
|
||||
DisableIngressClassLookup bool `description:"Disables the lookup of IngressClasses." json:"disableIngressClassLookup,omitempty" toml:"disableIngressClassLookup,omitempty" yaml:"disableIngressClassLookup,omitempty" export:"true"`
|
||||
Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
|
||||
Token types.FileOrContent `description:"Kubernetes bearer token (not needed for in-cluster client). It accepts either a token value or a file path to the token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
|
||||
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)." json:"certAuthFilePath,omitempty" toml:"certAuthFilePath,omitempty" yaml:"certAuthFilePath,omitempty"`
|
||||
Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"`
|
||||
LabelSelector string `description:"Kubernetes Ingress label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
|
||||
IngressClass string `description:"Value of kubernetes.io/ingress.class annotation or IngressClass name to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"`
|
||||
IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint." json:"ingressEndpoint,omitempty" toml:"ingressEndpoint,omitempty" yaml:"ingressEndpoint,omitempty" export:"true"`
|
||||
ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"`
|
||||
AllowEmptyServices bool `description:"Allow creation of services without endpoints." json:"allowEmptyServices,omitempty" toml:"allowEmptyServices,omitempty" yaml:"allowEmptyServices,omitempty" export:"true"`
|
||||
AllowExternalNameServices bool `description:"Allow ExternalName services." json:"allowExternalNameServices,omitempty" toml:"allowExternalNameServices,omitempty" yaml:"allowExternalNameServices,omitempty" export:"true"`
|
||||
DisableIngressClassLookup bool `description:"Disables the lookup of IngressClasses." json:"disableIngressClassLookup,omitempty" toml:"disableIngressClassLookup,omitempty" yaml:"disableIngressClassLookup,omitempty" export:"true"`
|
||||
|
||||
lastConfiguration safe.Safe
|
||||
|
||||
|
@ -103,7 +104,7 @@ func (p *Provider) newK8sClient(ctx context.Context) (*clientWrapper, error) {
|
|||
cl, err = newExternalClusterClientFromFile(os.Getenv("KUBECONFIG"))
|
||||
default:
|
||||
logger.Info().Msgf("Creating cluster-external Provider client%s", withEndpoint)
|
||||
cl, err = newExternalClusterClient(p.Endpoint, p.Token, p.CertAuthFilePath)
|
||||
cl, err = newExternalClusterClient(p.Endpoint, p.CertAuthFilePath, p.Token)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -463,8 +464,8 @@ func getCertificates(ctx context.Context, ingress *netv1.Ingress, k8sClient Clie
|
|||
|
||||
tlsConfigs[configKey] = &tls.CertAndStores{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent(cert),
|
||||
KeyFile: tls.FileOrContent(key),
|
||||
CertFile: types.FileOrContent(cert),
|
||||
KeyFile: types.FileOrContent(key),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -877,8 +877,8 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
CertFile: types.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
|
||||
KeyFile: types.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1834,14 +1834,14 @@ func TestGetCertificates(t *testing.T) {
|
|||
result: map[string]*tls.CertAndStores{
|
||||
"testing-test-secret": {
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("tls-crt"),
|
||||
KeyFile: tls.FileOrContent("tls-key"),
|
||||
CertFile: types.FileOrContent("tls-crt"),
|
||||
KeyFile: types.FileOrContent("tls-key"),
|
||||
},
|
||||
},
|
||||
"testing-test-secret2": {
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("tls-crt"),
|
||||
KeyFile: tls.FileOrContent("tls-key"),
|
||||
CertFile: types.FileOrContent("tls-crt"),
|
||||
KeyFile: types.FileOrContent("tls-key"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -811,8 +811,8 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("foobar"),
|
||||
KeyFile: tls.FileOrContent("foobar"),
|
||||
CertFile: types.FileOrContent("foobar"),
|
||||
KeyFile: types.FileOrContent("foobar"),
|
||||
},
|
||||
Stores: []string{
|
||||
"foobar",
|
||||
|
@ -821,8 +821,8 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: tls.FileOrContent("foobar"),
|
||||
KeyFile: tls.FileOrContent("foobar"),
|
||||
CertFile: types.FileOrContent("foobar"),
|
||||
KeyFile: types.FileOrContent("foobar"),
|
||||
},
|
||||
Stores: []string{
|
||||
"foobar",
|
||||
|
@ -843,9 +843,9 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"foobar",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("foobar"),
|
||||
tls.FileOrContent("foobar"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("foobar"),
|
||||
types.FileOrContent("foobar"),
|
||||
},
|
||||
ClientAuthType: "foobar",
|
||||
},
|
||||
|
@ -868,9 +868,9 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"foobar",
|
||||
},
|
||||
ClientAuth: tls.ClientAuth{
|
||||
CAFiles: []tls.FileOrContent{
|
||||
tls.FileOrContent("foobar"),
|
||||
tls.FileOrContent("foobar"),
|
||||
CAFiles: []types.FileOrContent{
|
||||
types.FileOrContent("foobar"),
|
||||
types.FileOrContent("foobar"),
|
||||
},
|
||||
ClientAuthType: "foobar",
|
||||
},
|
||||
|
@ -885,14 +885,14 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Stores: map[string]tls.Store{
|
||||
"Store0": {
|
||||
DefaultCertificate: &tls.Certificate{
|
||||
CertFile: tls.FileOrContent("foobar"),
|
||||
KeyFile: tls.FileOrContent("foobar"),
|
||||
CertFile: types.FileOrContent("foobar"),
|
||||
KeyFile: types.FileOrContent("foobar"),
|
||||
},
|
||||
},
|
||||
"Store1": {
|
||||
DefaultCertificate: &tls.Certificate{
|
||||
CertFile: tls.FileOrContent("foobar"),
|
||||
KeyFile: tls.FileOrContent("foobar"),
|
||||
CertFile: types.FileOrContent("foobar"),
|
||||
KeyFile: types.FileOrContent("foobar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/muxer/tcp"
|
||||
"github.com/traefik/traefik/v3/pkg/safe"
|
||||
traefiktls "github.com/traefik/traefik/v3/pkg/tls"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
// Provider is the Tailscale certificates provider implementation. It receives
|
||||
|
@ -254,8 +255,8 @@ func (p *Provider) fetchCerts(ctx context.Context, domains []string) {
|
|||
|
||||
p.certByDomainMu.Lock()
|
||||
p.certByDomain[domain] = traefiktls.Certificate{
|
||||
CertFile: traefiktls.FileOrContent(cert),
|
||||
KeyFile: traefiktls.FileOrContent(key),
|
||||
CertFile: types.FileOrContent(cert),
|
||||
KeyFile: types.FileOrContent(key),
|
||||
}
|
||||
p.certByDomainMu.Unlock()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue