doctl databases pool create (fails when --user arg not provided)
Describe the Issue:
-
According to the DO Dashboard, connection pools can have the user field (also known as
User privileges override (Optional)) set to an empty string (which appears asN/Ain the table shown on the Connection Pools tab for a Postgres database). The empty string corresponds to "Use inbound user" in the DO Dashboard.
name,mode,sizeanddbare required, butuseris not required.
- When using
doctl databases pool create <database-cluster-id> <pool-name> --size 25 --db <a-database-name-that-exists-inside-database-cluster-id-provided> --mode transaction, I see an error message appear:
Error: (pool.create.user) command is missing required arguments
See "Additional Details" below for a possible fix.
Environment:
- doctl version:
1.142.0-release(Git commit hash: 4979b33d) - OS: Ubuntu 20.04.4 LTS
- Installation method: Installed binary from tarball (https://github.com/digitalocean/doctl/releases/download/v1.142.0/doctl-1.142.0-linux-amd64.tar.gz)
Additional Details:
Since the --user arg is not marked as a requiredOpt() in https://github.com/digitalocean/doctl/blob/c74c583764a12cc7ddb353acfe2733c5d20bc5d5/commands/databases.go#L1239-L1240
I believe the problem lies with
https://github.com/digitalocean/doctl/blob/c74c583764a12cc7ddb353acfe2733c5d20bc5d5/commands/databases.go#L1344-L1348
which probably needs to be modified so it doesn't throw an error if no --user arg is provided.
Can I be assigned this issue to contribute?
! please assign
- Explanation of the fix
We must detect whether the --user flag was explicitly passed. If it was passed we set req.User to the value the user provided (including "", so that --user "" results in empty string). If it was not passed we must not set the field, because the API expects the field to be optional and doctl should not force a value or raise an error.
Using Cobra's flag Changed boolean is reliable: it tells us whether the user actually passed the flag on the command line. This lets us support both:
doctl databases pool create ... (no --user → omit user from request),
doctl databases pool create ... --user "dbuser" (set user),
doctl databases pool create ... --user "" (explicitly set user to empty string — matches "Use inbound user").
- Patch (replace the existing user-read block)
Find the location in doctl/commands/databases.go where the code currently reads the user:
// old (problematic) code user, err := c.Doit.GetString(c.NS, doctl.ArgDatabasePoolUserName) if err != nil { return nil, err } req.User = user
Replace it with this updated block:
// new (fixed) code:
// Only set req.User if the user explicitly passed the --user flag.
// This allows omission (flag not provided) to mean "do not include the field"
// while still allowing explicit empty-string values (e.g. --user "").
if f := c.Cmd.Flags().Lookup(doctl.ArgDatabasePoolUserName); f != nil && f.Changed {
user, err := c.Doit.GetString(c.NS, doctl.ArgDatabasePoolUserName)
if err != nil {
return nil, err
}
// Set req.User even if user == "". An explicit empty string is meaningful
// (represents "Use inbound user" in the Dashboard/API).
req.User = user
}
Notes:
c.Cmd is the Cobra command instance available from the CmdConfig (c) passed to the handler. If your CmdConfig field is named differently, substitute accordingly.
Flags().Lookup(...).Changed is the standard Cobra API that indicates whether the flag was supplied in this invocation.
We keep c.Doit.GetString for proper parsing and viper integration, but only call it when the flag is actually present.
- Test & Verification
Manual tests to run locally (after building the doctl binary from the updated source):
No user flag — should succeed (do not get the pool.create.user "missing arg" error):
doctl databases pool create
Expect: pool created; the CLI sends a payload without user field.
Explicit non-empty user:
doctl databases pool create
Expect: pool created; payload includes "user":"dbuser".
Explicit empty user:
doctl databases pool create
Expect: pool created; payload includes "user":"" (empty string) — this corresponds to "Use inbound user" behavior in the Dashboard.
Edge cases:
Short and long flag variants (if applicable).
Quoting rules for shells (some shells collapse --user "" — ensure quoting preserved).
Automated tests
If your test harness mocks the Do client, add tests to:
verify when flag not passed the request JSON does not contain user,
verify when flag passed empty string the request JSON contains "user":"",
verify when flag passed non-empty string that value is present.
- Documentation
Update the help text and docs for doctl databases pool create to explicitly call out the following:
--user is optional.
If you explicitly pass --user "" (empty string) it sets the pool user to empty, which corresponds to the Dashboard option "Use inbound user" (N/A in table).
If you omit --user entirely, the field will be omitted from the API request and default behavior will be used.
A brief addition to the command help is helpful, e.g.:
AddStringFlag(cmdDatabasePoolCreate, doctl.ArgDatabasePoolUserName, "", "", "The username for the database user (optional). To use 'Use inbound user' behavior, pass --user "" explicitly.")
- What I can do next
I can prepare a small PR patch (ready to apply) in the exact project layout with context lines if you want.
I can add unit tests that mock HTTP requests to verify the three behaviors (no flag / empty flag / non-empty flag).
I can update the help string in doctl/commands/databases.go and include a CHANGELOG note for release.
Would you like me to prepare the PR and include unit tests and documentation edits?
Please assign me this issue to implement the above plan
@K-Preetham-Reddy assigned the issue to you:)