Skip to content

Commit

Permalink
Add Tigris authentication support (#2040)
Browse files Browse the repository at this point in the history
Closes #1789.
  • Loading branch information
AlekSi authored Feb 22, 2023
1 parent eee9698 commit 07cab1c
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 151 deletions.
70 changes: 44 additions & 26 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ tasks:
run: once
deps: [gen-version]
cmds:
- go test -c -o=bin/ferretdb-testcover{{exeExt}} -trimpath {{.RACEFLAG}} -tags=ferretdb_testcover,{{.BUILDTAGS}} -coverpkg=./... ./cmd/ferretdb
# do not trim paths to make debugging with delve easier
- go test -c -o=bin/ferretdb-testcover{{exeExt}} -trimpath=false {{.RACEFLAG}} -tags=ferretdb_testcover,{{.BUILDTAGS}} -coverpkg=./... ./cmd/ferretdb

init-tools:
dir: tools
Expand Down Expand Up @@ -177,9 +178,9 @@ tasks:
go test -count=1 {{.RACEFLAG}} -tags={{.BUILDTAGS}} -shuffle=on -coverpkg=../...
-coverprofile=integration-pg.txt .
-target-backend=ferretdb-pg
{{.UNIXSOCKETFLAG}}
-postgresql-url=postgres://username@127.0.0.1:5432/ferretdb?pool_min_conns=1
-compat-url=mongodb://127.0.0.1:47017/
-target-tls
-postgresql-url=postgres://username@127.0.0.1:5432/ferretdb
-compat-url='mongodb://username:password@127.0.0.1:47018/?tls=true&tlsCertificateKeyFile=../build/certs/client.pem&tlsCaFile=../build/certs/rootCA-cert.pem'
-records-dir=../records
test-integration-tigris:
Expand All @@ -190,9 +191,9 @@ tasks:
go test -count=1 {{.RACEFLAG}} -tags={{.BUILDTAGS}} -shuffle=on -coverpkg=../...
-coverprofile=integration-tigris.txt .
-target-backend=ferretdb-tigris
-target-tls
{{.UNIXSOCKETFLAG}}
-tigris-urls=127.0.0.1:8081,127.0.0.1:8091,127.0.0.1:8092,127.0.0.1:8093,127.0.0.1:8094
-compat-url='mongodb://username:password@127.0.0.1:47018/?tls=true&tlsCertificateKeyFile=../build/certs/client.pem&tlsCaFile=../build/certs/rootCA-cert.pem'
-compat-url=mongodb://127.0.0.1:47017/
-records-dir=../records
test-integration-mongodb:
Expand Down Expand Up @@ -249,44 +250,64 @@ tasks:
- go run {{.RACEFLAG}} ./cmd/fuzztool corpus {{.FUZZCORPUS}} generated

run:
desc: "Run FerretDB"
desc: "Run FerretDB with `pg` handler"
deps: [build-testcover]
cmds:
- >
bin/ferretdb-testcover{{exeExt}} -test.coverprofile=cover.txt --
--listen-addr=:27017
--proxy-addr=127.0.0.1:47017
--mode=diff-normal
--postgresql-url="postgres://username@127.0.0.1:5432/ferretdb"
--handler=pg
--postgresql-url=postgres://username@127.0.0.1:5432/ferretdb
--test-records-dir=records
run-tigris:
desc: "Run FerretDB with `tigris` handler"
deps: [build-testcover]
cmds:
- >
bin/ferretdb-testcover{{exeExt}} -test.coverprofile=cover.txt --
--listen-addr=:27017
--proxy-addr=127.0.0.1:47017
--mode=diff-normal
--handler=tigris
--tigris-url=127.0.0.1:8081
--test-records-dir=records
run-secured:
desc: "Run secured FerretDB with TLS and authentication"
desc: "Run FerretDB with `pg` handler (TLS, auth required)"
deps: [build-testcover]
cmds:
- >
bin/ferretdb-testcover{{exeExt}} -test.coverprofile=cover.txt --
--listen-addr=''
--listen-tls=:27018
--listen-tls-cert-file=./build/certs/server-cert.pem
--listen-tls-key-file=./build/certs/server-key.pem
--listen-tls-ca-file=./build/certs/rootCA-cert.pem
--listen-tls=:27018
--mode=normal
--postgresql-url="postgres://127.0.0.1:5433/ferretdb"
--proxy-addr=127.0.0.1:47017
--mode=diff-normal
--handler=pg
--postgresql-url=postgres://127.0.0.1:5433/ferretdb
--test-records-dir=records
run-tigris:
# set FERRETDB_TIGRIS_CLIENT_ID and FERRETDB_TIGRIS_CLIENT_SECRET environment variables to use it
run-tigris-secured:
desc: "Run FerretDB with `tigris` handler (TLS, auth required; SaaS)"
deps: [build-testcover]
cmds:
- >
bin/ferretdb-testcover{{exeExt}} -test.coverprofile=cover.txt --
--handler=tigris
--listen-addr=:27017
--listen-addr=''
--listen-tls=:27018
--listen-tls-cert-file=./build/certs/server-cert.pem
--listen-tls-key-file=./build/certs/server-key.pem
--listen-tls=:27018
--mode=diff-normal
--listen-tls-ca-file=./build/certs/rootCA-cert.pem
--proxy-addr=127.0.0.1:47017
--mode=diff-normal
--handler=tigris
--tigris-url=api.preview.tigrisdata.cloud
--test-records-dir=records
run-proxy:
Expand All @@ -296,12 +317,10 @@ tasks:
- >
bin/ferretdb-testcover{{exeExt}} -test.coverprofile=cover.txt --
--listen-addr=:27017
--listen-tls-cert-file=./build/certs/server-cert.pem
--listen-tls-key-file=./build/certs/server-key.pem
--listen-tls=:27018
--mode=diff-proxy
--postgresql-url="postgres://username@127.0.0.1:5432/ferretdb"
--proxy-addr=127.0.0.1:47017
--mode=diff-proxy
--handler=pg
--postgresql-url=postgres://username@127.0.0.1:5432/ferretdb
--test-records-dir=records
lint:
Expand Down Expand Up @@ -355,17 +374,16 @@ tasks:
cmds:
- >
docker compose exec mongodb mongosh
'mongodb://host.docker.internal:27017/?heartbeatFrequencyMS=300000'
--verbose --eval 'disableTelemetry()' --shell
'mongodb://host.docker.internal:27017/?heartbeatFrequencyMS=300000'
mongosh-secured:
desc: "Run MongoDB shell (`mongosh`) for secured FerretDB"
desc: "Run MongoDB shell (`mongosh`) with TLS and auth"
cmds:
- >
docker compose exec mongodb mongosh
--tlsCertificateKeyFile=/etc/certs/client.pem --tlsCAFile=/etc/certs/rootCA-cert.pem
'mongodb://username:password@host.docker.internal:27018/?authMechanism=PLAIN&tls=true&heartbeatFrequencyMS=300000'
--verbose --eval 'disableTelemetry()' --shell
'mongodb://username:password@host.docker.internal:27018/?authMechanism=PLAIN&tls=true&tlsCertificateKeyFile=/etc/certs/client.pem&tlsCaFile=/etc/certs/rootCA-cert.pem'
mongo-test:
desc: "Run legacy MongoDB shell (`mongo`) with test script"
Expand Down
4 changes: 1 addition & 3 deletions cmd/ferretdb/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ var tigrisFlags struct {
TigrisURL string `default:"127.0.0.1:8081" help:"Tigris URL for 'tigris' handler."`
TigrisClientID string `default:"" help:"Tigris Client ID."`
TigrisClientSecret string `default:"" help:"Tigris Client secret."`
TigrisToken string `default:"" help:"Tigris token."`
}

// The hanaFlags struct represents flags that are used specifically by "hana" handler.
Expand Down Expand Up @@ -311,10 +310,9 @@ func run() {

PostgreSQLURL: cli.PostgreSQLURL,

TigrisURL: tigrisFlags.TigrisURL,
TigrisClientID: tigrisFlags.TigrisClientID,
TigrisClientSecret: tigrisFlags.TigrisClientSecret,
TigrisToken: tigrisFlags.TigrisToken,
TigrisURL: tigrisFlags.TigrisURL,
})
if err != nil {
logger.Fatal(err.Error())
Expand Down
13 changes: 7 additions & 6 deletions ferretdb/ferretdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,17 @@ type Config struct {
Handler string

// PostgreSQL connection string for `pg` handler.
// See:
// * https://pkg.go.dev/github.com/jackc/pgx/v4/pgxpool#ParseConfig
// * https://pkg.go.dev/github.com/jackc/pgx/v4#ParseConfig
// * https://pkg.go.dev/github.com/jackc/pgconn#ParseConfig
PostgreSQLURL string // For example: `postgres://hostname:5432/ferretdb`.

// Tigris parameters for `tigris` handler.
// See https://docs.tigrisdata.com/overview/authentication
// and https://docs.tigrisdata.com/golang/getting-started.
// See https://www.tigrisdata.com/docs/sdkstools/golang/getting-started/
TigrisURL string
TigrisClientID string
TigrisClientSecret string
TigrisToken string
TigrisURL string
}

// ListenerConfig represents listener configuration.
Expand Down Expand Up @@ -107,10 +109,9 @@ func New(config *Config) (*FerretDB, error) {

PostgreSQLURL: config.PostgreSQLURL,

TigrisURL: config.TigrisURL,
TigrisClientID: config.TigrisClientID,
TigrisClientSecret: config.TigrisClientSecret,
TigrisToken: config.TigrisToken,
TigrisURL: config.TigrisURL,
})
if err != nil {
return nil, fmt.Errorf("failed to construct handler: %s", err)
Expand Down
2 changes: 1 addition & 1 deletion integration/shareddata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// because all needed functionality is already available in setup helpers.
// This file is skipped by default; we pass the build tag only in the `task env-data` command.

// go:build ferretdb_testenvdata
//go:build ferretdb_testenvdata

package integration

Expand Down
67 changes: 0 additions & 67 deletions internal/handlers/common/msg_saslstart.go

This file was deleted.

13 changes: 11 additions & 2 deletions internal/handlers/dummy/msg_saslstart.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@ package dummy
import (
"context"

"github.com/FerretDB/FerretDB/internal/handlers/common"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/must"
"github.com/FerretDB/FerretDB/internal/wire"
)

// MsgSASLStart implements HandlerInterface.
func (h *Handler) MsgSASLStart(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, error) {
return common.MsgSASLStart(ctx, msg)
var reply wire.OpMsg
must.NoError(reply.SetSections(wire.OpMsgSection{
Documents: []*types.Document{must.NotFail(types.NewDocument(
"done", true,
"ok", float64(1),
))},
}))

return &reply, nil
}
22 changes: 18 additions & 4 deletions internal/handlers/pg/pg.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"context"
"net/url"
"sync"
"time"

"go.uber.org/zap"

Expand Down Expand Up @@ -75,8 +76,8 @@ func (h *Handler) Close() {
h.rw.Lock()
defer h.rw.Unlock()

for k, pgPool := range h.pools {
pgPool.Close()
for k, p := range h.pools {
p.Close()
delete(h.pools, k)
}
}
Expand All @@ -98,18 +99,31 @@ func (h *Handler) DBPool(ctx context.Context) (*pgdb.Pool, error) {

url := u.String()

// fast path

h.rw.RLock()
p, ok := h.pools[url]
p := h.pools[url]
h.rw.RUnlock()

if ok {
if p != nil {
h.L.Debug("DBPool: found existing pool", zap.String("username", username))
return p, nil
}

// slow path

h.rw.Lock()
defer h.rw.Unlock()

// a concurrent connection might have created a pool already; check again
if p = h.pools[url]; p != nil {
h.L.Debug("DBPool: found existing pool (after acquiring lock)", zap.String("username", username))
return p, nil
}

ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()

p, err := pgdb.NewPool(ctx, url, h.L, h.StateProvider)
if err != nil {
h.L.Warn("DBPool: authentication failed", zap.String("username", username), zap.Error(err))
Expand Down
3 changes: 1 addition & 2 deletions internal/handlers/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ type NewHandlerOpts struct {
PostgreSQLURL string

// for `tigris` handler
TigrisURL string
TigrisClientID string
TigrisClientSecret string
TigrisToken string
TigrisURL string
}

// NewHandler constructs a new handler.
Expand Down
9 changes: 5 additions & 4 deletions internal/handlers/registry/tigris.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ import (
func init() {
registry["tigris"] = func(opts *NewHandlerOpts) (handlers.Interface, error) {
handlerOpts := &tigris.NewOpts{
ClientID: opts.TigrisClientID,
ClientSecret: opts.TigrisClientSecret,
Token: opts.TigrisToken,
URL: opts.TigrisURL,
AuthParams: tigris.AuthParams{
URL: opts.TigrisURL,
ClientID: opts.TigrisClientID,
ClientSecret: opts.TigrisClientSecret,
},

L: opts.Logger,
Metrics: opts.Metrics,
Expand Down
Loading

0 comments on commit 07cab1c

Please sign in to comment.