Skip to content
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

Merged
merged 3 commits into from Jan 21, 2021

Conversation

r0mant
Copy link
Collaborator

@r0mant r0mant commented Jan 15, 2021

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 ls
Name                               Description            Labels    Connect
---------------------------------- ---------------------- --------- -------------------------
> local (user: postgres, db: test) PostgreSQL 13.0: Local env=local psql "service=root-local"
  • Add 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:
➜  ~ tsh db config
Name:      local
Host:      root.gravitational.io
Port:      3080
User:      postgres
Database:  test
CA:        /Users/r0mant/.tsh/keys/root.gravitational.io/certs.pem
Cert:      /Users/r0mant/.tsh/keys/root.gravitational.io/r0mant-db/root/local-x509.pem
Key:       /Users/r0mant/.tsh/keys/root.gravitational.io/r0mant

@r0mant r0mant added the database-access Database access related issues and PRs label Jan 15, 2021
@r0mant r0mant added this to the 6.0 "San Diego" milestone Jan 15, 2021
@r0mant r0mant self-assigned this Jan 15, 2021
section.NewKey("sslcert", profile.SSLCert)
section.NewKey("sslkey", profile.SSLKey)
if profile.Insecure {
section.NewKey("sslmode", SSLModeVerifyCA)
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

lib/client/db/postgres/servicefile.go Show resolved Hide resolved
limitations under the License.
*/

// Package db contains methods for working with database connection profiles
Copy link
Contributor

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

Copy link
Collaborator Author

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.

Copy link
Contributor

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>/.

lib/client/db/profile.go Show resolved Hide resolved
limitations under the License.
*/

package profile
Copy link
Contributor

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/...?

Copy link
Collaborator Author

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.

Copy link
Contributor

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?

Copy link
Collaborator Author

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.

tool/tsh/db.go Outdated Show resolved Hide resolved
}
host, port := tc.WebProxyHostPort()
fmt.Printf(`Name: %v
Host: %v
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

tool/tsh/tsh.go Outdated Show resolved Hide resolved
@r0mant
Copy link
Collaborator Author

r0mant commented Jan 20, 2021

@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!

Copy link
Contributor

@a-palchikov a-palchikov left a 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
Copy link
Contributor

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
Copy link
Contributor

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?

tool/tsh/tsh.go Outdated Show resolved Hide resolved
lib/client/db/profile/profile.go Outdated Show resolved Hide resolved
Comment on lines +201 to +218
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)
}
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

@r0mant r0mant merged commit f7e6838 into master Jan 21, 2021
@r0mant r0mant deleted the roman/dbprofile branch January 21, 2021 23:21
pierrebeaucamp pushed a commit that referenced this pull request Jan 22, 2021
…e/dynamodb-audit-fix

* 'master' of github.com:gravitational/teleport:
  Refactor db proxy/engine for easier reuse (#5325)
  Refactor postgres service file handling, add db config command (#5319)
  Fix tsh login issue when --proxy differs from actual proxy public addr (#5380)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
database-access Database access related issues and PRs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add insecure mode support for database access
4 participants