package main import ( "context" "database/sql" "fmt" "regexp" "strings" _ "github.com/go-sql-driver/mysql" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "github.com/moby/moby/client" ) type runningSqlServer struct { Type string `json:"type"` IPaddr string `json:"ipaddr"` Password string `json:"password"` } func getRunningSqlServer() (runningSqlServer, error) { var runningSql runningSqlServer // запущенный контейнер sql apiClient, err := client.New(client.FromEnv) if err != nil { err = fmt.Errorf("Ошибка при создании docker клиента %s", err) return runningSql, err } defer apiClient.Close() // пробуем этот метод! ctx := context.Background() containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{All: true}) if err != nil { err = fmt.Errorf("Ошибка получения списка контейнеров : %s", err) return runningSql, err } for _, ctr := range containers.Items { // println(ctr.Names[0]) if ctr.Names[0] == "/mysql" { runningSql.Type = "mysql" for _, nets := range ctr.NetworkSettings.Networks { runningSql.IPaddr = nets.IPAddress.String() } cont, err := apiClient.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{}) if err != nil { return runningSql, err } for _, e := range cont.Container.Config.Env { matched, _ := regexp.Match("PASSWORD", []byte(e)) if matched { runningSql.Password = strings.Split(e, "=")[1] } } } else if ctr.Names[0] == "/pgsql" { runningSql.Type = "pgsql" for _, nets := range ctr.NetworkSettings.Networks { runningSql.IPaddr = nets.IPAddress.String() } cont, err := apiClient.ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{}) if err != nil { return runningSql, err } for _, e := range cont.Container.Config.Env { matched, _ := regexp.Match("POSTGRES_PASSWORD", []byte(e)) if matched { runningSql.Password = strings.Split(e, "=")[1] } } } } return runningSql, nil } func checkIspDbname(runningSql runningSqlServer) (string, error) { var dbname string var dbnames []string query := "SELECT datname FROM pg_database;" rows, pool, err := pgsqlQuery(query, "postgres", runningSql) defer pool.Close() defer rows.Close() if err != nil { err = fmt.Errorf("Ошибка выполнения запроса к таблице postgres : %s", err.Error()) return dbname, err } else { for rows.Next() { var db string err = rows.Scan(&db) if err != nil { err = fmt.Errorf("Ошибка сканирования результатов запроса списка баз данных : %s", err.Error()) return dbname, err // continue } dbnames = append(dbnames, db) } } // if rows != nil { // rows.Close() // } for _, d := range dbnames { if d == "isp" { dbname = "isp" } } return dbname, nil } // func pgsqlQuery(query, dbname string, runningSql runningSqlServer) (pgx.Rows, error) { // dsn := "postgres://root:" + runningSql.Password + "@" + runningSql.IPaddr + ":5432/" + dbname // connect, err := pgx.Connect(context.Background(), dsn) // err = connect.Ping(context.Background()) // if err != nil { // return nil, err // } // result, err := connect.Query(context.Background(), query) // if err != nil { // err = fmt.Errorf("Ошибка выполнения запроса к БД: %s", err) // return result, err // } // defer connect.Close(context.Background()) // return result, nil // } func pgsqlQuery(query, dbname string, runningSql runningSqlServer) (pgx.Rows, *pgxpool.Pool, error) { dsn := "postgres://root:" + runningSql.Password + "@" + runningSql.IPaddr + ":5432/" + dbname pool, err := pgxpool.New(context.Background(), dsn) if err != nil { return nil, nil, err } rows, err := pool.Query(context.Background(), query) if err != nil { pool.Close() return nil, nil, fmt.Errorf("Ошибка выполнения запроса к БД: %s", err) } return rows, pool, nil } func mysqlQuery(query, dbname string, runningSql runningSqlServer) (*sql.Rows, *sql.DB, error) { dsn := "root:" + runningSql.Password + "@tcp(" + runningSql.IPaddr + ":3306)/" + dbname db, err := sql.Open("mysql", dsn) if err != nil { return nil, nil, err } if err := db.Ping(); err != nil { err = fmt.Errorf("Ошибка проверки подключения к БД mysql: %s", err) db.Close() return nil, nil, err } result, err := db.Query(query) if err != nil { err = fmt.Errorf("Ошибка выполнения запроса %s: %s", query, err) db.Close() return nil, nil, err } return result, db, nil }