mirror of
https://github.com/gravitational/teleport.git
synced 2026-11-03 07:40:28 +08:00
Only DynamoDB and AWS MongoDB Atlas depended on GetAWSSession, and the migration for these packages was trivial. Since this was the last AWS method in lib/cloud/clients, the vast majority of the changes are to remove dead code.
135 lines
3.8 KiB
Go
135 lines
3.8 KiB
Go
// Teleport
|
|
// Copyright (C) 2024 Gravitational, Inc.
|
|
//
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/gravitational/trace"
|
|
"github.com/jackc/pgx/v4"
|
|
|
|
dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1"
|
|
"github.com/gravitational/teleport/api/types"
|
|
"github.com/gravitational/teleport/lib/srv/db/common/databaseobjectimportrule"
|
|
"github.com/gravitational/teleport/lib/srv/db/objects"
|
|
)
|
|
|
|
// TODO(Tener): add e2e tests for objectFetcher.
|
|
type objectFetcher struct {
|
|
cfg objects.ObjectFetcherConfig
|
|
db types.Database
|
|
}
|
|
|
|
var _ objects.ObjectFetcher = (*objectFetcher)(nil)
|
|
|
|
func NewObjectFetcher(ctx context.Context, db types.Database, cfg objects.ObjectFetcherConfig) (objects.ObjectFetcher, error) {
|
|
if db.GetAdminUser().Name == "" {
|
|
return nil, objects.NewErrFetcherDisabled("no admin user configured")
|
|
}
|
|
return &objectFetcher{cfg: cfg, db: db}, nil
|
|
}
|
|
|
|
func (f *objectFetcher) FetchAll(ctx context.Context, dbNameFilter databaseobjectimportrule.DbNameFilter) (map[string]objects.FetchResult, error) {
|
|
names, err := f.getDatabaseNames(ctx)
|
|
if err != nil {
|
|
return nil, trace.Wrap(err)
|
|
}
|
|
|
|
result := make(map[string]objects.FetchResult)
|
|
|
|
for _, dbName := range names {
|
|
if dbNameFilter(dbName) == false {
|
|
continue
|
|
}
|
|
objs, fetchErr := f.FetchOneDatabase(ctx, dbName)
|
|
result[dbName] = objects.FetchResult{
|
|
Objects: objs,
|
|
Error: fetchErr,
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (f *objectFetcher) FetchOneDatabase(ctx context.Context, databaseName string) ([]*dbobjectv1.DatabaseObject, error) {
|
|
conn, err := f.connectAsAdmin(ctx, databaseName)
|
|
if err != nil {
|
|
return nil, trace.Wrap(err)
|
|
}
|
|
defer conn.Close(ctx)
|
|
|
|
objsFetched, err := fetchDatabaseObjects(ctx, f.db, databaseName, conn)
|
|
if err != nil {
|
|
return nil, trace.Wrap(err)
|
|
}
|
|
f.cfg.Log.InfoContext(ctx, "fetched objects from database", "count", len(objsFetched))
|
|
|
|
return objsFetched, nil
|
|
}
|
|
|
|
func (f *objectFetcher) getDatabaseNames(ctx context.Context) ([]string, error) {
|
|
dbName := f.db.GetAdminUser().DefaultDatabase
|
|
if dbName == "" {
|
|
dbName = "postgres"
|
|
f.cfg.Log.WarnContext(ctx, "No default database configured, using default.", "db_name", dbName)
|
|
}
|
|
conn, err := f.connectAsAdmin(ctx, dbName)
|
|
if err != nil {
|
|
return nil, trace.Wrap(err)
|
|
}
|
|
defer conn.Close(ctx)
|
|
|
|
rows, err := conn.Query(context.Background(), "SELECT pg_database.datname FROM pg_catalog.pg_database WHERE pg_database.datistemplate = false;")
|
|
if err != nil {
|
|
return nil, trace.Wrap(err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var databases []string
|
|
for rows.Next() {
|
|
var datname string
|
|
err := rows.Scan(&datname)
|
|
if err != nil {
|
|
return nil, trace.Wrap(err)
|
|
}
|
|
databases = append(databases, datname)
|
|
}
|
|
|
|
if rows.Err() != nil {
|
|
return nil, trace.Wrap(rows.Err())
|
|
}
|
|
|
|
return databases, nil
|
|
}
|
|
|
|
func (f *objectFetcher) connectAsAdmin(ctx context.Context, databaseName string) (*pgx.Conn, error) {
|
|
conn := &connector{
|
|
auth: f.cfg.Auth,
|
|
gcpClients: f.cfg.GCPClients,
|
|
log: f.cfg.Log,
|
|
|
|
certExpiry: time.Now().Add(time.Hour),
|
|
database: f.db,
|
|
databaseUser: f.db.GetAdminUser().Name,
|
|
databaseName: databaseName,
|
|
|
|
startupParams: map[string]string{},
|
|
}
|
|
return conn.connectAsAdmin(ctx)
|
|
}
|