Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/teleterm/clusters/cluster_databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,17 @@ func (c *Cluster) ReissueDBCerts(ctx context.Context, user, dbName string, db ty
return trace.BadParameter("please provide the database user name using --db-user flag")
}

// Refresh the certs to account for clusterClient.SiteName pointing at a leaf cluster.
err := c.clusterClient.ReissueUserCerts(ctx, client.CertCacheKeep, client.ReissueParams{
RouteToCluster: c.clusterClient.SiteName,
AccessRequests: c.status.ActiveRequests.AccessRequests,
})
if err != nil {
return trace.Wrap(err)
}

// Fetch the certs for the database.
err = c.clusterClient.ReissueUserCerts(ctx, client.CertCacheKeep, client.ReissueParams{
RouteToCluster: c.clusterClient.SiteName,
RouteToDatabase: proto.RouteToDatabase{
ServiceName: db.GetName(),
Expand Down
11 changes: 9 additions & 2 deletions lib/teleterm/clusters/cluster_gateways.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (c *Cluster) CreateGateway(ctx context.Context, params CreateGatewayParams)
TargetSubresourceName: params.TargetSubresourceName,
Protocol: db.GetProtocol(),
KeyPath: c.status.KeyPath(),
CertPath: c.status.DatabaseCertPathForCluster("", db.GetName()),
CertPath: c.status.DatabaseCertPathForCluster(c.clusterClient.SiteName, db.GetName()),
Insecure: c.clusterClient.InsecureSkipVerify,
WebProxyAddr: c.clusterClient.WebProxyAddr,
Log: c.Log.WithField("gateway", params.TargetURI),
Expand All @@ -84,7 +84,14 @@ func buildCLICommand(c *Cluster, gw *gateway.Gateway) (*exec.Cmd, error) {
Database: gw.TargetSubresourceName,
}

cmd, err := dbcmd.NewCmdBuilder(c.clusterClient, &c.status, &routeToDb, c.GetActualName(),
cmd, err := dbcmd.NewCmdBuilder(c.clusterClient, &c.status, &routeToDb,
// TODO(ravicious): Pass the root cluster name here. GetActualName returns leaf name for leaf
// clusters.
//
// At this point it doesn't matter though, because this argument is used only for
// generating correct CA paths. But we use dbcmd.WithNoTLS here, which doesn't include CA paths
// in the returned CLI command.
c.GetActualName(),
dbcmd.WithLogger(gw.Log),
dbcmd.WithLocalProxy(gw.LocalAddress, gw.LocalPortInt(), ""),
dbcmd.WithNoTLS(),
Expand Down
41 changes: 22 additions & 19 deletions lib/teleterm/clusters/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (s *Storage) ReadAll() ([]*Cluster, error) {

clusters := make([]*Cluster, 0, len(pfNames))
for _, name := range pfNames {
cluster, err := s.fromProfile(name)
cluster, err := s.fromProfile(name, "")
if err != nil {
return nil, trace.Wrap(err)
}
Expand All @@ -58,7 +58,7 @@ func (s *Storage) ReadAll() ([]*Cluster, error) {

// GetByName returns a cluster by name
func (s *Storage) GetByName(clusterName string) (*Cluster, error) {
cluster, err := s.fromProfile(clusterName)
cluster, err := s.fromProfile(clusterName, "")
if err != nil {
return nil, trace.Wrap(err)
}
Expand All @@ -72,17 +72,11 @@ func (s *Storage) GetByURI(clusterURI string) (*Cluster, error) {
rootClusterName := URI.GetRootClusterName()
leafClusterName := URI.GetLeafClusterName()

cluster, err := s.fromProfile(rootClusterName)
cluster, err := s.fromProfile(rootClusterName, leafClusterName)
if err != nil {
return nil, trace.Wrap(err)
}

if leafClusterName != "" {
cluster.clusterClient.SiteName = leafClusterName
}

cluster.URI = URI

return cluster, nil
}

Expand Down Expand Up @@ -161,20 +155,28 @@ func (s *Storage) addCluster(ctx context.Context, dir, webProxyAddress string) (
}

// fromProfile creates a new cluster from its profile
func (s *Storage) fromProfile(clusterName string) (*Cluster, error) {
if clusterName == "" {
func (s *Storage) fromProfile(profileName, leafClusterName string) (*Cluster, error) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an outstanding issue in Teleport Connect where all our URIs use the proxy hostname as the cluster name (which is equivalent to a profile name, I think). I'll create a separate ticket for it soon, but in general the problem is that the proxy hostname can be different than the root cluster name.

So when Storage.GetByURI calls fromProfile, this name is actually the profile name and not the real root cluster name from the key. I changed the argument name here from clusterName to profileName to signal that for the future.

if profileName == "" {
return nil, trace.BadParameter("cluster name is missing")
}

clusterNameForKey := profileName
clusterURI := uri.NewClusterURI(profileName)

cfg := client.MakeDefaultConfig()
if err := cfg.LoadProfile(s.Dir, clusterName); err != nil {
if err := cfg.LoadProfile(s.Dir, profileName); err != nil {
return nil, trace.Wrap(err)
}

cfg.KeysDir = s.Dir
cfg.HomePath = s.Dir
cfg.InsecureSkipVerify = s.InsecureSkipVerify

if leafClusterName != "" {
clusterNameForKey = leafClusterName
clusterURI = clusterURI.AppendLeafCluster(leafClusterName)
cfg.SiteName = leafClusterName
}

clusterClient, err := client.NewClient(cfg)
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -183,13 +185,13 @@ func (s *Storage) fromProfile(clusterName string) (*Cluster, error) {
status := &client.ProfileStatus{}

// load profile status if key exists
_, err = clusterClient.LocalAgent().GetKey(clusterName)
_, err = clusterClient.LocalAgent().GetKey(clusterNameForKey)
if err != nil {
s.Log.WithError(err).Infof("Unable to load the keys for cluster %v.", clusterName)
s.Log.WithError(err).Infof("Unable to load the keys for cluster %v.", clusterNameForKey)
}

if err == nil && cfg.Username != "" {
status, err = client.ReadProfileStatus(s.Dir, clusterName)
status, err = client.ReadProfileStatus(s.Dir, profileName)
if err != nil {
return nil, trace.Wrap(err)
}
Expand All @@ -202,10 +204,11 @@ func (s *Storage) fromProfile(clusterName string) (*Cluster, error) {
return nil, trace.Wrap(err)
}

clusterURI := uri.NewClusterURI(clusterName)
return &Cluster{
URI: clusterURI,
Name: clusterName,
URI: clusterURI,
// TODO(ravicious): This should probably use leafClusterName if available, but at this point I'm
// worried that changing it might break something else in the app.
Name: profileName,
Comment on lines +209 to +211
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment it doesn't cause any issues because Teleport Connect uses another code path to get names of leaf clusters.

Methods on Storage are used mostly to get a Cluster instance that lets us perform operations on the root/leaf cluster through TeleportClient.

clusterClient: clusterClient,
dir: s.Dir,
clock: s.Clock,
Expand Down