forked from ebhomengo/niki
1
0
Fork 0

feat(niki): setup and implement sample end2end test (#109)

This commit is contained in:
Ruhollah 2024-08-06 15:19:46 +03:30
parent 3ff9d13da1
commit f0001975ea
24 changed files with 717 additions and 28 deletions

View File

@ -0,0 +1,43 @@
//go:build end2end
// +build end2end
package end2end
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
)
func TestAdmin_KindBox_Get(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
// Get token
lRes, err := services.AdminSvc.LoginWithPhoneNumber(context.Background(), adminserviceparam.LoginWithPhoneNumberRequest{
PhoneNumber: "09384664402",
Password: "Abc123456",
})
if err != nil {
t.Fatalf("could not login: %s", err)
}
// Create a request
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes/1", nil)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
// Serve the request
testServer.Serve(rec, req)
// Assertions
assert.Equal(t, http.StatusOK, rec.Code)
}

View File

@ -0,0 +1,80 @@
//go:build end2end
// +build end2end
package end2end
import (
"testing"
"git.gocasts.ir/ebhomengo/niki/adapter/kavenegar"
"git.gocasts.ir/ebhomengo/niki/config"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
"git.gocasts.ir/ebhomengo/niki/service"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor"
)
var (
services *service.Service
testServer *setup.TestServer
testContainer *setup.TestContainer
testSmsAdapter *setup.TestSmsAdapter
)
func TestMain(m *testing.M) {
// Start test containers
testContainer = setup.NewTestContainer()
testContainer.Start()
defer testContainer.Stop()
// Run MariaDB Migrations
teardown := setup.MigrateMariaDB(testContainer.GetMariaDBConfig())
defer teardown()
// Setup Test SMS Adapter
testSmsAdapter = setup.NewTestSmsAdapter()
// Setup Services and Test Server
cfg := getConfig()
services = service.New(
cfg,
testContainer.GetMariaDBConnection(),
testContainer.GetRedisDBConnection(),
testSmsAdapter,
)
testServer = setup.NewTestServer(cfg, services)
// Run the tests
m.Run()
}
func getConfig() config.Config {
return config.Config{
HTTPServer: config.HTTPServer{Port: 42069},
Mysql: testContainer.GetMariaDBConfig(),
BenefactorAuth: authservice.Config{
SignKey: "jwt_secret_test_nik",
AccessExpirationTime: config.Default().BenefactorAuth.AccessExpirationTime,
RefreshExpirationTime: config.Default().BenefactorAuth.RefreshExpirationTime,
AccessSubject: config.Default().BenefactorAuth.AccessSubject,
RefreshSubject: config.Default().BenefactorAuth.RefreshSubject,
},
AdminAuth: authservice.Config{
SignKey: "admin-jwt_secret_test_nik",
AccessExpirationTime: config.Default().BenefactorAuth.AccessExpirationTime,
RefreshExpirationTime: config.Default().BenefactorAuth.RefreshExpirationTime,
AccessSubject: config.Default().BenefactorAuth.AccessSubject,
RefreshSubject: config.Default().BenefactorAuth.RefreshSubject,
},
Redis: testContainer.GetRedisConfig(),
KavenegarSmsProvider: kavenegar.Config{
APIKey: "",
Sender: "",
},
BenefactorSvc: benefactorservice.Config{
LengthOfOtpCode: 5,
OtpChars: config.OtpChars,
OtpExpireTime: config.OtpExpireTime,
},
}
}

View File

@ -0,0 +1,183 @@
package setup
import (
"context"
"log"
"strconv"
redisadapter "git.gocasts.ir/ebhomengo/niki/adapter/redis"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
// nolint
_ "github.com/go-sql-driver/mysql"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
)
// TestContainer holds the state of docker test.
type TestContainer struct {
dockerPool *dockertest.Pool // the connection pool to Docker.
mariaResource *dockertest.Resource // MariaDB Docker container resource.
redisResource *dockertest.Resource // Redis Docker container resource.
mariaDBConn *mysql.DB // Connection to the MariaDB database.
redisDBConn *redisadapter.Adapter // Connection to the Redis database.
containerExpiryInSeconds uint
}
func NewTestContainer() *TestContainer {
return &TestContainer{
// nolint
containerExpiryInSeconds: 120,
}
}
func (t *TestContainer) GetMariaDBConnection() *mysql.DB {
if t.mariaDBConn == nil {
log.Fatal("did you forgot to start the test container?")
}
return t.mariaDBConn
}
func (t *TestContainer) GetRedisDBConnection() *redisadapter.Adapter {
if t.redisDBConn == nil {
log.Fatal("did you forgot to start the test container?")
}
return t.redisDBConn
}
func (t *TestContainer) GetMariaDBConfig() mysql.Config {
if t.mariaResource == nil {
log.Fatal("did you forgot to start the test container?")
}
port, err := strconv.Atoi(t.mariaResource.GetPort("3306/tcp"))
if err != nil {
log.Fatalf("couldn't convert port to integer: %s", err)
}
return mysql.Config{
Username: "root",
Password: "secret",
Port: port,
Host: "localhost",
DBName: "mysql",
}
}
func (t *TestContainer) GetRedisConfig() redisadapter.Config {
if t.mariaResource == nil {
log.Fatal("did you forgot to start the test container?")
}
port, err := strconv.Atoi(t.redisResource.GetPort("6379/tcp"))
if err != nil {
log.Fatalf("couldn't convert port to integer: %s", err)
}
return redisadapter.Config{
Host: "localhost",
Port: port,
Password: "",
DB: 0,
}
}
// Start initializes and starts the MariaDB and Redis Docker container for testing.
func (t *TestContainer) Start() {
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
var err error
t.dockerPool, err = dockertest.NewPool("")
if err != nil {
log.Fatalf("Could not construct pool: %s", err)
}
// uses pool to try to connect to Docker
err = t.dockerPool.Client.Ping()
if err != nil {
log.Fatalf("Could not connect to Docker: %s", err)
}
// pulls mariaDB image, creates a container based on it and runs it
t.mariaResource, err = t.dockerPool.RunWithOptions(
&dockertest.RunOptions{
Repository: "mariadb",
Tag: "11.1",
Env: []string{"MARIADB_ROOT_PASSWORD=secret"},
}, func(config *docker.HostConfig) {
config.AutoRemove = true // Ensure the container is removed after the test.
config.RestartPolicy = docker.RestartPolicy{
Name: "no", // Do not automatically restart the container.
}
},
)
if err != nil {
log.Fatalf("Could not start maria resource: %s", err)
}
// Set container to expire after two minutes to avoid dangling resources in case of test interruption.
if err = t.mariaResource.Expire(t.containerExpiryInSeconds); err != nil {
log.Fatalf("Couldn't set MariaDB container expiration: %s", err)
}
t.redisResource, err = t.dockerPool.RunWithOptions(
&dockertest.RunOptions{
Repository: "redis",
Tag: "6.2",
Env: []string{"ALLOW_EMPTY_PASSWORD=yes"},
}, func(config *docker.HostConfig) {
config.AutoRemove = true // Ensure the container is removed after the test.
config.RestartPolicy = docker.RestartPolicy{
Name: "no", // Do not automatically restart the container.
}
},
)
if err != nil {
log.Fatalf("Could not start redis resource: %s", err)
}
// Set container to expire after two minutes to avoid dangling resources in case of test interruption.
if err = t.redisResource.Expire(t.containerExpiryInSeconds); err != nil {
log.Fatalf("Couldn't set RedisDB container expiration: %s", err)
}
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
if err = t.dockerPool.Retry(func() error {
var err error
t.mariaDBConn = mysql.New(t.GetMariaDBConfig())
err = t.mariaDBConn.Conn().Ping()
if err != nil {
return err
}
t.redisDBConn = redisadapter.New(t.GetRedisConfig())
err = t.redisDBConn.Client().Ping(context.Background()).Err()
if err != nil {
return err
}
return nil
}); err != nil {
log.Fatalf("Could not connect to database: %s", err)
}
}
// Stop cleans up the Docker containers.
func (t *TestContainer) Stop() {
err := t.mariaDBConn.CloseStatements()
if err != nil {
log.Fatalf("Could not close statements on maria db connection: %s", err)
}
err = t.mariaDBConn.Conn().Close()
if err != nil {
log.Fatalf("Could not close maria db connection: %s", err)
}
if err = t.dockerPool.Purge(t.mariaResource); err != nil {
log.Fatalf("Could not purge maria resource: %s", err)
}
if err = t.dockerPool.Purge(t.redisResource); err != nil {
log.Fatalf("Could not purge redis resource: %s", err)
}
}

View File

@ -0,0 +1,32 @@
package setup
import (
"git.gocasts.ir/ebhomengo/niki/repository/migrator"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
)
func MigrateMariaDB(cfg mysql.Config) func() {
migrations := migrator.New(migrator.Config{
MysqlConfig: cfg,
MigrationPath: "../../../repository/mysql/migration",
MigrationDBName: "gorp_migrations",
})
migrations.Up()
return func() {
migrations.Down()
}
}
func SeedMariaDB(cfg mysql.Config) func() {
seed := migrator.New(migrator.Config{
MysqlConfig: cfg,
MigrationPath: "./setup/seed_data",
MigrationDBName: "test_migrations",
})
seed.Up()
return func() {
seed.Down()
}
}

View File

@ -0,0 +1,16 @@
-- +migrate Up
INSERT INTO `kind_box_reqs` (`id`, `benefactor_id`, `kind_box_type`, `count_requested`, `description`, `status`, `deliver_refer_time_id`, `deliver_refer_date`, `deliver_address_id`)
VALUES (
3,
1,
'on-table',
100,
'too many!',
'rejected',
1,
NOW() + INTERVAL 7 DAY,
1
);
-- +migrate Down
DELETE FROM `kind_box_reqs` WHERE id = 3;

View File

@ -0,0 +1,17 @@
-- +migrate Up
INSERT INTO `kind_box_reqs` (`id`, `benefactor_id`, `kind_box_type`, `count_requested`, `count_accepted`, `status`, `deliver_refer_time_id`, `deliver_refer_date`, `deliver_address_id`, `sender_agent_id`)
VALUES (
4,
1,
'on-table',
1,
1,
'assigned-sender-agent',
1,
NOW() + INTERVAL 7 DAY,
1,
1
);
-- +migrate Down
DELETE FROM `kind_box_reqs` WHERE id = 4;

View File

@ -0,0 +1,18 @@
-- +migrate Up
INSERT INTO `kind_box_reqs` (`id`, `benefactor_id`, `kind_box_type`, `count_requested`, `count_accepted`, `status`, `deliver_refer_time_id`, `deliver_refer_date`, `deliver_address_id`, `sender_agent_id`, `delivered_at`)
VALUES (
5,
1,
'on-table',
1,
1,
'delivered',
1,
NOW() - INTERVAL 7 DAY,
1,
1,
NOW()
);
-- +migrate Down
DELETE FROM `kind_box_reqs` WHERE id = 5;

View File

@ -0,0 +1,18 @@
-- +migrate Up
INSERT INTO `kind_boxes` (`id`, `kind_box_req_id`, `benefactor_id`, `type`, `serial_number`, `status`, `deliver_refer_time_id`, `deliver_refer_date`, `deliver_address_id`, `sender_agent_id`, `delivered_at`)
VALUES (
1,
1,
1,
'on-table',
'serial-1',
'delivered',
1,
NOW() - INTERVAL 7 DAY,
1,
1,
NOW()
);
-- +migrate Down
DELETE FROM `kind_boxes` WHERE id = 1;

View File

@ -0,0 +1,18 @@
-- +migrate Up
INSERT INTO `admins` (`id`, `first_name`, `last_name`, `password`, `phone_number`, `role`, `description`, `email`, `gender`, `status`)
VALUES (
2,
'ruhi',
'hosseini',
-- password is: Abc123456
'$2a$10$UggC7sgECCaNm2TAkchve.TLcHJuxPAVZkzMfCDZqKRQVHcJZaoX2',
'09384664401',
'super-admin',
'testing',
'admin.superadmin.01@gmail.com',
'male',
'active'
);
-- +migrate Dow
DELETE FROM `admins` WHERE id = 2;

View File

@ -0,0 +1,18 @@
-- +migrate Up
INSERT INTO `admins` (`id`, `first_name`, `last_name`, `password`, `phone_number`, `role`, `description`, `email`, `gender`, `status`)
VALUES (
3,
'ruhi',
'hosseini',
-- password is: Abc123456
'$2a$10$xaNwJqcuRUlPhAUPZhhV3.WRmI5iBea5RzvL4qWS6OCFk0F7bKvaW',
'09384664402',
'admin',
'testing',
'admin.admin.01@gmail.com',
'male',
'active'
);
-- +migrate Down
DELETE FROM `admins` WHERE id = 3;

View File

@ -0,0 +1,18 @@
-- +migrate Up
INSERT INTO `admins` (`id`, `first_name`, `last_name`, `password`, `phone_number`, `role`, `description`, `email`, `gender`, `status`)
VALUES (
4,
'ruhi',
'hosseini',
-- password is: Abc123456
'$2a$10$A4qiAep9OGYe2aFT3Tn1cuJfj99Xp6WA2F0SN9I7zAS01JGFU7XAO',
'09384664403',
'agent',
'testing',
'admin.agent.01@gmail.com',
'male',
'active'
);
-- +migrate Down
DELETE FROM `admins` WHERE id = 4;

View File

@ -0,0 +1,15 @@
-- +migrate Up
INSERT INTO `benefactors` (`id`, `first_name`, `last_name`, `phone_number`, `description`, `email`, `gender`, `birth_date`)
VALUES (
1,
'ruhi',
'hosseini',
'09384664404',
'testing',
'benefactor.01@gmail.com',
'male',
'1998-05-02 04:20:00'
);
-- +migrate Down
DELETE FROM `benefactors` WHERE id = 1;

View File

@ -0,0 +1,15 @@
-- +migrate Up
INSERT INTO `benefactors` (`id`, `first_name`, `last_name`, `phone_number`, `description`, `email`, `gender`, `birth_date`)
VALUES (
2,
'doctor',
'who',
'09384664405',
'testing',
'benefactor.02@gmail.com',
'male',
'2000-05-02 04:20:00'
);
-- +migrate Down
DELETE FROM `benefactors` WHERE id = 2;

View File

@ -0,0 +1,16 @@
-- +migrate Up
INSERT INTO `addresses` (`id`, `postal_code`, `address`, `lat`, `lon`, `name`, `city_id`, `province_id`, `benefactor_id`)
VALUES (
1,
'3719655861',
'tehran sare koche 1',
35.632508,
51.452859,
'home1',
8,
8,
1
);
-- +migrate Down
DELETE FROM `addresses` WHERE id = 1;

View File

@ -0,0 +1,16 @@
-- +migrate Up
INSERT INTO `addresses` (`id`, `postal_code`, `address`, `lat`, `lon`, `name`, `city_id`, `province_id`, `benefactor_id`)
VALUES (
2,
'3719655869',
'tehran sare koche 2',
35.735638,
51.312945,
'home2',
8,
8,
2
);
-- +migrate Down
DELETE FROM `addresses` WHERE id = 2;

View File

@ -0,0 +1,15 @@
-- +migrate Up
INSERT INTO `kind_box_reqs` (`id`, `benefactor_id`, `kind_box_type`, `count_requested`, `status`, `deliver_refer_time_id`, `deliver_refer_date`, `deliver_address_id`)
VALUES (
1,
1,
'on-table',
1,
'pending',
1,
NOW() + INTERVAL 7 DAY,
1
);
-- +migrate Down
DELETE FROM `kind_box_reqs` WHERE id = 1;

View File

@ -0,0 +1,16 @@
-- +migrate Up
INSERT INTO `kind_box_reqs` (`id`, `benefactor_id`, `kind_box_type`, `count_requested`, `count_accepted`, `status`, `deliver_refer_time_id`, `deliver_refer_date`, `deliver_address_id`)
VALUES (
2,
1,
'on-table',
2,
1,
'accepted',
1,
NOW() + INTERVAL 7 DAY,
1
);
-- +migrate Down
DELETE FROM `kind_box_reqs` WHERE id = 2;

View File

@ -0,0 +1,25 @@
package setup
import (
"github.com/labstack/echo/v4"
"net/http"
"git.gocasts.ir/ebhomengo/niki/config"
httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
"git.gocasts.ir/ebhomengo/niki/service"
)
type TestServer struct {
router *echo.Echo
}
func NewTestServer(cfg config.Config, svc *service.Service) *TestServer {
s := httpserver.New(cfg, svc)
s.RegisterRoutes()
return &TestServer{router: s.Router}
}
func (t *TestServer) Serve(w http.ResponseWriter, r *http.Request) {
t.router.ServeHTTP(w, r)
}

View File

@ -0,0 +1,13 @@
package setup
type TestSmsAdapter struct {
Inbox string
}
func NewTestSmsAdapter() *TestSmsAdapter {
return &TestSmsAdapter{}
}
func (s *TestSmsAdapter) Send(_, message string) {
s.Inbox = message
}

View File

@ -16,7 +16,7 @@ import (
"git.gocasts.ir/ebhomengo/niki/docs"
"git.gocasts.ir/ebhomengo/niki/service"
echo "github.com/labstack/echo/v4"
middleware "github.com/labstack/echo/v4/middleware"
"github.com/labstack/echo/v4/middleware"
echoSwagger "github.com/swaggo/echo-swagger"
)
@ -54,9 +54,20 @@ func New(
}
func (s Server) Serve() {
s.RegisterRoutes()
// Start server
address := fmt.Sprintf(":%d", s.config.HTTPServer.Port)
fmt.Printf("start echo server on %s\n", address)
if err := s.Router.Start(address); err != nil {
fmt.Println("router start error", err)
}
}
func (s Server) RegisterRoutes() {
s.Router.Use(middleware.RequestID())
s.Router.Use(middleware.Recover())
RegisterSwagger(s.Router, s.config)
registerSwagger(s.Router, s.config)
// Routes
s.Router.GET("/health-check", s.healthCheck)
@ -68,16 +79,9 @@ func (s Server) Serve() {
s.adminKindBoxReqHandler.SetRoutes(s.Router)
s.adminKindBoxHandler.SetRoutes(s.Router)
s.agentKindBoxHandler.SetRoutes(s.Router)
// Start server
address := fmt.Sprintf(":%d", s.config.HTTPServer.Port)
fmt.Printf("start echo server on %s\n", address)
if err := s.Router.Start(address); err != nil {
fmt.Println("router start error", err)
}
}
func RegisterSwagger(s *echo.Echo, c config.Config) {
func registerSwagger(s *echo.Echo, c config.Config) {
// TODO: move this to a better place and make it more dynamic and configurable
docs.SwaggerInfo.Title = "NIKI API"
docs.SwaggerInfo.Description = "This is the API documentation for the NIKI project"

32
go.mod
View File

@ -1,16 +1,19 @@
module git.gocasts.ir/ebhomengo/niki
go 1.21.3
go 1.22
toolchain go1.22.4
require (
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
github.com/go-sql-driver/mysql v1.6.0
github.com/go-sql-driver/mysql v1.8.1
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/kavenegar/kavenegar-go v0.0.0-20221124112814-40341057b5ca
github.com/knadh/koanf v1.5.0
github.com/labstack/echo-jwt/v4 v4.2.0
github.com/labstack/echo/v4 v4.12.0
github.com/ory/dockertest/v3 v3.11.0
github.com/redis/go-redis/v9 v9.4.0
github.com/rubenv/sql-migrate v1.6.0
github.com/stretchr/testify v1.9.0
@ -21,11 +24,22 @@ require (
)
require (
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/continuity v0.4.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/docker/cli v26.1.4+incompatible // indirect
github.com/docker/docker v27.1.1+incompatible // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
@ -34,8 +48,10 @@ require (
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
@ -44,13 +60,23 @@ require (
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/opencontainers/runc v1.1.13 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/swaggo/files/v2 v2.0.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.21.0 // indirect

67
go.sum
View File

@ -1,8 +1,18 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -33,6 +43,8 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
@ -40,13 +52,25 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8=
github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/docker/cli v26.1.4+incompatible h1:I8PHdc0MtxEADqYJZvhBrW9bo8gawKwwenxRM7/rLu8=
github.com/docker/cli v26.1.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -83,12 +107,13 @@ github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU=
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es=
github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
@ -123,7 +148,11 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
@ -198,8 +227,8 @@ github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+k
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@ -236,6 +265,10 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@ -244,6 +277,14 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/opencontainers/runc v1.1.13 h1:98S2srgG9vw0zWcDpFMn5TRrh8kLxa/5OFUstuUhmRs=
github.com/opencontainers/runc v1.1.13/go.mod h1:R016aXacfp/gwQBYw2FDGa9m+n6atbLWrYY8hNMT/sA=
github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA=
github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI=
@ -251,6 +292,7 @@ github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAv
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -288,6 +330,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -311,6 +355,13 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
@ -401,10 +452,12 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -483,6 +536,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

View File

@ -46,7 +46,11 @@ func MariaDB(cfg config.Config) *mysql.DB {
migrate := flag.Bool("migrate", false, "perform database migration")
flag.Parse()
if *migrate {
migrator.New(cfg.Mysql).Up()
migrator.New(migrator.Config{
MysqlConfig: cfg.Mysql,
MigrationPath: "./repository/mysql/migration",
MigrationDBName: "gorp_migrations",
}).Up()
}
return mysql.New(cfg.Mysql)

View File

@ -8,29 +8,35 @@ import (
migrate "github.com/rubenv/sql-migrate"
)
type Config struct {
MysqlConfig mysql.Config
MigrationPath string
MigrationDBName string
}
type Migrator struct {
cfg Config
dialect string
dbConfig mysql.Config
migrations *migrate.FileMigrationSource
}
// TODO - set migration table name
// TODO - add limit to Up and Down method
func New(dbConfig mysql.Config) Migrator {
func New(cfg Config) Migrator {
// OR: Read migrations from a folder:
migrations := &migrate.FileMigrationSource{
Dir: "./repository/mysql/migration",
Dir: cfg.MigrationPath,
}
return Migrator{dbConfig: dbConfig, dialect: "mysql", migrations: migrations}
return Migrator{cfg: cfg, dialect: "mysql", migrations: migrations}
}
func (m Migrator) Up() {
fmt.Println("mysql add= ", fmt.Sprintf("%s:%s@(%s:%d)/%s?parseTime=true",
m.dbConfig.Username, m.dbConfig.Password, m.dbConfig.Host, m.dbConfig.Port, m.dbConfig.DBName))
migrate.SetTable(m.cfg.MigrationDBName)
db, err := sql.Open(m.dialect, fmt.Sprintf("%s:%s@(%s:%d)/%s?parseTime=true",
m.dbConfig.Username, m.dbConfig.Password, m.dbConfig.Host, m.dbConfig.Port, m.dbConfig.DBName))
m.cfg.MysqlConfig.Username, m.cfg.MysqlConfig.Password, m.cfg.MysqlConfig.Host, m.cfg.MysqlConfig.Port, m.cfg.MysqlConfig.DBName))
if err != nil {
panic(fmt.Errorf("can't open mysql db: %w", err))
}
@ -43,8 +49,10 @@ func (m Migrator) Up() {
}
func (m Migrator) Down() {
migrate.SetTable(m.cfg.MigrationDBName)
db, err := sql.Open(m.dialect, fmt.Sprintf("%s:%s@(%s:%d)/%s?parseTime=true",
m.dbConfig.Username, m.dbConfig.Password, m.dbConfig.Host, m.dbConfig.Port, m.dbConfig.DBName))
m.cfg.MysqlConfig.Username, m.cfg.MysqlConfig.Password, m.cfg.MysqlConfig.Host, m.cfg.MysqlConfig.Port, m.cfg.MysqlConfig.DBName))
if err != nil {
panic(fmt.Errorf("can't open mysql db: %w", err))
}