blob: 2603eaef2d50cae15ca2c09e9115760cc1c95c63 [file] [log] [blame]
package main
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
)
// test1InClusterKubernetes exercises connectivity to the cluster-local
// Kubernetes API server. It expects to be able to connect to the APIserver using
// the ServiceAccount and cluster CA injected by the Kubelet.
//
// The entire functionality is reimplemented without relying on Kubernetes
// client code to make the expected behaviour clear.
func test1InClusterKubernetes(ctx context.Context) error {
token, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token")
if err != nil {
return fmt.Errorf("failed to read serviceaccount token: %w", err)
}
cacert, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt")
if err != nil {
return fmt.Errorf("failed to read cluster CA certificate: %w", err)
}
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(cacert)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: pool,
},
},
}
req, err := http.NewRequestWithContext(ctx, "GET", "https://kubernetes.default.svc.cluster.local/api", nil)
if err != nil {
return fmt.Errorf("creating request failed: %w", err)
}
req.Header.Set("Authorization", "Bearer "+string(token))
res, err := client.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer res.Body.Close()
j := struct {
Kind string `json:"kind"`
Message string `json:"message"`
}{}
if err := json.NewDecoder(res.Body).Decode(&j); err != nil {
return fmt.Errorf("json parse error: %w", err)
}
if j.Kind == "Status" {
return fmt.Errorf("API server responded with error: %q", j.Message)
}
if j.Kind != "APIVersions" {
return fmt.Errorf("unexpected response from server (kind: %q)", j.Kind)
}
return nil
}
func main() {
log.Printf("Metropolis Kubernetes self-test starting...")
ctx, ctxC := context.WithTimeout(context.Background(), 10*time.Second)
defer ctxC()
log.Printf("1. In-cluster Kubernetes client...")
if err := test1InClusterKubernetes(ctx); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
log.Printf("All tests passed.")
}