Skip to content

Commit

Permalink
add sshuser flag (#335)
Browse files Browse the repository at this point in the history
* add sshuser flag

* add options fields

* Per feedback

* update Doc

* update connect information output
  • Loading branch information
tedteng authored Sep 11, 2023
1 parent 21c888c commit 311684a
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/help/gardenctl_ssh.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ gardenctl ssh --keep-bastion --bastion-name cli-xxxxxxxx --public-key-file /path
--seed string target the given seed cluster
--shoot string target the given shoot cluster
--skip-availability-check Skip checking for SSH bastion host availability.
--user string user is the name of the Shoot cluster node ssh login username. (default "gardener")
--wait-timeout duration Maximum duration to wait for the bastion to become available. (default 10m0s)
```

Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/ssh/arguments.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func sshCommandArguments(
bastionUserKnownHostsFiles []string,
nodeHostname string,
nodePrivateKeyFiles []PrivateKeyFile,
user string,
) arguments {
bastionUserKnownHostsFilesArg := userKnownHostsFilesArgument(bastionUserKnownHostsFiles)

Expand All @@ -87,7 +88,7 @@ func sshCommandArguments(

args = append(args, argument{value: fmt.Sprintf("-oProxyCommand=%s", proxyCmdArgs.String())})

args = append(args, argument{value: fmt.Sprintf("%s@%s", SSHNodeUsername, nodeHostname)})
args = append(args, argument{value: fmt.Sprintf("%s@%s", user, nodeHostname)})

return arguments{list: args}
}
Expand Down
15 changes: 15 additions & 0 deletions pkg/cmd/ssh/arguments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type testCase struct {
nodeHostname string
nodePrivateKeyFiles []ssh.PrivateKeyFile
expectedArgs []string
user string
}

func newTestCase() testCase {
Expand All @@ -32,6 +33,7 @@ func newTestCase() testCase {
sshPrivateKeyFile: "path/to/private/key",
nodeHostname: "node.example.com",
nodePrivateKeyFiles: []ssh.PrivateKeyFile{"path/to/node/private/key"},
user: "gardener",
}
}

Expand All @@ -46,6 +48,7 @@ var _ = Describe("Arguments", func() {
tc.bastionUserKnownHostsFiles,
tc.nodeHostname,
tc.nodePrivateKeyFiles,
tc.user,
)
Expect(args.String()).To(Equal(strings.Join(tc.expectedArgs, " ")))
},
Expand All @@ -60,6 +63,18 @@ var _ = Describe("Arguments", func() {
}
return tc
}()),
Entry("basic case with other ssh username", func() testCase {
tc := newTestCase()
tc.user = "aaa"
tc.expectedArgs = []string{
"-oStrictHostKeyChecking=no",
"-oIdentitiesOnly=yes",
"'-ipath/to/node/private/key'",
`'-oProxyCommand=ssh -W%h:%p -oStrictHostKeyChecking=no -oIdentitiesOnly=yes '"'"'-ipath/to/private/key'"'"' '"'"'gardener@bastion.example.com'"'"' '"'"'-p22'"'"''`,
"'aaa@node.example.com'",
}
return tc
}()),
Entry("no bastion port", func() testCase {
tc := newTestCase()
tc.bastionPort = ""
Expand Down
6 changes: 6 additions & 0 deletions pkg/cmd/ssh/connect_information.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ type ConnectInformation struct {

// Nodes is a list of Node objects containing information about the worker nodes.
Nodes []Node `json:"nodes"`

// User is the name of the Shoot cluster node ssh login username
User string
}

var _ fmt.Stringer = &ConnectInformation{}
Expand Down Expand Up @@ -84,6 +87,7 @@ func NewConnectInformation(
sshPrivateKeyFile PrivateKeyFile,
nodePrivateKeyFiles []PrivateKeyFile,
nodes []corev1.Node,
user string,
) (*ConnectInformation, error) {
var nodeList []Node

Expand Down Expand Up @@ -140,6 +144,7 @@ func NewConnectInformation(
NodeHostname: nodeHostname,
NodePrivateKeyFiles: nodePrivateKeyFiles,
Nodes: nodeList,
User: user,
}, nil
}

Expand Down Expand Up @@ -200,6 +205,7 @@ func (p *ConnectInformation) String() string {
p.Bastion.UserKnownHostsFiles,
nodeHostname,
p.NodePrivateKeyFiles,
p.User,
)

fmt.Fprintf(&buf, "> Connect to shoot nodes by using the bastion as a proxy/jump host.\n")
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/ssh/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func SSHCommandArguments(
bastionUserKnownHostsFiles []string,
nodeHostname string,
nodePrivateKeyFiles []PrivateKeyFile,
user string,
) TestArguments {
return TestArguments{
sshCommandArguments(
Expand All @@ -69,6 +70,7 @@ func SSHCommandArguments(
bastionUserKnownHostsFiles,
nodeHostname,
nodePrivateKeyFiles,
user,
),
}
}
18 changes: 15 additions & 3 deletions pkg/cmd/ssh/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ import (
const (
// SSHBastionUsername is the system username on the bastion host.
SSHBastionUsername = "gardener"
// SSHNodeUsername is the system username on any of the shoot cluster nodes.
SSHNodeUsername = "gardener"
// DefaultUsername is the default Shoot cluster node ssh login username.
DefaultUsername = "gardener"
// SSHPort is the TCP port on a bastion instance that allows incoming SSH.
SSHPort = 22
)
Expand Down Expand Up @@ -194,6 +194,9 @@ type SSHOptions struct {
// bastion host, but leave it up to the user to SSH themselves.
NodeName string

// User is the name of the Shoot cluster node ssh login username
User string

// SSHPublicKeyFile is the full path to the file containing the user's
// public SSH key. If not given, gardenctl will create a new temporary keypair.
SSHPublicKeyFile PublicKeyFile
Expand Down Expand Up @@ -242,6 +245,7 @@ func NewSSHOptions(ioStreams util.IOStreams) *SSHOptions {
SkipAvailabilityCheck: false,
NoKeepalive: false,
BastionPort: strconv.Itoa(SSHPort),
User: DefaultUsername,
}
}

Expand All @@ -258,7 +262,7 @@ func (o *SSHOptions) AddFlags(flagSet *pflag.FlagSet) {
flagSet.StringVar(&o.BastionPort, "bastion-port", o.BastionPort, "SSH port of the bastion used for the SSH client command. Defaults to port 22")
flagSet.StringSliceVar(&o.BastionUserKnownHostsFiles, "bastion-user-known-hosts-file", o.BastionUserKnownHostsFiles, "Path to a custom known hosts file for the SSH connection to the bastion. This file is used to verify the public keys of remote hosts when establishing a secure connection.")
flagSet.BoolVarP(&o.ConfirmAccessRestriction, "confirm-access-restriction", "y", o.ConfirmAccessRestriction, "Bypasses the need for confirmation of any access restrictions. Set this flag only if you are fully aware of the access restrictions.")

flagSet.StringVar(&o.User, "user", o.User, "user is the name of the Shoot cluster node ssh login username.")
o.Options.AddFlags(flagSet)
}

Expand Down Expand Up @@ -368,6 +372,10 @@ func (o *SSHOptions) Validate() error {
}
}

if o.User == "" {
return errors.New("user must not be empty")
}

content, err := os.ReadFile(o.SSHPublicKeyFile.String())
if err != nil {
return fmt.Errorf("invalid SSH public key file: %w", err)
Expand Down Expand Up @@ -655,6 +663,7 @@ func (o *SSHOptions) Run(f util.Factory) error {
o.SSHPrivateKeyFile,
nodePrivateKeyFiles,
nodes,
o.User,
)
if err != nil {
return err
Expand Down Expand Up @@ -682,6 +691,7 @@ func (o *SSHOptions) Run(f util.Factory) error {
o.BastionUserKnownHostsFiles,
nodeHostname,
nodePrivateKeyFiles,
o.User,
)
}

Expand Down Expand Up @@ -946,6 +956,7 @@ func remoteShell(
bastionUserKnownHostsFiles []string,
nodeHostname string,
nodePrivateKeyFiles []PrivateKeyFile,
user string,
) error {
commandArgs := sshCommandArguments(
bastionHost,
Expand All @@ -954,6 +965,7 @@ func remoteShell(
bastionUserKnownHostsFiles,
nodeHostname,
nodePrivateKeyFiles,
user,
)

fmt.Fprintf(ioStreams.Out, "> You can open additional SSH sessions by running the following command in a separate terminal:\n\n")
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/ssh/ssh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ var _ = Describe("SSH Command", func() {
ssh.SSHBastionUsername,
bastionIP,
),
fmt.Sprintf("%s@%s", ssh.SSHNodeUsername, nodeHostname),
fmt.Sprintf("%s@%s", options.User, nodeHostname),
}))

return nil
Expand Down Expand Up @@ -407,7 +407,7 @@ var _ = Describe("SSH Command", func() {
ssh.SSHBastionUsername,
bastionIP,
),
fmt.Sprintf("%s@%s", ssh.SSHNodeUsername, nodeName),
fmt.Sprintf("%s@%s", options.User, nodeName),
}))

return nil
Expand Down

0 comments on commit 311684a

Please sign in to comment.