New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create user in envtool
for PostgreSQL
#4133
Changes from 7 commits
36c81c0
d3a2bef
167ccf6
2043e92
b2f6205
ff25f6f
d68a777
1f1c728
af0bdff
563e165
96d34ef
9db3718
34bd803
f41adb2
80bf3a0
aba7e4e
6192940
4c4add2
8d5ca45
5278da8
3134785
5801476
afae527
0b57bbe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,9 @@ | |
"github.com/FerretDB/FerretDB/build/version" | ||
mysqlpool "github.com/FerretDB/FerretDB/internal/backends/mysql/metadata/pool" | ||
"github.com/FerretDB/FerretDB/internal/backends/postgresql/metadata/pool" | ||
"github.com/FerretDB/FerretDB/internal/clientconn" | ||
"github.com/FerretDB/FerretDB/internal/clientconn/connmetrics" | ||
"github.com/FerretDB/FerretDB/internal/handler/registry" | ||
"github.com/FerretDB/FerretDB/internal/util/ctxutil" | ||
"github.com/FerretDB/FerretDB/internal/util/debug" | ||
"github.com/FerretDB/FerretDB/internal/util/lazyerrors" | ||
|
@@ -132,7 +135,7 @@ | |
return ctx.Err() | ||
} | ||
|
||
return nil | ||
return setupUser(ctx, logger, uint16(port)) | ||
} | ||
|
||
// setupPostgres configures `postgres` container. | ||
|
@@ -219,6 +222,118 @@ | |
return ctx.Err() | ||
} | ||
|
||
// setupUser creates a user in admin database with supported mechanisms. | ||
// The user uses username/password credential which is the same as the PostgreSQL | ||
// credentials. | ||
// | ||
// Without this, once the first user is created, the authentication fails | ||
// as username/password does not exist in admin.system.users collection. | ||
func setupUser(ctx context.Context, logger *zap.SugaredLogger, postgreSQLPort uint16) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not replace setupUser() in integration test.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the clarification! I was worried this could jeopardize running tests directly with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's still there for SQLite. It only has handler level authentication, and once the first user is created without this code, auth would fail. It will be handled in a separate PR. |
||
if err := waitForPort(ctx, logger.Named("postgreSQL"), postgreSQLPort); err != nil { | ||
return err | ||
} | ||
|
||
sp, err := state.NewProvider("") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
postgreSQlURL := fmt.Sprintf("postgres://username:password@localhost:%d/ferretdb", postgreSQLPort) | ||
listenerMetrics := connmetrics.NewListenerMetrics() | ||
handlerOpts := ®istry.NewHandlerOpts{ | ||
Logger: logger.Desugar(), | ||
ConnMetrics: listenerMetrics.ConnMetrics, | ||
StateProvider: sp, | ||
PostgreSQLURL: postgreSQlURL, | ||
TestOpts: registry.TestOpts{ | ||
CappedCleanupPercentage: 20, | ||
EnableNewAuth: true, | ||
}, | ||
} | ||
|
||
h, closeBackend, err := registry.NewHandler("postgresql", handlerOpts) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
defer closeBackend() | ||
|
||
listenerOpts := clientconn.NewListenerOpts{ | ||
Mode: clientconn.NormalMode, | ||
Metrics: listenerMetrics, | ||
Handler: h, | ||
Logger: logger.Desugar(), | ||
TCP: "127.0.0.1:0", | ||
} | ||
|
||
l := clientconn.NewListener(&listenerOpts) | ||
|
||
runErr := make(chan error) | ||
|
||
go func() { | ||
if err := l.Run(ctx); err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) { | ||
runErr <- err | ||
|
||
return | ||
} | ||
}() | ||
|
||
defer close(runErr) | ||
|
||
select { | ||
case err := <-runErr: | ||
if err != nil { | ||
return err | ||
} | ||
case <-time.After(time.Millisecond): | ||
} | ||
|
||
port := l.TCPAddr().(*net.TCPAddr).Port | ||
|
||
var retry int64 | ||
|
||
eval := `' | ||
if (db.getSiblingDB("admin").getUser("username") == null){ | ||
db.getSiblingDB("admin").createUser( | ||
{user: "username", pwd: "password", roles: [], mechanisms: ["SCRAM-SHA-1","SCRAM-SHA-256","PLAIN"]} | ||
) | ||
} | ||
'` | ||
args := []string{ | ||
"compose", | ||
"exec", | ||
"-T", | ||
"mongodb", | ||
"mongosh", | ||
"--host=host.docker.internal", | ||
fmt.Sprintf("--port=%d", port), | ||
"--eval", | ||
eval, | ||
} | ||
|
||
var buf bytes.Buffer | ||
|
||
for ctx.Err() == nil { | ||
buf.Reset() | ||
|
||
err = runCommand("docker", args, &buf, logger) | ||
if err == nil { | ||
break | ||
} | ||
|
||
logger.Infof("%s:\n%s", err, buf.String()) | ||
|
||
retry++ | ||
ctxutil.SleepWithJitter(ctx, time.Second, retry) | ||
} | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return ctx.Err() | ||
} | ||
|
||
// setupMongodbSecured configures `mongodb_secured` container. | ||
func setupMongodbSecured(ctx context.Context, logger *zap.SugaredLogger) error { | ||
if err := waitForPort(ctx, logger.Named("mongodb_secured"), 47018); err != nil { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For run-secured to work, what other better thing can I do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That target was supposed to be for the "old" authentication that does not need credentials in the PostgreSQL URI. Why are they needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's because postgres started on port 5433 is created from
postgres_secured
docker https://github.com/FerretDB/FerretDB/blob/main/docker-compose.yml#L28.Unlike
postgres
docker which hasPOSTGRES_HOST_AUTH_METHOD=trust
,postgres_secured
doesn't havetrust
so username/password is required to connect to it.