Browse Source

refactoring to implement changes suggested in pull request 265 ,namely, 1) fetch client certificate and key as tls k8s secrets and 2) pass them directly to TLSClientConfig avoiding storing in disk

ric 4 years ago
parent
commit
44ef7756ef

+ 1 - 1
apis/externalsecrets/v1alpha1/secretstore_vault_types.go

@@ -173,7 +173,7 @@ type VaultCertAuth struct {
 	// ClientCert is a certificate to authenticate using the Cert Vault
 	// ClientCert is a certificate to authenticate using the Cert Vault
 	// authentication method
 	// authentication method
 	// +optional
 	// +optional
-	ClientCert string `json:"clientCert"`
+	ClientCert esmeta.SecretKeySelector `json:"clientCert,omitempty"`
 
 
 	// SecretRef to a key in a Secret resource containing client private key to
 	// SecretRef to a key in a Secret resource containing client private key to
 	// authenticate with Vault using the Cert authentication method
 	// authenticate with Vault using the Cert authentication method

+ 1 - 0
apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go

@@ -828,6 +828,7 @@ func (in *VaultAuth) DeepCopy() *VaultAuth {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *VaultCertAuth) DeepCopyInto(out *VaultCertAuth) {
 func (in *VaultCertAuth) DeepCopyInto(out *VaultCertAuth) {
 	*out = *in
 	*out = *in
+	in.ClientCert.DeepCopyInto(&out.ClientCert)
 	in.SecretRef.DeepCopyInto(&out.SecretRef)
 	in.SecretRef.DeepCopyInto(&out.SecretRef)
 }
 }
 
 

+ 20 - 1
deploy/crds/external-secrets.io_clustersecretstores.yaml

@@ -349,7 +349,26 @@ spec:
                               clientCert:
                               clientCert:
                                 description: ClientCert is a certificate to authenticate
                                 description: ClientCert is a certificate to authenticate
                                   using the Cert Vault authentication method
                                   using the Cert Vault authentication method
-                                type: string
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               secretRef:
                               secretRef:
                                 description: SecretRef to a key in a Secret resource
                                 description: SecretRef to a key in a Secret resource
                                   containing client private key to authenticate with
                                   containing client private key to authenticate with

+ 20 - 1
deploy/crds/external-secrets.io_secretstores.yaml

@@ -349,7 +349,26 @@ spec:
                               clientCert:
                               clientCert:
                                 description: ClientCert is a certificate to authenticate
                                 description: ClientCert is a certificate to authenticate
                                   using the Cert Vault authentication method
                                   using the Cert Vault authentication method
-                                type: string
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
                               secretRef:
                               secretRef:
                                 description: SecretRef to a key in a Secret resource
                                 description: SecretRef to a key in a Secret resource
                                   containing client private key to authenticate with
                                   containing client private key to authenticate with

+ 8 - 63
pkg/provider/vault/vault.go

@@ -16,8 +16,8 @@ package vault
 
 
 import (
 import (
 	"context"
 	"context"
+	"crypto/tls"
 	"crypto/x509"
 	"crypto/x509"
-	b64 "encoding/base64"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
@@ -45,7 +45,6 @@ var (
 
 
 const (
 const (
 	serviceAccTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
 	serviceAccTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
-	certsBasePath = "/auth-certs/"
 
 
 	errVaultStore     = "received invalid Vault SecretStore resource: %w"
 	errVaultStore     = "received invalid Vault SecretStore resource: %w"
 	errVaultClient    = "cannot setup new vault client: %w"
 	errVaultClient    = "cannot setup new vault client: %w"
@@ -350,7 +349,6 @@ func (v *client) secretKeyRef(ctx context.Context, secretRef *esmeta.SecretKeySe
 	}
 	}
 
 
 	value := string(keyBytes)
 	value := string(keyBytes)
-
 	valueStr := strings.TrimSpace(value)
 	valueStr := strings.TrimSpace(value)
 	return valueStr, nil
 	return valueStr, nil
 }
 }
@@ -523,7 +521,7 @@ func (v *client) requestTokenWithJwtAuth(ctx context.Context, client Client, jwt
 		"role": role,
 		"role": role,
 		"jwt":  jwt,
 		"jwt":  jwt,
 	}
 	}
-	url := strings.Join([]string{"/v1", "auth", "cert", "login"}, "/")
+	url := strings.Join([]string{"/v1", "auth", "jwt", "login"}, "/")
 	request := client.NewRequest("POST", url)
 	request := client.NewRequest("POST", url)
 
 
 	err = request.SetJSONBody(parameters)
 	err = request.SetJSONBody(parameters)
@@ -558,26 +556,14 @@ func (v *client) requestTokenWithCertAuth(ctx context.Context, client Client, ce
 		return "", err
 		return "", err
 	}
 	}
 
 
-	clientKeyPath, err := getCertPath(clientKey, "client.key")
-	if err != nil {
-		return "", fmt.Errorf(errGetCertPath, err)
-	}
-
-	clientCertPath, err := getCertPath(certAuth.ClientCert, "client.crt")
+	clientCert, err := v.secretKeyRef(ctx, &certAuth.ClientCert)
 	if err != nil {
 	if err != nil {
-		return "", fmt.Errorf(errGetCertPath, err)
-	}
-
-
-	tlscfg := vault.TLSConfig{
-		ClientCert: clientCertPath,
-		ClientKey:  clientKeyPath,
+		return "", err
 	}
 	}
 
 
-	err = cfg.ConfigureTLS(&tlscfg)
-
-	if err != nil {
-		return "", fmt.Errorf(errVaultCert, err)
+	cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
+	if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
+		transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
 	}
 	}
 
 
 	url := strings.Join([]string{"/v1", "auth", "cert", "login"}, "/")
 	url := strings.Join([]string{"/v1", "auth", "cert", "login"}, "/")
@@ -601,45 +587,4 @@ func (v *client) requestTokenWithCertAuth(ctx context.Context, client Client, ce
 	}
 	}
 
 
 	return token, nil
 	return token, nil
-}
-
-func getCertPath(cert, filename string) (string, error) {
-
-	certPath := certsBasePath + filename
-
-	if _, err := os.Stat(certsBasePath); os.IsNotExist(err) {
-		_, err := MkdirToStoreCertificate(certsBasePath)
-		return "", err
-	}
-
-	f, err := os.Create(certPath)
-	if err != nil {
-		return "", fmt.Errorf(errOsCreateFile, err)
-	}
-
-	defer f.Close()
-
-	if filename == "client.crt" || filename == "ca.crt" {
-
-		decodedCert, err := b64.StdEncoding.DecodeString(cert)
-		if err != nil {
-			return "", fmt.Errorf(errCertDecode, err)
-		}
-		cert = string(decodedCert)
-	}
-	_, err = f.WriteString(cert)
-	if err != nil {
-		return "", fmt.Errorf(errWriteCertToFile, err)
-	}
-
-	return certPath, nil
-}
-
-func MkdirToStoreCertificate(clientCertsBasePath string) (string, error) {
-
-	if err := os.MkdirAll(clientCertsBasePath, 0700); err != nil {
-		return "", fmt.Errorf(errCertMkdir, err)
-	}
-
-	return "", nil
-}
+}