mirror of
https://github.com/hexolan/stocklet.git
synced 2026-03-26 11:41:18 +00:00
chore: initial commit
This commit is contained in:
63
cmd/service-init/config.go
Normal file
63
cmd/service-init/config.go
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright (C) 2024 Declan Teevan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/hexolan/stocklet/internal/pkg/config"
|
||||
)
|
||||
|
||||
// Init Container Configuration
|
||||
type InitConfig struct {
|
||||
// Name of the service (e.g. 'auth' or 'order')
|
||||
//
|
||||
// Env Var: "INIT_SVC_NAME"
|
||||
ServiceName string
|
||||
|
||||
// Env Var: "INIT_MIGRATIONS" (optional. accepts 'false')
|
||||
// Defaults to true
|
||||
ApplyMigrations bool
|
||||
|
||||
// 'ApplyDebezium' will default to false unless
|
||||
// the debezium host is provided.
|
||||
//
|
||||
// Env Var: "INIT_DEBEZIUM_HOST" (optional)
|
||||
// e.g. "http://debezium:8083"
|
||||
ApplyDebezium bool
|
||||
DebeziumHost string
|
||||
}
|
||||
|
||||
func (opts *InitConfig) Load() error {
|
||||
// ServiceName
|
||||
opt, err := config.RequireFromEnv("INIT_SVC_NAME")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.ServiceName = opt
|
||||
|
||||
// ApplyMigrations
|
||||
opts.ApplyMigrations = true
|
||||
if opt, _ := config.RequireFromEnv("INIT_MIGRATIONS"); opt == "false" {
|
||||
opts.ApplyMigrations = false
|
||||
}
|
||||
|
||||
// ApplyDebezium and DebeziumHost
|
||||
if opt, err := config.RequireFromEnv("INIT_DEBEZIUM_HOST"); err == nil {
|
||||
opts.ApplyDebezium = true
|
||||
opts.DebeziumHost = opt
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
67
cmd/service-init/connectors.go
Normal file
67
cmd/service-init/connectors.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2024 Declan Teevan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/hexolan/stocklet/internal/pkg/config"
|
||||
)
|
||||
|
||||
func applyPostgresOutbox(cfg *InitConfig, conf *config.PostgresConfig) {
|
||||
payloadB, err := json.Marshal(map[string]string{
|
||||
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
|
||||
"plugin.name": "pgoutput",
|
||||
"tasks.max": "1",
|
||||
"table.include.list": "public.event_outbox",
|
||||
"transforms": "outbox",
|
||||
"transforms.outbox.type": "io.debezium.transforms.outbox.EventRouter",
|
||||
"transforms.outbox.route.topic.replacement": "${routedByValue}",
|
||||
"value.converter": "io.debezium.converters.BinaryDataConverter",
|
||||
|
||||
"topic.prefix": cfg.ServiceName,
|
||||
"database.hostname": conf.Host,
|
||||
"database.port": conf.Port,
|
||||
"database.user": conf.Username,
|
||||
"database.password": conf.Password,
|
||||
"database.dbname": conf.Database,
|
||||
})
|
||||
if err != nil {
|
||||
log.Panic().Err(err).Msg("debezium connect: failed to marshal debezium cfg")
|
||||
}
|
||||
|
||||
url := cfg.DebeziumHost + "/connectors/" + cfg.ServiceName + "-outbox/config"
|
||||
log.Info().Str("url", url).Msg("debezium url")
|
||||
req, err := http.NewRequest(
|
||||
"PUT",
|
||||
url,
|
||||
bytes.NewReader(payloadB),
|
||||
)
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
client := &http.Client{}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Panic().Err(err).Msg("debezium connect: failed to perform debezium request")
|
||||
}
|
||||
|
||||
log.Info().Str("status", res.Status).Msg("debezium connect: applied outbox config")
|
||||
}
|
||||
52
cmd/service-init/main.go
Normal file
52
cmd/service-init/main.go
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright (C) 2024 Declan Teevan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/hexolan/stocklet/internal/pkg/config"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Load the init container cfg options
|
||||
cfg := InitConfig{}
|
||||
if err := cfg.Load(); err != nil {
|
||||
log.Panic().Err(err).Msg("missing required configuration")
|
||||
}
|
||||
|
||||
// If migrations or debezium are enabled,
|
||||
// then a database configuration will be required.
|
||||
if cfg.ApplyMigrations || cfg.ApplyDebezium {
|
||||
// Support for dynamic loading of configuration
|
||||
// (e.g. mongo config instead of postgres config)
|
||||
pgConf := config.PostgresConfig{}
|
||||
if err := pgConf.Load(); err == nil {
|
||||
// Using postgres as a database.
|
||||
if cfg.ApplyMigrations {
|
||||
applyPostgresMigrations(&pgConf)
|
||||
}
|
||||
|
||||
if cfg.ApplyDebezium {
|
||||
applyPostgresOutbox(&cfg, &pgConf)
|
||||
}
|
||||
} else {
|
||||
log.Panic().Msg("unable to load any db configs (unable to perform migrations or apply connector cfgs)")
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().Str("svc", cfg.ServiceName).Msg("completed init for service")
|
||||
}
|
||||
43
cmd/service-init/migrations.go
Normal file
43
cmd/service-init/migrations.go
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2024 Declan Teevan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
_ "github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/hexolan/stocklet/internal/pkg/config"
|
||||
)
|
||||
|
||||
func applyPostgresMigrations(conf *config.PostgresConfig) {
|
||||
m, err := migrate.New("file:///migrations", conf.GetDSN())
|
||||
if err != nil {
|
||||
log.Panic().Err(err).Msg("migrate: failed to open client")
|
||||
}
|
||||
|
||||
err = m.Up()
|
||||
if err != nil {
|
||||
if err.Error() == "no change" {
|
||||
log.Info().Err(err).Msg("migrate: migrations up to date")
|
||||
} else {
|
||||
log.Panic().Err(err).Msg("migrate: raised when performing db migration")
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().Msg("migrate: succesfully performed postgres migrations")
|
||||
}
|
||||
Reference in New Issue
Block a user