in pkg/plugin/healthz.go [53:138]
func (h *HealthZ) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
mlog.Trace("Started health check")
ctx, cancel := context.WithTimeout(context.Background(), h.RPCTimeout)
defer cancel()
conn, err := h.dialUnixSocket()
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
defer conn.Close()
// create the kms client for v1
kmsClient := kmsv1.NewKeyManagementServiceClient(conn)
// create the kms client for v2
kmsV2Client := kmsv2.NewKeyManagementServiceClient(conn)
// check version response against KMS-Plugin's gRPC endpoint.
err = h.checkRPC(ctx, kmsClient, kmsV2Client)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// Both encryption and decryption calls are made for each version,
// resulting in a total of 4 calls to the keyvault.
// Additionally, a health check is performed every 10 seconds.
// v1 checks
// check the configured keyvault, key, key version and permissions are still
// valid to encrypt and decrypt with test data.
enc, err := h.KMSv1Server.Encrypt(ctx, &kmsv1.EncryptRequest{Plain: []byte(healthCheckPlainText)})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
dec, err := h.KMSv1Server.Decrypt(ctx, &kmsv1.DecryptRequest{Cipher: enc.Cipher})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if string(dec.Plain) != healthCheckPlainText {
http.Error(w, "plain text mismatch after decryption", http.StatusInternalServerError)
return
}
// v2 checks.
// appending a string to UUID allows us to differentiate the UUIDs generated by us from those generated by the API server.
uid := "local-healthz-check-" + string(uuid.NewUUID())
v2EncryptResponse, err := h.KMSv2Server.Encrypt(
ctx,
&kmsv2.EncryptRequest{
Plaintext: []byte(healthCheckPlainText),
Uid: uid,
},
)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
v2DecryptResponse, err := h.KMSv2Server.Decrypt(ctx, &kmsv2.DecryptRequest{
Ciphertext: v2EncryptResponse.Ciphertext,
KeyId: v2EncryptResponse.KeyId,
Uid: uid, // passing the same uid to track roundtrip encrypt/decrypt calls
Annotations: v2EncryptResponse.Annotations,
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if string(v2DecryptResponse.Plaintext) != healthCheckPlainText {
http.Error(w, "plain text mismatch after decryption with KMSv2", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
if _, err = w.Write([]byte("ok")); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
mlog.Trace("Completed health check")
}