package main import ( "context" "encoding/json" "fmt" "log" "net" "net/http" "os" "strings" "time" ) // Terraform Registry Protocol Structs type Discovery struct { ProvidersV1 string `json:"providers.v1"` } type VersionList struct { ID string `json:"id"` Versions []Version `json:"versions"` Warnings []string `json:"warnings"` } type Version struct { Version string `json:"version"` Protocols []string `json:"protocols"` Platforms []Platform `json:"platforms"` } type Platform struct { OS string `json:"os"` Arch string `json:"arch"` } type DownloadResponse struct { Protocols []string `json:"protocols"` OS string `json:"os"` Arch string `json:"arch"` Filename string `json:"filename"` DownloadURL string `json:"download_url"` ShasumsURL string `json:"shasums_url"` ShasumsSignatureURL string `json:"shasums_signature_url"` Shasum string `json:"shasum"` SigningKeys SigningKeys `json:"signing_keys"` } type SigningKeys struct { GPGPublicKeys []GPGPublicKey `json:"gpg_public_keys"` } type GPGPublicKey struct { KeyID string `json:"key_id"` ASCIIArmor string `json:"ascii_armor"` } func discoveryHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(Discovery{ProvidersV1: "/v1/providers/"}) } func rootHandler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") tmpl, _ := templateFS.ReadFile("index.html") html := strings.Replace(string(tmpl), "{{.Version}}", VERSION, 1) fmt.Fprint(w, html) } func healthzHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("ok")) } func readyzHandler(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) defer cancel() _, err := s3Client.BucketExists(ctx, bucketName) if err != nil { msg := fmt.Sprintf("s3 unreachable: %v", err) log.Printf("readyz: %s", msg) w.WriteHeader(http.StatusServiceUnavailable) w.Write([]byte(msg)) return } w.WriteHeader(http.StatusOK) w.Write([]byte("ok")) } func debugHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, "=== ENV ===\n") for _, e := range os.Environ() { if strings.Contains(e, "S3_") || strings.Contains(e, "REGISTRY") || strings.Contains(e, "PORT") { fmt.Fprintln(w, e) } } s3ep := os.Getenv("S3_ENDPOINT") fmt.Fprintf(w, "\n=== DNS: %s ===\n", s3ep) addrs, err := net.LookupHost(s3ep) if err != nil { fmt.Fprintf(w, "DNS ERROR: %v\n", err) } else { for _, a := range addrs { fmt.Fprintf(w, " %s\n", a) } } fmt.Fprintf(w, "\n=== TCP dial: %s:443 ===\n", s3ep) conn, err := net.DialTimeout("tcp", s3ep+":443", 5*time.Second) if err != nil { fmt.Fprintf(w, "TCP ERROR: %v\n", err) } else { fmt.Fprintf(w, "TCP OK: %s -> %s\n", conn.LocalAddr(), conn.RemoteAddr()) conn.Close() } fmt.Fprintf(w, "\n=== S3 BucketExists ===\n") ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second) defer cancel() _, err = s3Client.BucketExists(ctx, bucketName) if err != nil { fmt.Fprintf(w, "S3 ERROR: %v\n", err) } else { fmt.Fprintf(w, "S3 OK: bucket %s accessible\n", bucketName) } }