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

Add way to specify user for exec command. #511

Merged
merged 11 commits into from
Nov 22, 2024
23 changes: 23 additions & 0 deletions services/exec/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Exec
Executes arbitrary command remotely and returns the response.

## Usage

### sanssh exec run

For SoT of command line reference run `sanssh exec help run`.

```bash
sanssh <sanssh-args> exec run [--stream] [--user user] <command> [<args>...]
```

Run a command remotely and return the response.

Note: This is not optimized for large output or long running commands. If
the output doesn't fit in memory in a single proto message or if it doesn't
complete within the timeout, you'll have a bad time.

Where:
- `<sanssh-args>` common sanssh arguments
- `<stream>` flag can be used to stream back command output as the command runs. It doesn't affect the timeout.
- `<user>` lag allows to specify a user for running command, equivalent of `sudo -u <user> <command> ...`
9 changes: 7 additions & 2 deletions services/exec/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func (p *execCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interfac

type runCmd struct {
streaming bool
user string

// returnCode internally keeps track of the final status to return
returnCode subcommands.ExitStatus
Expand All @@ -75,7 +76,7 @@ type runCmd struct {
func (*runCmd) Name() string { return "run" }
func (*runCmd) Synopsis() string { return "Run provided command and return a response." }
func (*runCmd) Usage() string {
return `run [--stream] <command> [<args>...]:
return `run [--stream] [--user=user] <command> [<args>...]:
Run a command remotely and return the response

Note: This is not optimized for large output or long running commands. If
Expand All @@ -84,11 +85,15 @@ func (*runCmd) Usage() string {

The --stream flag can be used to stream back command output as the command
runs. It doesn't affect the timeout.

--user flag allows to specify a user for running command, equivalent of
sudo -u <user> <command> ...
`
}

func (p *runCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&p.streaming, "stream", DefaultStreaming, "If true, stream back stdout and stdin during the command instead of sending it all at the end.")
f.StringVar(&p.user, "user", "", "If specified, allows to run a command as a specified user. Equivalent of sudo -u <user> <command> ... .")
}

func (p *runCmd) printCommandOutput(state *util.ExecuteState, idx int, resp *pb.ExecResponse, err error) {
Expand Down Expand Up @@ -121,7 +126,7 @@ func (p *runCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface
}

c := pb.NewExecClientProxy(state.Conn)
req := &pb.ExecRequest{Command: f.Args()[0], Args: f.Args()[1:]}
req := &pb.ExecRequest{Command: f.Args()[0], Args: f.Args()[1:], User: p.user}

if p.streaming {
resp, err := c.StreamingRunOneMany(ctx, req)
Expand Down
58 changes: 34 additions & 24 deletions services/exec/exec.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions services/exec/exec.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ service Exec {
message ExecRequest {
string command = 1;
repeated string args = 2;
// User to execute command as, equivalent of `sudo -u <user> <command>`.
string user = 3;
}

// ExecResponse describes output of execution
Expand Down
81 changes: 37 additions & 44 deletions services/exec/exec_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading