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
Refactor postgres service file handling, add db config command #5319
Conversation
section.NewKey("sslcert", profile.SSLCert) | ||
section.NewKey("sslkey", profile.SSLKey) | ||
if profile.Insecure { | ||
section.NewKey("sslmode", SSLModeVerifyCA) |
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.
According to documentation, there are 6 SSL modes and the 3 require
, verify-ca
and verify-full
will error if Postgres was not compiled with SSL support - is this a concern in this case? Also looks like disable
or even allow
would make a better candidate for insecure mode than verify-ca
.
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.
It's not a concern because we require TLS for the database access. I'm using verify-ca for the same reason, all our routing/authentication it based on client certificates. Also, this is configuring client to talk to Teleport proxy, not Postgres.
limitations under the License. | ||
*/ | ||
|
||
// Package db contains methods for working with database connection profiles |
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.
Sounds like lib/client/db/profile
would be a more apt package location for working with profiles
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.
Can't move it there due to circular imports.
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'm not sure which imports you mean here, but my suggestion was to pull the interfaces (ConnectProfileFile
and ConnectProfile
) to lib/client/db
and implement support for profile handling for a specific database flavor in the corresponding lib/client/db/profile/<profile>
or lib/client/db/<flavor>/
.
limitations under the License. | ||
*/ | ||
|
||
package profile |
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 is probably meant to land in lib/client/db
instead - to be implemented by more specific packages in lib/client/db/...
?
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 really, this is intentional so particular implementations can reuse this struct from here. Can't move it level up due to circular imports.
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.
With the structs in lib/client/db
, they'd do exactly that. The specific provider implementation would use the struct from lib/client/db
. Of course this means lib/client/db/<provider>
cannot be used from lib/client/db
which does cause a circular dependency. But it should not have to - the providers should just register themselves somewhere in the root and the root would use them via an interface - does that make sense?
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.
Yeah, I know what you're saying, I just feel that introducing this sort of registry when I only need to share one struct between a couple of packages may be a bit of an overkill.
} | ||
host, port := tc.WebProxyHostPort() | ||
fmt.Printf(`Name: %v | ||
Host: %v |
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 would consider adding a format option for this to make this machine-parsable - this way it can be converted to any other format on the fly without much trouble.
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 is intended to be human-readable first. I agree it might make sense to add other format in future, I'll leave it as a potential improvements if anyone actually needs it.
fbb6ec8
to
335190f
Compare
@awly @a-palchikov @russjones @fspmarshall Can I please get some codeowners reviews when you get a chance? I'd like to get this merged so I can continue with MySQL integration. Thanks! |
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.
Feel free to merge if the suggested provider package layout is not warranted.
limitations under the License. | ||
*/ | ||
|
||
// Package db contains methods for working with database connection profiles |
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'm not sure which imports you mean here, but my suggestion was to pull the interfaces (ConnectProfileFile
and ConnectProfile
) to lib/client/db
and implement support for profile handling for a specific database flavor in the corresponding lib/client/db/profile/<profile>
or lib/client/db/<flavor>/
.
limitations under the License. | ||
*/ | ||
|
||
package profile |
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.
With the structs in lib/client/db
, they'd do exactly that. The specific provider implementation would use the struct from lib/client/db
. Of course this means lib/client/db/<provider>
cannot be used from lib/client/db
which does cause a circular dependency. But it should not have to - the providers should just register themselves somewhere in the root and the root would use them via an interface - does that make sense?
tc, err := makeClient(cf, false) | ||
if err != nil { | ||
utils.FatalError(err) | ||
} | ||
database, err := pickActiveDatabase(cf) | ||
if err != nil { | ||
utils.FatalError(err) | ||
} | ||
env, err := dbprofile.Env(tc, *database) | ||
if err != nil { | ||
utils.FatalError(err) | ||
} | ||
for k, v := range env { | ||
fmt.Printf("export %v=%v\n", k, v) | ||
} |
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.
You may not need this, but if you want to print some instructions as well, you can add something like the following:
fmt.Printf(`echo 'Environment loaded, run the following command to connect...\n'`)
I'm doing something similar for tsh login leaf.example.com --env
.
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.
The purpose of this command is for its output to be fed to shell's eval (like, $(tsh db env)
- similar to what minikube for example does as well). For easier discovery of the connect commands I added those to tsh db ls
table.
335190f
to
6acc78f
Compare
This PR belongs to a series of smaller self-contained database access PRs that I will be submitting to land various QoL improvements and refactorings to help keep future MySQL integration PR smaller.
This PR includes:
Refactor and reorganize Postgres connection service file handling a bit to make adding MySQL option file easier.
While being at it, also added support for
--insecure
flag for Postgres service file. Closes Add insecure mode support for database access #5026.tsh db ls
command output now includes an example connect command to make it easier for users to learn how to connect to a database (can just copy-paste). Example:tsh db config
command that prints database connection information in text form. I realized the need for a command like this when configuring GUI clients - they often require entering paths for certificates for example, and regular users may not know where Teleport stores them on their machine. Example: