diff --git a/cgat b/cgat new file mode 100755 index 0000000000000000000000000000000000000000..7437e90723a9340dd1e3872e78ba87ef32c949b1 Binary files /dev/null and b/cgat differ diff --git a/cgat.sh b/cgat.sh deleted file mode 100755 index 9e455f717f9609e2c7d1d0416606f46c24bdb104..0000000000000000000000000000000000000000 --- a/cgat.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -openssl req -nodes -new -x509 -subj '/CN=spilo.dummy.org' -keyout /etc/ssl/certs/pgbouncer.key -out /etc/ssl/certs/pgbouncer.crt -/bin/pggat diff --git a/cmd/cgat/main.go b/cmd/cgat/main.go index e5b383b97317d85522c4e412616421236166cef3..5e2d58401846e34bcc475d1ad919dda61da8f878 100644 --- a/cmd/cgat/main.go +++ b/cmd/cgat/main.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "net/http" _ "net/http/pprof" "os" @@ -20,77 +19,41 @@ func main() { panic(http.ListenAndServe(":8080", nil)) }() - log.Printf("Starting pggat...") - - if len(os.Args) == 2 { - log.Printf("running in pgbouncer compatibility mode") - conf, err := pgbouncer.Load(os.Args[1]) - if err != nil { - panic(err) - } - - err = conf.ListenAndServe() - if err != nil { - panic(err) - } - return + runMode := os.Getenv("PGGAT_RUN_MODE") + if runMode == "" { + runMode = "pgbouncer" } - if os.Getenv("CONNECTION_POOLER_MODE") != "" { - log.Printf("running in zalando compatibility mode") - - conf, err := zalando.Load() - if err != nil { - panic(err) - } + log.Printf("Starting pggat (%s)...", runMode) - err = conf.ListenAndServe() - if err != nil { - panic(err) - } - return + // TODO: this really should load a dynamically registered module + var conf interface { + ListenAndServe() error } - - if os.Getenv("PGGAT_GC_PROJECT") != "" { - conf, err := cloud_sql_discovery.Load() - if err != nil { - panic(err) - } - err = conf.ListenAndServe() - if err != nil { - panic(err) - } - return + var err error + switch runMode { + case "pggat": + conf, err = pgbouncer.Load(os.Args[1]) + case "pgbouncer": + conf, err = pgbouncer.Load(os.Args[1]) + case "pgbouncer_spilo": + conf, err = zalando.Load() + case "zalando_kubernetes_operator": + conf, err = zalando_operator_discovery.Load() + case "google_cloud_sql": + conf, err = cloud_sql_discovery.Load() + case "digitalocean_databases": + conf, err = digitalocean_discovery.Load() + default: + panic("Unknown PGGAT_RUN_MODE: " + runMode) } - - if os.Getenv("PGGAT_DO_API_KEY") != "" { - log.Printf("running in digitalocean discovery mode") - - conf, err := digitalocean_discovery.Load() - if err != nil { - panic(err) - } - - err = conf.ListenAndServe() - if err != nil { - panic(err) - } - return + if err != nil { + panic(err) } - if os.Getenv("KUBERNETES_SERVICE_HOST") != "" && os.Getenv("KUBERNETES_SERVICE_PORT") != "" { - log.Printf("running in zalando operator discovery mode") - conf, err := zalando_operator_discovery.Load() - if err != nil { - panic(err) - } - - err = conf.ListenAndServe() - if err != nil { - panic(err) - } - return + err = conf.ListenAndServe() + if err != nil { + panic(err) } - - panic(fmt.Sprintf("usage: %s <config>", os.Args[0])) + return } diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..61f26ffc99437cabcc2421fb715dfa125df0f63e --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,20 @@ +#!/bin/sh +set -e + +EXEC_BIN_PATH=${PGGAT_BIN_PATH:=/usr/bin/pggat} + +pggat() { + exec $EXEC_BIN_PATH ${@} +} + + +case "${1}" in + "") + pggat ${@} + ;; + *) + export PGGAT_RUN_MODE=${1} + shift + pggat ${@} + ;; +esac diff --git a/lib/gat/modes/cloud_sql_discovery/config.go b/lib/gat/modes/cloud_sql_discovery/config.go index da7df4fdf5b529927be8fae763c13cd797023929..369b4ffd9ca592ea800f3f0cfcfab25cafa8b265 100644 --- a/lib/gat/modes/cloud_sql_discovery/config.go +++ b/lib/gat/modes/cloud_sql_discovery/config.go @@ -21,13 +21,13 @@ type Config struct { AuthPassword string `env:"PGGAT_GC_AUTH_PASSWORD"` } -func Load() (Config, error) { +func Load() (*Config, error) { var conf Config gun.Load(&conf) if conf.Project == "" { - return Config{}, errors.New("expected google cloud project id") + return &Config{}, errors.New("expected google cloud project id") } - return conf, nil + return &conf, nil } func (T *Config) ListenAndServe() error { diff --git a/lib/gat/modes/digitalocean_discovery/config.go b/lib/gat/modes/digitalocean_discovery/config.go index ddf416577b32c468ce5b694ed1a488dceff8f9a4..e476286da1a3d460b8245605c2af176e30bd3462 100644 --- a/lib/gat/modes/digitalocean_discovery/config.go +++ b/lib/gat/modes/digitalocean_discovery/config.go @@ -35,14 +35,14 @@ type Config struct { TLSKeyFile string `env:"PGGAT_TLS_KEY_FILE" default:"/etc/ssl/certs/pgbouncer.key"` } -func Load() (Config, error) { +func Load() (*Config, error) { var conf Config gun.Load(&conf) if conf.APIKey == "" { - return Config{}, errors.New("expected auth token") + return &Config{}, errors.New("expected auth token") } - return conf, nil + return &conf, nil } func (T *Config) ListenAndServe() error { diff --git a/lib/gat/modes/pgbouncer/config.go b/lib/gat/modes/pgbouncer/config.go index 191ba398a2b860416f042c4223e317d48d22944b..648c34f0b8816686ffb4057f4534e6e704867f2d 100644 --- a/lib/gat/modes/pgbouncer/config.go +++ b/lib/gat/modes/pgbouncer/config.go @@ -241,15 +241,15 @@ var Default = Config{ }, } -func Load(config string) (Config, error) { +func Load(config string) (*Config, error) { conf, err := ini.ReadFile(config) if err != nil { - return Config{}, err + return &Config{}, err } var c = Default err = ini.Unmarshal(conf, &c) - return c, err + return &c, err } func (T *Config) ListenAndServe() error { diff --git a/lib/gat/modes/zalando/config.go b/lib/gat/modes/zalando/config.go index 44b3e255986aedf3bdb546ba6bab3bb9ca8f2676..a0812e3697fd0c656f0450eb0421d8564c8445d1 100644 --- a/lib/gat/modes/zalando/config.go +++ b/lib/gat/modes/zalando/config.go @@ -26,14 +26,14 @@ type Config struct { PoolerMaxDBConn int `env:"CONNECTION_POOLER_MAX_DB_CONN"` } -func Load() (Config, error) { +func Load() (*Config, error) { var conf Config gun.Load(&conf) if conf.PoolerMode == "" { - return Config{}, errors.New("expected pooler mode") + return &Config{}, errors.New("expected pooler mode") } - return conf, nil + return &conf, nil } func (T *Config) ListenAndServe() error { diff --git a/pggat.Dockerfile b/pggat.Dockerfile index 3e562d5f61b981a2f359979c538cac0d46943f8b..57061010df72e342af9468b6d92544448a2b58e6 100644 --- a/pggat.Dockerfile +++ b/pggat.Dockerfile @@ -8,16 +8,12 @@ RUN go mod tidy RUN go build -o cgat ./cmd/cgat FROM alpine:latest +WORKDIR / +RUN apk add --no-cache bash -WORKDIR /bin +COPY entrypoint.sh . -RUN addgroup -S pgbouncer && adduser -S pgbouncer -COPY --from=GOBUILDER /src/cgat.sh entrypoint.sh -COPY --from=GOBUILDER /src/cgat pggat -RUN apk add openssl -RUN install -d -m 0755 -o pgbouncer -g pgbouncer /etc/pgbouncer /var/log/pgbouncer /var/run/pgbouncer /etc/ssl/certs -RUN chown -R pgbouncer:pgbouncer /bin/entrypoint.sh -RUN cp /bin/entrypoint.sh /bin/run.sh -USER pgbouncer:pgbouncer +COPY --from=GOBUILDER /src/cgat /usr/bin/pggat -ENTRYPOINT ["entrypoint.sh"] +ENTRYPOINT ["/entrypoint.sh"] +cmd ["pggat"]