-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Generate DB CLI commands for Teleterm from tsh daemon #11835
Conversation
I'll fix the lint problems on Monday. |
lib/client/db/dbcmd/dbcmd.go
Outdated
// Check for mysql binary. Return with error as mysql and mariadb are missing. There is nothing else we can do here. | ||
if !c.isMySQLBinAvailable() { | ||
return nil, trace.NotFound("neither %q nor %q CLI clients were found, please make sure an appropriate CLI client is available in $PATH", mysqlBin, mariadbBin) | ||
} | ||
|
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.
This was removed so that dbcmd doesn't fail for Teleterm if the user doesn't have the binaries installed.
For the most part, the DB CLI command in Teleterm has a more "decorative" function – unlike tsh db connect
, it doesn't have to actually work on the user's machine.
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.
Left a few nits but mostly lgtm.
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.
I took quick look and left some comments.
routeToDb := tlsca.RouteToDatabase{ | ||
ServiceName: gw.TargetName, | ||
Protocol: gw.Protocol, | ||
Username: gw.TargetUser, | ||
} |
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.
Seems that database name is missing.
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.
Right, for now there's no way for the user to specify the db name anyway.
} | ||
|
||
cmd, err := dbcmd.NewCmdBuilder(c.clusterClient, &c.status, &routeToDb, c.URI.GetRootClusterName(), | ||
dbcmd.WithLocalProxy(gw.LocalAddress, gw.LocalPortInt(), ""), |
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.
Not sure if it the last argument - caPath should be empty. For example mongo, and redis commands are using this arg to overwrite CA
Line 333 in 97c0b5c
if c.options.caPath != "" { |
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.
They do this only in the absence of the noTLS
option and this callsite here will always use dbcmd.WithNoTLS()
.
Perhaps in the future it'd be worthwhile to refactor connectionCommandOpts
so that it's not possible to pass mutually exclusive options.
} | ||
|
||
// Check for mysql binary. Return with error as mysql and mariadb are missing. There is nothing else we can do here. | ||
if !c.isMySQLBinAvailable() { |
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.
Is there a way for Teleterm to deal with that error?
- Currently if none of the supported binaries are installed
tsh
will printmysql not found not mentioning that
mariadb` is also a supported client - If Teleterm fails on every error returned from
CLIBuildder
then another person working on that code can easily return an error and break the Teleterm. If this is the case I'd suggest removing theerror
from returned values.
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.
If Teleterm fails on every error returned from
CLIBuildder
then another person working on that code can easily return an error and break the Teleterm.
Good point.
The fundamental issue is that tsh db connect
expects dbcmd
to return a command that will work and if it can't provide one, it should either return an appropriate error or attempt to execute the command which will result in the <binary> not found
error.
tsh db connect
also executes dbcmd
only when the command is actually needed. So if someone has a cluster with a Postgres db but they don't have psql
installed it and they never try to access it, nothing bad ever happens.
Teleterm on the other hand doesn't expect this command to work. It's more of a "if you have the CLI client installed on your system, this command should connect you to that db". It also needs this command any time it creates a local proxy for the db, but the user might not even want to use that command. They might want to use a GUI app. So again, in this case we don't really care if the binary is actually on the system.
@jakule What if we added a tolerateMissingCLIClient
flag to connectionCommandOpts
? If it's present, dbcmd would not return an error here, but rather c.getMySQLOracleCommand()
.
#11843 added the printFormat
flag so that tsh db config
can wrap Postgres connection strings in quotes. With tolerateMissingCLIClient
, the option usage would look like this:
use case | printFormat | tolerateMissingCLIClient |
---|---|---|
tsh db config | ✅ | ❌ |
tsh db connect | ❌ | ❌ |
Teleterm | ✅ | ✅ |
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.
@jakule I added a comment which adds said option, please let me know what you think.
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.
Fine by me. I'd just change the name of that flag to ignoreMissingBin
or skipBinCheck
maybe?
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.
Please also add a test with this flag set.
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.
Heh, I thought about a name like this. However, for all the other protocols, dbcmd doesn't actually check if the binary is there or not – attempting to run the resulting command is just going to fail with a regular shell error about a missing binary.
At the moment it really is just a special case for MySQL where instead of telling the user that mysql
doesn't exist we also want to point out that mariadb
is a valid option too. So I didn't want to use a field name that would suggest that if the field is not present then the check will be done.
In that sense it's more of a caller telling dbcmd "I'm okay with the CLI missing on user's system".
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.
Please also add a test with this flag set.
Yep, I already added one that makes mysql and mariadb not available and expects that the method will not return an error.
Teleterm wasn't launch yet, so we don't have to worry too much about backwards compatibility in the proto files and we can just repurpose old field numbers.
1e650a8
to
dd1d11c
Compare
b73446b
to
d60bf57
Compare
* Extract dbcmd.go into a new package under lib/client/db/dbcmd * Use dbcmd to generate CliCommand for gateways * Return relative db command from tsh daemon * Add WithTolarateMissingCLIClient func to dbcmd
* Extract dbcmd.go into a new package under lib/client/db/dbcmd * Use dbcmd to generate CliCommand for gateways * Return relative db command from tsh daemon * Add WithTolarateMissingCLIClient func to dbcmd
…commands for Teleport Connect (#12206) * Quote postgres connection string for printing to terminals (#11843) * Generate DB CLI commands for Teleterm from tsh daemon (#11835) * Extract dbcmd.go into a new package under lib/client/db/dbcmd * Use dbcmd to generate CliCommand for gateways * Return relative db command from tsh daemon * Add WithTolarateMissingCLIClient func to dbcmd Co-authored-by: STeve (Xin) Huang <xin.huang@goteleport.com>
lib/teleterm/api/protogen
are autogenerated from proto files.To test this change in Teleterm, you need a dev version of Teleterm with gravitational/webapps#726.
Why
When you connect to a cluster with Teleterm and click "Connect" next to a database, it sets up the equivalent of
tsh proxy db --tunnel
(--tunnel
was added in #11720).However, up until this point, Teleterm was constructing the DB CLI commands by hand, meaning that each time the Database Access team adds support for a new protocol, we'd need to update Teleterm. In general, we'd need to keep both places in sync.
What
@smallinsky suggested to generate those inside the tsh daemon and this is what this PR achieves.
On top of that, it adds
GetRelativeConnectCommand
so that Teleterm doesn't have to show absolute paths to the binaries.