Skip to content

Commit 81bf8d3

Browse files
committed
updated
1 parent f2696f7 commit 81bf8d3

File tree

5 files changed

+130
-214
lines changed

5 files changed

+130
-214
lines changed

pkg/kubernetes/auth_headers.go

Lines changed: 69 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,104 +3,110 @@ package kubernetes
33
import (
44
"encoding/base64"
55
"fmt"
6+
"strings"
67
)
78

89
// AuthType represents the type of Kubernetes authentication.
910
type AuthType string
11+
type ContextKey string
1012

1113
const (
1214
// AuthTypeToken represents token-based authentication.
1315
AuthTypeToken AuthType = "token"
1416
// AuthTypeClientCertificate represents client certificate authentication.
1517
AuthTypeClientCertificate AuthType = "client_certificate"
16-
// AuthTypeUnknown represents unknown or unsupported authentication type.
17-
AuthTypeUnknown AuthType = "unknown"
18-
AuthHeadersContextKey string = "k8s_auth_headers"
18+
// AuthHeadersContextKey is the context key for the Kubernetes authentication headers.
19+
AuthHeadersContextKey ContextKey = "k8s_auth_headers"
1920
)
2021

2122
// K8sAuthHeaders represents Kubernetes API authentication headers.
2223
type K8sAuthHeaders struct {
23-
// ClusterURL is the Kubernetes cluster URL.
24-
ClusterURL string
25-
// ClusterCertificateAuthorityData is the base64-encoded CA certificate.
26-
ClusterCertificateAuthorityData string
24+
// Server is the Kubernetes cluster URL.
25+
Server string
26+
// ClusterCertificateAuthorityData is the Certificate Authority data.
27+
CertificateAuthorityData []byte
2728
// AuthorizationToken is the optional bearer token for authentication.
2829
AuthorizationToken string
29-
// ClientCertificateData is the optional base64-encoded client certificate.
30-
ClientCertificateData string
31-
// ClientKeyData is the optional base64-encoded client key.
32-
ClientKeyData string
30+
// ClientCertificateData is the optional client certificate data.
31+
ClientCertificateData []byte
32+
// ClientKeyData is the optional client key data.
33+
ClientKeyData []byte
34+
// InsecureSkipTLSVerify is the optional flag to skip TLS verification.
35+
InsecureSkipTLSVerify bool
36+
}
37+
38+
// GetDecodedData decodes and returns the data.
39+
func GetDecodedData(data string) ([]byte, error) {
40+
return base64.StdEncoding.DecodeString(data)
3341
}
3442

3543
func NewK8sAuthHeadersFromHeaders(data map[string]any) (*K8sAuthHeaders, error) {
36-
authHeaders := &K8sAuthHeaders{}
3744
var ok bool
38-
authHeaders.ClusterURL, ok = data[string(CustomClusterURLHeader)].(string)
39-
if !ok || authHeaders.ClusterURL == "" {
40-
return nil, fmt.Errorf("%s header is required", CustomClusterURLHeader)
45+
var err error
46+
47+
// Initialize auth headers.
48+
authHeaders := &K8sAuthHeaders{
49+
InsecureSkipTLSVerify: false,
50+
}
51+
52+
// Get cluster URL from headers.
53+
authHeaders.Server, ok = data[string(CustomServerHeader)].(string)
54+
if !ok || authHeaders.Server == "" {
55+
return nil, fmt.Errorf("%s header is required", CustomServerHeader)
4156
}
4257

43-
authHeaders.ClusterCertificateAuthorityData, ok = data[string(CustomCertificateAuthorityDataHeader)].(string)
44-
if !ok || authHeaders.ClusterCertificateAuthorityData == "" {
58+
// Get certificate authority data from headers.
59+
certificateAuthorityDataBase64, ok := data[string(CustomCertificateAuthorityDataHeader)].(string)
60+
if !ok || certificateAuthorityDataBase64 == "" {
4561
return nil, fmt.Errorf("%s header is required", CustomCertificateAuthorityDataHeader)
4662
}
63+
// Decode certificate authority data.
64+
authHeaders.CertificateAuthorityData, err = GetDecodedData(certificateAuthorityDataBase64)
65+
if err != nil {
66+
return nil, fmt.Errorf("invalid certificate authority data: %w", err)
67+
}
68+
69+
// Get insecure skip TLS verify flag from headers.
70+
if data[string(CustomInsecureSkipTLSVerifyHeader)] != nil && strings.ToLower(data[string(CustomInsecureSkipTLSVerifyHeader)].(string)) == "true" {
71+
authHeaders.InsecureSkipTLSVerify = true
72+
}
4773

48-
// Token or client certificate and key data (optional).
74+
// Get authorization token from headers.
4975
authHeaders.AuthorizationToken, _ = data[string(CustomAuthorizationHeader)].(string)
50-
authHeaders.ClientCertificateData, _ = data[string(CustomClientCertificateDataHeader)].(string)
51-
authHeaders.ClientKeyData, _ = data[string(CustomClientKeyDataHeader)].(string)
5276

53-
// Check if either token auth or client certificate auth is provided
54-
hasTokenAuth := authHeaders.AuthorizationToken != ""
55-
hasClientCertAuth := authHeaders.ClientCertificateData != "" && authHeaders.ClientKeyData != ""
77+
// Get client certificate data from headers.
78+
clientCertificateDataBase64, _ := data[string(CustomClientCertificateDataHeader)].(string)
79+
if clientCertificateDataBase64 != "" {
80+
authHeaders.ClientCertificateData, err = GetDecodedData(clientCertificateDataBase64)
81+
if err != nil {
82+
return nil, fmt.Errorf("invalid client certificate data: %w", err)
83+
}
84+
}
85+
// Get client key data from headers.
86+
clientKeyDataBase64, _ := data[string(CustomClientKeyDataHeader)].(string)
87+
if clientKeyDataBase64 != "" {
88+
authHeaders.ClientKeyData, err = GetDecodedData(clientKeyDataBase64)
89+
if err != nil {
90+
return nil, fmt.Errorf("invalid client key data: %w", err)
91+
}
92+
}
5693

57-
if !hasTokenAuth && !hasClientCertAuth {
58-
return nil, fmt.Errorf("either %s header or (%s and %s) headers are required", CustomAuthorizationHeader, CustomClientCertificateDataHeader, CustomClientKeyDataHeader)
94+
// Check if a valid authentication type is provided.
95+
_, err = authHeaders.GetAuthType()
96+
if err != nil {
97+
return nil, fmt.Errorf("either %s header for token authentication or (%s and %s) headers for client certificate authentication required", CustomAuthorizationHeader, CustomClientCertificateDataHeader, CustomClientKeyDataHeader)
5998
}
6099

61100
return authHeaders, nil
62101
}
63102

64103
// GetAuthType returns the authentication type based on the provided headers.
65-
func (h *K8sAuthHeaders) GetAuthType() AuthType {
104+
func (h *K8sAuthHeaders) GetAuthType() (AuthType, error) {
66105
if h.AuthorizationToken != "" {
67-
return AuthTypeToken
106+
return AuthTypeToken, nil
68107
}
69-
if h.ClientCertificateData != "" && h.ClientKeyData != "" {
70-
return AuthTypeClientCertificate
108+
if h.ClientCertificateData != nil && h.ClientKeyData != nil {
109+
return AuthTypeClientCertificate, nil
71110
}
72-
return AuthTypeUnknown
111+
return "", fmt.Errorf("invalid authentication type")
73112
}
74-
75-
// GetDecodedCertificateAuthorityData decodes and returns the CA certificate data.
76-
func (h *K8sAuthHeaders) GetDecodedCertificateAuthorityData() ([]byte, error) {
77-
data, err := base64.StdEncoding.DecodeString(h.ClusterCertificateAuthorityData)
78-
if err != nil {
79-
return nil, fmt.Errorf("failed to decode certificate authority data: %w", err)
80-
}
81-
return data, nil
82-
}
83-
84-
// // GetDecodedClientCertificateData decodes and returns the client certificate data.
85-
// func (h *K8sAuthHeaders) GetDecodedClientCertificateData() ([]byte, error) {
86-
// if h.ClientCertificateData == nil || *h.ClientCertificateData == "" {
87-
// return nil, errors.New("client certificate data is not available")
88-
// }
89-
// data, err := base64.StdEncoding.DecodeString(*h.ClientCertificateData)
90-
// if err != nil {
91-
// return nil, fmt.Errorf("failed to decode client certificate data: %w", err)
92-
// }
93-
// return data, nil
94-
// }
95-
96-
// // GetDecodedClientKeyData decodes and returns the client key data.
97-
// func (h *K8sAuthHeaders) GetDecodedClientKeyData() ([]byte, error) {
98-
// if h.ClientKeyData == nil || *h.ClientKeyData == "" {
99-
// return nil, errors.New("client key data is not available")
100-
// }
101-
// data, err := base64.StdEncoding.DecodeString(*h.ClientKeyData)
102-
// if err != nil {
103-
// return nil, fmt.Errorf("failed to decode client key data: %w", err)
104-
// }
105-
// return data, nil
106-
// }

pkg/kubernetes/kubernetes.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@ import (
1212
type HeaderKey string
1313

1414
const (
15-
CustomClusterURLHeader = HeaderKey("kubernetes-cluster-url")
16-
CustomAuthorizationHeader = HeaderKey("kubernetes-authorization")
15+
// CustomServerHeader is the Kubernetes cluster URL.
16+
CustomServerHeader = HeaderKey("kubernetes-server")
1717
// CustomCertificateAuthorityData is the base64-encoded CA certificate.
1818
CustomCertificateAuthorityDataHeader = HeaderKey("kubernetes-certificate-authority-data")
19+
// CustomAuthorizationHeader is the optional bearer token for authentication.
20+
CustomAuthorizationHeader = HeaderKey("kubernetes-authorization")
1921
// CustomClientCertificateData is the base64-encoded client certificate.
2022
CustomClientCertificateDataHeader = HeaderKey("kubernetes-client-certificate-data")
2123
// CustomClientKeyData is the base64-encoded client key.
2224
CustomClientKeyDataHeader = HeaderKey("kubernetes-client-key-data")
25+
// CustomInsecureSkipTLSVerify is the optional flag to skip TLS verification.
26+
CustomInsecureSkipTLSVerifyHeader = HeaderKey("kubernetes-insecure-skip-tls-verify")
2327

2428
OAuthAuthorizationHeader = HeaderKey("Authorization")
2529

pkg/kubernetes/manager.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,43 @@ func NewInClusterManager(config *config.StaticConfig) (*Manager, error) {
9191
return newManager(config, restConfig, clientcmd.NewDefaultClientConfig(*clientCmdConfig, nil))
9292
}
9393

94+
func NewAuthHeadersClusterManager(authHeaders *K8sAuthHeaders, config *config.StaticConfig) (*Manager, error) {
95+
96+
var certData []byte = nil
97+
if len(authHeaders.ClientCertificateData) > 0 {
98+
certData = authHeaders.ClientCertificateData
99+
}
100+
101+
var keyData []byte = nil
102+
if len(authHeaders.ClientKeyData) > 0 {
103+
keyData = authHeaders.ClientKeyData
104+
}
105+
106+
restConfig := &rest.Config{
107+
Host: authHeaders.Server,
108+
BearerToken: authHeaders.AuthorizationToken,
109+
TLSClientConfig: rest.TLSClientConfig{
110+
Insecure: authHeaders.InsecureSkipTLSVerify,
111+
CAData: authHeaders.CertificateAuthorityData,
112+
CertData: certData,
113+
KeyData: keyData,
114+
},
115+
}
116+
// Create a dummy kubeconfig clientcmdapi.Config for in-cluster config to be used in places where clientcmd.ClientConfig is required
117+
clientCmdConfig := clientcmdapi.NewConfig()
118+
clientCmdConfig.Clusters["cluster"] = &clientcmdapi.Cluster{
119+
Server: authHeaders.Server,
120+
InsecureSkipTLSVerify: authHeaders.InsecureSkipTLSVerify,
121+
}
122+
clientCmdConfig.AuthInfos["user"] = &clientcmdapi.AuthInfo{
123+
Token: authHeaders.AuthorizationToken,
124+
ClientCertificateData: certData,
125+
ClientKeyData: keyData,
126+
}
127+
128+
return newManager(config, restConfig, clientcmd.NewDefaultClientConfig(*clientCmdConfig, nil))
129+
}
130+
94131
func newManager(config *config.StaticConfig, restConfig *rest.Config, clientCmdConfig clientcmd.ClientConfig) (*Manager, error) {
95132
k8s := &Manager{
96133
staticConfig: config,

0 commit comments

Comments
 (0)