Skip to content

Commit

Permalink
Add reloading of changed TLS key/cert
Browse files Browse the repository at this point in the history
  • Loading branch information
choffmeister committed Aug 15, 2023
1 parent 86378c9 commit 6c16b4d
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
2 changes: 1 addition & 1 deletion deploy/kubernetes/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ spec:
labels:
app: kube-resourceless
spec:
terminationGracePeriodSeconds: 3
containers:
- name: kube-resourceless
image: ghcr.io/airfocusio/kube-resourceless:latest
volumeMounts:
- name: tls
mountPath: "/etc/certs"
readOnly: true
terminationGracePeriodSeconds: 3
volumes:
- name: tls
secret:
Expand Down
35 changes: 35 additions & 0 deletions internal/certloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// see https://stackoverflow.com/questions/37473201/is-there-a-way-to-update-the-tls-certificates-in-a-net-http-server-without-any-d
package internal

import (
"crypto/tls"
"fmt"
"os"
"time"
)

type CertLoader struct {
CertFile string
KeyFile string
cachedCert *tls.Certificate
cachedCertModTime time.Time
}

func (cr *CertLoader) GetCertificate(h *tls.ClientHelloInfo) (*tls.Certificate, error) {
stat, err := os.Stat(cr.KeyFile)
if err != nil {
return nil, fmt.Errorf("failed checking key file modification time: %w", err)
}

if cr.cachedCert == nil || stat.ModTime().After(cr.cachedCertModTime) {
pair, err := tls.LoadX509KeyPair(cr.CertFile, cr.KeyFile)
if err != nil {
return nil, fmt.Errorf("failed loading tls key pair: %w", err)
}

cr.cachedCert = &pair
cr.cachedCertModTime = stat.ModTime()
}

return cr.cachedCert, nil
}
21 changes: 19 additions & 2 deletions internal/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package internal

import (
"context"
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
Expand Down Expand Up @@ -76,14 +77,30 @@ func NewService(opts ServiceOpts) (*Service, error) {
}

func (s *Service) Run(stop <-chan os.Signal) error {
Info.Printf("starting server...\n")

certLoader := CertLoader{
CertFile: s.Opts.TLSCertFile,
KeyFile: s.Opts.TLSKeyFile,
}
tlsConfig := &tls.Config{
GetCertificate: certLoader.GetCertificate,
}
tlsListener, err := tls.Listen("tcp", ":8443", tlsConfig)
if err != nil {
Error.Printf("listening failed: %v\n", err)
return err
}

http.HandleFunc("/mutate", func(w http.ResponseWriter, r *http.Request) {
s.ServeAdmitHandler(w, r, AdmitHandler(s.Mutate))
})
Info.Printf("starting server...\n")
if err := http.ListenAndServeTLS(":8443", s.Opts.TLSCertFile, s.Opts.TLSKeyFile, nil); err != nil {

if err := http.Serve(tlsListener, nil); err != nil {
Error.Printf("starting server failed: %v\n", err)
return err
}

return nil
}

Expand Down
1 change: 1 addition & 0 deletions test/examples/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ spec:
labels:
app: deplpoyment
spec:
terminationGracePeriodSeconds: 1
containers:
- name: container-1
image: nginx:alpine
Expand Down

0 comments on commit 6c16b4d

Please sign in to comment.