Skip to content

Commit

Permalink
Add Session tracker to DB, App, and Windows Desktop Sessions (#12304)
Browse files Browse the repository at this point in the history
  • Loading branch information
Joerger committed May 12, 2022
1 parent a269244 commit 3b3f925
Show file tree
Hide file tree
Showing 28 changed files with 2,762 additions and 2,132 deletions.
45 changes: 36 additions & 9 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2424,7 +2424,7 @@ func (c *Client) CreateRegisterChallenge(ctx context.Context, in *proto.CreateRe

// GenerateCertAuthorityCRL generates an empty CRL for a CA.
func (c *Client) GenerateCertAuthorityCRL(ctx context.Context, req *proto.CertAuthorityRequest) (*proto.CRL, error) {
resp, err := c.grpc.GenerateCertAuthorityCRL(ctx, req)
resp, err := c.grpc.GenerateCertAuthorityCRL(ctx, req, c.callOpts...)
return resp, trail.FromGRPC(err)
}

Expand Down Expand Up @@ -2524,21 +2524,48 @@ func GetResourcesWithFilters(ctx context.Context, clt ListResourcesClient, req p
}

// CreateSessionTracker creates a tracker resource for an active session.
func (c *Client) CreateSessionTracker(ctx context.Context, req *proto.CreateSessionTrackerRequest) (types.SessionTracker, error) {
resp, err := c.grpc.CreateSessionTracker(ctx, req)
return resp, trail.FromGRPC(err)
func (c *Client) CreateSessionTracker(ctx context.Context, st types.SessionTracker) (types.SessionTracker, error) {
v1, ok := st.(*types.SessionTrackerV1)
if !ok {
return nil, trace.BadParameter("invalid type %T, expected *types.SessionTrackerV1", st)
}

req := &proto.CreateSessionTrackerRequest{SessionTracker: v1}

// DELETE IN 11.0.0
// Early v9 versions use a flattened out types.SessionTrackerV1
req.ID = v1.Spec.SessionID
req.Type = v1.Spec.Kind
req.Reason = v1.Spec.Reason
req.Invited = v1.Spec.Invited
req.Hostname = v1.Spec.Hostname
req.Address = v1.Spec.Address
req.ClusterName = v1.Spec.ClusterName
req.Login = v1.Spec.Login
req.Expires = v1.Spec.Expires
req.KubernetesCluster = v1.Spec.KubernetesCluster
req.HostUser = v1.Spec.HostUser
if len(v1.Spec.Participants) > 0 {
req.Initiator = &v1.Spec.Participants[0]
}

tracker, err := c.grpc.CreateSessionTracker(ctx, req, c.callOpts...)
if err != nil {
return nil, trail.FromGRPC(err)
}
return tracker, nil
}

// GetSessionTracker returns the current state of a session tracker for an active session.
func (c *Client) GetSessionTracker(ctx context.Context, sessionID string) (types.SessionTracker, error) {
req := &proto.GetSessionTrackerRequest{SessionID: sessionID}
resp, err := c.grpc.GetSessionTracker(ctx, req)
resp, err := c.grpc.GetSessionTracker(ctx, req, c.callOpts...)
return resp, trail.FromGRPC(err)
}

// GetActiveSessionTrackers returns a list of active session trackers.
func (c *Client) GetActiveSessionTrackers(ctx context.Context) ([]types.SessionTracker, error) {
stream, err := c.grpc.GetActiveSessionTrackers(ctx, &empty.Empty{})
stream, err := c.grpc.GetActiveSessionTrackers(ctx, &empty.Empty{}, c.callOpts...)
if err != nil {
return nil, trail.FromGRPC(err)
}
Expand All @@ -2562,18 +2589,18 @@ func (c *Client) GetActiveSessionTrackers(ctx context.Context) ([]types.SessionT

// RemoveSessionTracker removes a tracker resource for an active session.
func (c *Client) RemoveSessionTracker(ctx context.Context, sessionID string) error {
_, err := c.grpc.RemoveSessionTracker(ctx, &proto.RemoveSessionTrackerRequest{SessionID: sessionID})
_, err := c.grpc.RemoveSessionTracker(ctx, &proto.RemoveSessionTrackerRequest{SessionID: sessionID}, c.callOpts...)
return trail.FromGRPC(err)
}

// UpdateSessionTracker updates a tracker resource for an active session.
func (c *Client) UpdateSessionTracker(ctx context.Context, req *proto.UpdateSessionTrackerRequest) error {
_, err := c.grpc.UpdateSessionTracker(ctx, req)
_, err := c.grpc.UpdateSessionTracker(ctx, req, c.callOpts...)
return trail.FromGRPC(err)
}

// MaintainSessionPresence establishes a channel used to continuously verify the presence for a session.
func (c *Client) MaintainSessionPresence(ctx context.Context) (proto.AuthService_MaintainSessionPresenceClient, error) {
stream, err := c.grpc.MaintainSessionPresence(ctx)
stream, err := c.grpc.MaintainSessionPresence(ctx, c.callOpts...)
return stream, trail.FromGRPC(err)
}
1,306 changes: 691 additions & 615 deletions api/client/proto/authservice.pb.go

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions api/client/proto/authservice.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1529,55 +1529,73 @@ message ListResourcesResponse {
// This is not specific to any session type. Relevant fields should be set for a given session type.
message CreateSessionTrackerRequest {
// Namespace is a session namespace, separating sessions from each other.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string Namespace = 1 [ (gogoproto.jsontag) = "namespace,omitempty" ];

// Type describes what type of session this is.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string Type = 2 [ (gogoproto.jsontag) = "type,omitempty" ];

// Reason is an arbitrary string that may be used to describe the session and/or it's
// purpose.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string Reason = 3 [ (gogoproto.jsontag) = "reason,omitempty" ];

// Invited is a list of invited users, this field is interpreted by different
// clients on a best-effort basis and used for delivering notifications to invited users.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
repeated string Invited = 4 [ (gogoproto.jsontag) = "invited,omitempty" ];

// Hostname is the address of the target this session is connected to.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string Hostname = 5 [ (gogoproto.jsontag) = "target_hostname,omitempty" ];

// Address is the address of the target this session is connected to.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string Address = 6 [ (gogoproto.jsontag) = "target_address,omitempty" ];

// ClusterName is the name of cluster that this session belongs to.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string ClusterName = 7 [ (gogoproto.jsontag) = "cluster_name,omitempty" ];

// Login is the local login/user on the target used by the session.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string Login = 8 [ (gogoproto.jsontag) = "login,omitempty" ];

// Initiator is the participant that initiated the session.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
types.Participant Initiator = 9 [ (gogoproto.jsontag) = "initiator,omitempty" ];

// Expires encodes the time at which this session expires and becomes invalid.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
google.protobuf.Timestamp Expires = 10 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "expires,omitempty"
];

// The Kubernetes cluster this session belongs to.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string KubernetesCluster = 11 [ (gogoproto.jsontag) = "kubernetes_cluster,omitempty" ];

// HostUser is the user regarded as the owner of this session, RBAC checks are performed
// against the require policies of this user.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string HostUser = 12 [ (gogoproto.jsontag) = "host_user,omitempty" ];

// ID is the ID of the session.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
string ID = 13 [ (gogoproto.jsontag) = "id,omitempty" ];

// HostPolicies is a list of RBAC policy sets held by the host user at the time of session
// creation.
// DELETE IN V11 - deprecated/reserve in favor of SessionTracker field.
repeated types.SessionTrackerPolicySet HostPolicies = 14
[ (gogoproto.jsontag) = "host_policies,omitempty" ];

// SessionTracker is the session tracker to be created.
types.SessionTrackerV1 SessionTracker = 15
[ (gogoproto.jsontag) = "session_tracker,omitempty" ];
}

// GetSessionTrackerRequest is a request to fetch a session resource.
Expand Down
3 changes: 3 additions & 0 deletions api/defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ const (
// deviation added to this time to avoid lots of simultaneous
// heartbeats coming to auth server
ServerAnnounceTTL = 600 * time.Second

// SessionTrackerTTL defines the default base ttl of a session tracker.
SessionTrackerTTL = time.Hour
)

var (
Expand Down
36 changes: 31 additions & 5 deletions api/types/session_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,20 @@ package types
import (
"time"

"github.com/gravitational/teleport/api/defaults"

"github.com/gravitational/trace"
)

const (
SSHSessionKind SessionKind = "ssh"
KubernetesSessionKind SessionKind = "k8s"
SessionObserverMode SessionParticipantMode = "observer"
SessionModeratorMode SessionParticipantMode = "moderator"
SessionPeerMode SessionParticipantMode = "peer"
SSHSessionKind SessionKind = "ssh"
KubernetesSessionKind SessionKind = "k8s"
DatabaseSessionKind SessionKind = "db"
AppSessionKind SessionKind = "app"
WindowsDesktopSessionKind SessionKind = "desktop"
SessionObserverMode SessionParticipantMode = "observer"
SessionModeratorMode SessionParticipantMode = "moderator"
SessionPeerMode SessionParticipantMode = "peer"
)

// SessionKind is a type of session.
Expand All @@ -52,6 +57,9 @@ type SessionTracker interface {
// SetState sets the state of the session.
SetState(SessionState) error

// SetCreated sets the time at which the session was created.
SetCreated(time.Time)

// GetCreated returns the time at which the session was created.
GetCreated() time.Time

Expand Down Expand Up @@ -186,6 +194,19 @@ func (s *SessionTrackerV1) CheckAndSetDefaults() error {
return trace.Wrap(err)
}

if s.GetCreated().IsZero() {
s.SetCreated(time.Now())
}

if s.Expiry().IsZero() {
// By default, resource expiration should match session expiration.
expiry := s.GetExpires()
if expiry.IsZero() {
expiry = s.GetCreated().Add(defaults.SessionTrackerTTL)
}
s.SetExpiry(expiry)
}

return nil
}

Expand Down Expand Up @@ -220,6 +241,11 @@ func (s *SessionTrackerV1) GetCreated() time.Time {
return s.Spec.Created
}

// SetCreated returns the time at which the session was created.
func (s *SessionTrackerV1) SetCreated(created time.Time) {
s.Spec.Created = created
}

// GetExpires return the time at which the session expires.
func (s *SessionTrackerV1) GetExpires() time.Time {
return s.Spec.Expires
Expand Down
Loading

0 comments on commit 3b3f925

Please sign in to comment.