quorate/services/mirrored-image/k8s/bootstrap/vault-tests.fsx

124 lines
4.3 KiB
Text
Raw Normal View History

#load "gateway.fsx"
open System
open System.IO
open System.Net
open System.Net.Http
open System.Text
open System.Text.Json
open System.Threading
open System.Threading.Tasks
open Gateway
let require condition message =
if not condition then
invalidOp message
type VaultHandler() =
inherit HttpMessageHandler()
let seen = ResizeArray<string * string>()
member _.Seen = seen
member private _.Respond(request: HttpRequestMessage) =
let path = request.RequestUri.AbsolutePath
let body =
if path = "/v1/auth/kubernetes/login" then
use document = JsonDocument.Parse(request.Content.ReadAsStream())
require (document.RootElement.GetProperty("role").GetString() = "bootstrap") "Vault role changed"
require
(document.RootElement.GetProperty("jwt").GetString() = "service-account-jwt")
"Vault JWT changed"
"""{"auth":{"client_token":"vault-token"}}"""
elif request.Method = HttpMethod.Get then
let token = request.Headers.GetValues("X-Vault-Token") |> Seq.exactlyOne
seen.Add(path, token)
"""{"data":{"data":{"token":"stored"}}}"""
else
let token = request.Headers.GetValues("X-Vault-Token") |> Seq.exactlyOne
seen.Add(path, token)
use document = JsonDocument.Parse(request.Content.ReadAsStream())
require
(document.RootElement.GetProperty("data").GetProperty("token").GetString() = "issued")
"Vault write did not use a KVv2 envelope"
"{}"
let response = new HttpResponseMessage(HttpStatusCode.OK)
response.Content <- new StringContent(body, Encoding.UTF8, "application/json")
response
override this.Send(request: HttpRequestMessage, _: CancellationToken) = this.Respond request
override this.SendAsync(request: HttpRequestMessage, _: CancellationToken) =
let response = this.Respond request
Task.FromResult response
type KubeHandler() =
inherit HttpMessageHandler()
member private _.Respond(request: HttpRequestMessage) =
require
(request.RequestUri.AbsolutePath = "/api/v1/namespaces/zitadel/secrets/zitadel-login-service-key")
"Kubernetes Secret path changed"
require (request.Headers.Authorization.Scheme = "Bearer") "Kubernetes bearer token was omitted"
require (request.Headers.Authorization.Parameter = "service-account-jwt") "Kubernetes bearer token changed"
let encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes "private-key")
let response = new HttpResponseMessage(HttpStatusCode.OK)
response.Content <-
new StringContent($"{{\"data\":{{\"tls.key\":\"{encoded}\"}}}}", Encoding.UTF8, "application/json")
response
override this.Send(request: HttpRequestMessage, _: CancellationToken) = this.Respond request
override this.SendAsync(request: HttpRequestMessage, _: CancellationToken) = Task.FromResult(this.Respond request)
let jwtPath = Path.GetTempFileName()
try
File.WriteAllText(jwtPath, "service-account-jwt")
let handler = new VaultHandler()
let config =
{ URL = "http://vault"
Role = "bootstrap"
JwtPath = jwtPath
CaPath = "" }
use vaultClient = new HttpClient(handler, true)
let store = makeStoreWith vaultClient config
require
(store.Read "secret/data/test" = Map.ofList (List.singleton ("token", "stored")))
"Vault secret was not decoded"
store.Write "secret/data/test" (Map.ofList (List.singleton ("token", "issued")))
require
(handler.Seen |> Seq.forall (fun (_, token) -> token = "vault-token"))
"Vault operation omitted its client token"
use kubeClient = new HttpClient(new KubeHandler(), true)
let key =
readKubeKeyWith
kubeClient
{ URL = "http://kubernetes"
TokenPath = jwtPath
CaPath = ""
Namespace = "zitadel"
Secret = "zitadel-login-service-key" }
require (key = "private-key") "Kubernetes Secret key was not decoded"
printfn "bootstrap HTTP tests passed"
finally
File.Delete jwtPath