Skip to content

Commit

Permalink
vault driver: add base64 decode option
Browse files Browse the repository at this point in the history
  • Loading branch information
robert lestak committed Jul 17, 2024
1 parent c9647c9 commit 4f3759c
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 10 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ Annotations:
cert-manager-sync.lestak.sh/vault-role: "role-name" # HashiCorp Vault role name
cert-manager-sync.lestak.sh/vault-auth-method: "auth-method" # HashiCorp Vault auth method name
cert-manager-sync.lestak.sh/vault-path: "kv-name/path/to/secret" # HashiCorp Vault path to store cert
cert-manager-sync.lestak.sh/vault-base64-decode: "true" # base64 decode the cert before storing in Vault. Default is "false"
```

### Heroku
Expand Down Expand Up @@ -320,6 +320,7 @@ metadata:
cert-manager-sync.lestak.sh/vault-role: "role-name" # HashiCorp Vault role name
cert-manager-sync.lestak.sh/vault-auth-method: "auth-method" # HashiCorp Vault auth method name
cert-manager-sync.lestak.sh/vault-path: "kv-name/path/to/secret" # HashiCorp Vault path to store cert
cert-manager-sync.lestak.sh/vault-base64-decode: "true" # base64 decode the cert before storing in Vault. Default is "false"
cert-manager-sync.lestak.sh/max-sync-attempts: "5" # limit the number of retries to 5, after which you will need to manually resolve the underlying issue and reset/remove the failed-sync-attempts annotation
cert-manager-sync.lestak.sh/failed-sync-attempts: "0" # number of failed sync attempts, will be auto-filled by operator
cert-manager-sync.lestak.sh/next-retry: "2022-01-01T00:00:00Z" # next retry time (RFC3339), will be auto-filled by operator. Remove this if you want to retry immediately.
Expand Down
36 changes: 35 additions & 1 deletion pkg/tlssecret/tlssecret.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package tlssecret

import corev1 "k8s.io/api/core/v1"
import (
"encoding/base64"

log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
)

type Certificate struct {
SecretName string
Expand Down Expand Up @@ -32,3 +37,32 @@ func (c *Certificate) FullChain() []byte {
}
return c.Certificate
}

func (c *Certificate) Base64Decode() error {
l := log.WithFields(log.Fields{
"action": "Base64Decode",
})
var err error
if c.Ca != nil {
c.Ca, err = base64.StdEncoding.DecodeString(string(c.Ca))
if err != nil {
l.WithError(err).Errorf("error decoding ca")
return err
}
}
if c.Certificate != nil {
c.Certificate, err = base64.StdEncoding.DecodeString(string(c.Certificate))
if err != nil {
l.WithError(err).Errorf("error decoding certificate")
return err
}
}
if c.Key != nil {
c.Key, err = base64.StdEncoding.DecodeString(string(c.Key))
if err != nil {
l.WithError(err).Errorf("error decoding key")
return err
}
}
return nil
}
50 changes: 50 additions & 0 deletions pkg/tlssecret/tlssecret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"encoding/pem"
"fmt"
"math/big"
Expand Down Expand Up @@ -177,3 +178,52 @@ func TestFullChain(t *testing.T) {
})
}
}

func TestCertificate_Base64Decode(t *testing.T) {
tests := []struct {
name string
cert *Certificate
wantErr bool
}{
{
name: "All fields encoded correctly",
cert: &Certificate{
Ca: []byte(base64.StdEncoding.EncodeToString([]byte("CA Data"))),
Certificate: []byte(base64.StdEncoding.EncodeToString([]byte("Certificate Data"))),
Key: []byte(base64.StdEncoding.EncodeToString([]byte("Key Data"))),
},
wantErr: false,
},
{
name: "Certificate field encoded incorrectly",
cert: &Certificate{
Ca: []byte(base64.StdEncoding.EncodeToString([]byte("CA Data"))),
Certificate: []byte("Not Base64"),
Key: []byte(base64.StdEncoding.EncodeToString([]byte("Key Data"))),
},
wantErr: true,
},
{
name: "All fields nil",
cert: &Certificate{},
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.cert.Base64Decode()
if (err != nil) != tt.wantErr {
t.Errorf("Certificate.Base64Decode() error = %v, wantErr %v", err, tt.wantErr)
}
if !tt.wantErr {
// For the successful case, verify the decoded data
if tt.name == "All fields encoded correctly" {
if string(tt.cert.Ca) != "CA Data" || string(tt.cert.Certificate) != "Certificate Data" || string(tt.cert.Key) != "Key Data" {
t.Errorf("Certificate.Base64Decode() did not decode correctly")
}
}
}
})
}
}
26 changes: 18 additions & 8 deletions stores/vault/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ import (
)

type VaultStore struct {
Addr string
Namespace string
Role string
AuthMethod string
Path string
KubeToken string // auto-filled
Client *api.Client // auto-filled
Token string // auto-filled
Addr string
Namespace string
Role string
AuthMethod string
Path string
Base64Decode bool
KubeToken string // auto-filled
Client *api.Client // auto-filled
Token string // auto-filled
}

func kubeToken() string {
Expand Down Expand Up @@ -177,6 +178,9 @@ func (s *VaultStore) ParseCertificate(c *tlssecret.Certificate) error {
if c.Annotations[state.OperatorName+"/vault-auth-method"] != "" {
s.AuthMethod = c.Annotations[state.OperatorName+"/vault-auth-method"]
}
if c.Annotations[state.OperatorName+"/vault-base64-decode"] == "true" || c.Annotations[state.OperatorName+"/vault-b64dec"] == "true" {
s.Base64Decode = true
}
return nil
}

Expand Down Expand Up @@ -210,6 +214,12 @@ func (s *VaultStore) Update(secret *corev1.Secret) error {
l.WithError(err).Errorf("vault.NewToken error")
return err
}
if s.Base64Decode {
if err := c.Base64Decode(); err != nil {
l.WithError(err).Errorf("Base64Decode error")
return err
}
}
cd := map[string]interface{}{
"tls.crt": c.Certificate,
"tls.key": c.Key,
Expand Down

0 comments on commit 4f3759c

Please sign in to comment.