Skip to content

Commit

Permalink
Refactor non-interactive sessions out of proxy/sess.go (#12497)
Browse files Browse the repository at this point in the history
  • Loading branch information
xacrimon authored May 10, 2022
1 parent fd750dd commit bc09235
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 204 deletions.
79 changes: 74 additions & 5 deletions lib/kube/proxy/forwarder.go
Original file line number Diff line number Diff line change
Expand Up @@ -797,10 +797,6 @@ func (f *Forwarder) join(ctx *authContext, w http.ResponseWriter, req *http.Requ
return nil, trace.NotFound("session %v not found", sessionID)
}

if !session.tty {
return nil, trace.NotFound("session %v is not interactive", sessionID)
}

ws, err := f.upgrader.Upgrade(w, req, nil)
if err != nil {
return nil, trace.Wrap(err)
Expand Down Expand Up @@ -951,6 +947,75 @@ func (f *Forwarder) AcquireConnectionLock(ctx context.Context, user string, role
return nil
}

// execNonInteractive handles all exec sessions without a TTY.
func (f *Forwarder) execNonInteractive(ctx *authContext, w http.ResponseWriter, req *http.Request, p httprouter.Params, request remoteCommandRequest, proxy *remoteCommandProxy, sess *clusterSession) (resp interface{}, err error) {
defer proxy.Close()
roles, err := getRolesByName(f, ctx.Context.Identity.GetIdentity().Groups)
if err != nil {
return nil, trace.Wrap(err)
}

var policySets []*types.SessionTrackerPolicySet
for _, role := range roles {
policySet := role.GetSessionPolicySet()
policySets = append(policySets, &policySet)
}

authorizer := auth.NewSessionAccessEvaluator(policySets, types.KubernetesSessionKind)
canStart, _, err := authorizer.FulfilledFor(nil)
if err != nil {
return nil, trace.Wrap(err)
}
if !canStart {
return nil, trace.AccessDenied("insufficient permissions to launch non-interactive session")
}

eventPodMeta := request.eventPodMeta(request.context, sess.creds)
event := &apievents.Exec{
Metadata: apievents.Metadata{
Type: events.ExecEvent,
ClusterName: f.cfg.ClusterName,
},
ServerMetadata: apievents.ServerMetadata{
ServerID: f.cfg.ServerID,
ServerNamespace: f.cfg.Namespace,
},
SessionMetadata: apievents.SessionMetadata{
SessionID: uuid.NewString(),
WithMFA: ctx.Identity.GetIdentity().MFAVerified,
},
UserMetadata: ctx.eventUserMeta(),
ConnectionMetadata: apievents.ConnectionMetadata{
RemoteAddr: req.RemoteAddr,
LocalAddr: sess.kubeAddress,
Protocol: events.EventProtocolKube,
},
CommandMetadata: apievents.CommandMetadata{
Command: strings.Join(request.cmd, " "),
},
KubernetesClusterMetadata: ctx.eventClusterMeta(),
KubernetesPodMetadata: eventPodMeta,
}

if err := f.cfg.StreamEmitter.EmitAuditEvent(f.ctx, event); err != nil {
f.log.WithError(err).Warn("Failed to emit exec event.")
}

executor, err := f.getExecutor(*ctx, sess, req)
if err != nil {
f.log.WithError(err).Warning("Failed creating executor.")
return nil, trace.Wrap(err)
}

streamOptions := proxy.options()
if err = executor.Stream(streamOptions); err != nil {
f.log.WithError(err).Warning("Executor failed while streaming.")
return nil, trace.Wrap(err)
}

return nil, nil
}

// exec forwards all exec requests to the target server, captures
// all output from the session
func (f *Forwarder) exec(ctx *authContext, w http.ResponseWriter, req *http.Request, p httprouter.Params) (resp interface{}, err error) {
Expand Down Expand Up @@ -1005,6 +1070,11 @@ func (f *Forwarder) exec(ctx *authContext, w http.ResponseWriter, req *http.Requ
return f.remoteExec(ctx, w, req, p, sess, request, proxy)
}

if !request.tty {
resp, err = f.execNonInteractive(ctx, w, req, p, request, proxy, sess)
return
}

client := newKubeProxyClientStreams(proxy)
party := newParty(*ctx, types.SessionPeerMode, client)
session, err := newSession(*ctx, f, req, p, party, sess)
Expand Down Expand Up @@ -1035,7 +1105,6 @@ func (f *Forwarder) remoteExec(ctx *authContext, w http.ResponseWriter, req *htt
return nil, trace.Wrap(err)
}
streamOptions := proxy.options()

if err = executor.Stream(streamOptions); err != nil {
f.log.WithError(err).Warning("Executor failed while streaming.")
return nil, trace.Wrap(err)
Expand Down
Loading

0 comments on commit bc09235

Please sign in to comment.