summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Dessaux2024-09-28 09:45:03 +0200
committerJulien Dessaux2024-09-28 09:45:03 +0200
commit0f7e13222d087d85c1afd67d22d36f544a39801d (patch)
tree72f935064914ba415d3a41b9c78ef638689d5083
parentchore(tfstate): initial import (diff)
downloadtfstated-0f7e13222d087d85c1afd67d22d36f544a39801d.tar.gz
tfstated-0f7e13222d087d85c1afd67d22d36f544a39801d.tar.bz2
tfstated-0f7e13222d087d85c1afd67d22d36f544a39801d.zip
feat(tfstate): bootstrap an http server that answers /healthz
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--cmd/tfstate/healthz.go12
-rw-r--r--cmd/tfstate/main.go93
-rw-r--r--cmd/tfstate/routes.go7
-rw-r--r--go.mod3
5 files changed, 116 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1788154
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+tfstate
diff --git a/cmd/tfstate/healthz.go b/cmd/tfstate/healthz.go
new file mode 100644
index 0000000..20c72c9
--- /dev/null
+++ b/cmd/tfstate/healthz.go
@@ -0,0 +1,12 @@
+package main
+
+import "net/http"
+
+func handleHealthz() http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Cache-Control", "no-store, no-cache")
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ _, _ = w.Write([]byte("{}"))
+ })
+}
diff --git a/cmd/tfstate/main.go b/cmd/tfstate/main.go
new file mode 100644
index 0000000..e0b33a5
--- /dev/null
+++ b/cmd/tfstate/main.go
@@ -0,0 +1,93 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "log"
+ "log/slog"
+ "net"
+ "net/http"
+ "os"
+ "os/signal"
+ "sync"
+ "time"
+)
+
+type Config struct {
+ Host string
+ Port string
+}
+
+func run(
+ ctx context.Context,
+ config *Config,
+ args []string,
+ getenv func(string) string,
+ stdin io.Reader,
+ stdout, stderr io.Writer,
+) error {
+ ctx, cancel := signal.NotifyContext(ctx, os.Interrupt)
+ defer cancel()
+
+ mux := http.NewServeMux()
+ addRoutes(
+ mux,
+ )
+ httpServer := &http.Server{
+ Addr: net.JoinHostPort(config.Host, config.Port),
+ Handler: mux,
+ }
+ go func() {
+ log.Printf("listening on %s\n", httpServer.Addr)
+ if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ fmt.Fprintf(os.Stderr, "error listening and serving: %+v\n", err)
+ }
+ }()
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-ctx.Done()
+ shutdownCtx := context.Background()
+ shutdownCtx, cancel := context.WithTimeout(shutdownCtx, 10*time.Second)
+ defer cancel()
+ if err := httpServer.Shutdown(shutdownCtx); err != nil {
+ fmt.Fprintf(os.Stderr, "error shutting down http server: %+v\n", err)
+ }
+ }()
+ wg.Wait()
+
+ return nil
+}
+
+func main() {
+ ctx := context.Background()
+
+ var opts *slog.HandlerOptions
+ if os.Getenv("TFSTATE_DEBUG") != "" {
+ opts = &slog.HandlerOptions{
+ AddSource: true,
+ Level: slog.LevelDebug,
+ }
+ }
+ logger := slog.New(slog.NewJSONHandler(os.Stdout, opts))
+ slog.SetDefault(logger)
+
+ config := Config{
+ Host: "0.0.0.0",
+ Port: "8080",
+ }
+
+ if err := run(
+ ctx,
+ &config,
+ os.Args,
+ os.Getenv,
+ os.Stdin,
+ os.Stdout, os.Stderr,
+ ); err != nil {
+ fmt.Fprintf(os.Stderr, "%+v\n", err)
+ os.Exit(1)
+ }
+}
diff --git a/cmd/tfstate/routes.go b/cmd/tfstate/routes.go
new file mode 100644
index 0000000..f583fc7
--- /dev/null
+++ b/cmd/tfstate/routes.go
@@ -0,0 +1,7 @@
+package main
+
+import "net/http"
+
+func addRoutes(mux *http.ServeMux) {
+ mux.Handle("GET /healthz", handleHealthz())
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..0fa79e2
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module git.adyxax.org/adyxax/tfstate
+
+go 1.23.1