- Notifications
You must be signed in to change notification settings - Fork1.1k
feat: add support for reading db connection string from a file#20910
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
72b7eca0a17d8fe6da2058b42b2a5d9dbaa7cff6736dfd6cbdf7b098b25ed30File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -76,6 +76,7 @@ import ( | ||
| "github.com/coder/coder/v2/coderd/database/dbmetrics" | ||
| "github.com/coder/coder/v2/coderd/database/dbpurge" | ||
| "github.com/coder/coder/v2/coderd/database/migrations" | ||
| "github.com/coder/coder/v2/coderd/database/pgfileurl" | ||
| "github.com/coder/coder/v2/coderd/database/pubsub" | ||
| "github.com/coder/coder/v2/coderd/devtunnel" | ||
| "github.com/coder/coder/v2/coderd/entitlements" | ||
| @@ -433,6 +434,31 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. | ||
| } | ||
| config := r.createConfig() | ||
| // If a postgres URL file is specified, register a driver that | ||
| // re-reads the file on each connection attempt. This supports | ||
| // credential rotation without restarting the server. | ||
| if vals.PostgresURLFile != "" { | ||
| if vals.PostgresURL != "" { | ||
| return xerrors.Errorf("cannot specify both --postgres-url and --postgres-url-file flags") | ||
| } | ||
| // Read the URL once for initial validation and migrations. | ||
| logger.Debug(ctx, "coderd: database connection URL sourced from file") | ||
| postgresURL, err := ReadPostgresURLFromFile(vals.PostgresURLFile.String()) | ||
Member 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. We need some sort of go sql driver BS so we can get this to be read on every single connection attempt. Reading it once on startup won't resolve the customer's problem. | ||
| if err != nil { | ||
| return err | ||
| } | ||
| if err := vals.PostgresURL.Set(postgresURL); err != nil { | ||
| return xerrors.Errorf("set database URL from file: %w", err) | ||
| } | ||
| // Register a driver that re-reads the file on each new connection. | ||
| sqlDriver, err = pgfileurl.Register(sqlDriver, vals.PostgresURLFile.String(), logger) | ||
| if err != nil { | ||
| return xerrors.Errorf("register database file URL driver: %w", err) | ||
| } | ||
| } else if vals.PostgresURL != "" { | ||
| logger.Debug(ctx, "database connection URL sourced from environment variable") | ||
| } | ||
| builtinPostgres := false | ||
| // Only use built-in if PostgreSQL URL isn't specified! | ||
| if vals.PostgresURL == "" { | ||
| @@ -2820,6 +2846,58 @@ func signalNotifyContext(ctx context.Context, inv *serpent.Invocation, sig ...os | ||
| return inv.SignalNotifyContext(ctx, sig...) | ||
| } | ||
| // ReadPostgresURLFromFile reads a PostgreSQL connection URL from a file. The | ||
| // file contents are trimmed of whitespace. This is useful for reading secrets | ||
| // from files, such as Docker or Kubernetes secrets. | ||
| func ReadPostgresURLFromFile(filePath string) (string, error) { | ||
| content, err := os.ReadFile(filePath) | ||
| if err != nil { | ||
| return "", xerrors.Errorf("read postgres URL file %q: %w", filePath, err) | ||
| } | ||
| return strings.TrimSpace(string(content)), nil | ||
| } | ||
| // PostgresParams holds parameters for resolving a postgres connection. | ||
| type PostgresParams struct { | ||
| // URL is the direct connection URL (from --postgres-url or CODER_PG_CONNECTION_URL). | ||
| URL string | ||
| // URLFile is the path to a file containing the connection URL | ||
| // (from --postgres-url-file or CODER_PG_CONNECTION_URL_FILE). | ||
| URLFile string | ||
| // Auth is the authentication method (e.g., "password" or "awsiamrds"). | ||
| Auth string | ||
| } | ||
| // ResolvePostgresParams resolves the postgres connection URL and SQL driver. | ||
| // It handles mutual exclusion between URL and URLFile, reads the URL from file | ||
| // if specified, and registers the appropriate SQL driver based on the auth type. | ||
| // Returns the driver name and the resolved URL. | ||
| func ResolvePostgresParams(ctx context.Context, params PostgresParams, baseDriver string) (driver string, dbURL string, err error) { | ||
| dbURL = params.URL | ||
| // Handle mutual exclusion and file reading. | ||
| if params.URLFile != "" { | ||
| if params.URL != "" { | ||
| return "", "", xerrors.Errorf("cannot specify both --postgres-url and --postgres-url-file") | ||
| } | ||
| dbURL, err = ReadPostgresURLFromFile(params.URLFile) | ||
| if err != nil { | ||
| return "", "", err | ||
| } | ||
| } | ||
| // Register the appropriate driver. | ||
| driver = baseDriver | ||
| if codersdk.PostgresAuth(params.Auth) == codersdk.PostgresAuthAWSIAMRDS { | ||
| driver, err = awsiamrds.Register(ctx, driver) | ||
| if err != nil { | ||
| return "", "", xerrors.Errorf("register aws rds iam auth: %w", err) | ||
| } | ||
| } | ||
| return driver, dbURL, nil | ||
| } | ||
| func getAndMigratePostgresDB(ctx context.Context, logger slog.Logger, postgresURL string, auth codersdk.PostgresAuth, sqlDriver string) (*sql.DB, string, error) { | ||
| dbURL, err := escapePostgresURLUserInfo(postgresURL) | ||
| if err != nil { | ||
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.