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

Discover keypaths from ssh_config, update agent key selection logic #73

Merged
merged 7 commits into from
Nov 10, 2022
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
9 changes: 9 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- name: install test dependencies
run: |
sudo apt-get update
sudo apt-get install expect

- uses: actions/checkout@v2

- name: Set up Go
Expand All @@ -32,3 +37,7 @@ jobs:

- name: Test
run: go test -v ./...

- name: Run integration tests
run: make -C test test

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
test/rigtest
test/footloose.yaml
test/Library
test/.ssh
163 changes: 163 additions & 0 deletions cmd/rigtest/rigtest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package main

import (
"flag"
"fmt"
goos "os"
"strconv"
"strings"
"time"

"github.com/k0sproject/rig"
"github.com/k0sproject/rig/exec"
"github.com/k0sproject/rig/os"
"github.com/k0sproject/rig/os/registry"
_ "github.com/k0sproject/rig/os/support"
"github.com/kevinburke/ssh_config"
)

type configurer interface {
WriteFile(os.Host, string, string, string) error
LineIntoFile(os.Host, string, string, string) error
ReadFile(os.Host, string) (string, error)
FileExist(os.Host, string) bool
DeleteFile(os.Host, string) error
Stat(os.Host, string, ...exec.Option) (*os.FileInfo, error)
}

// Host is a host that utilizes rig for connections
type Host struct {
rig.Connection

Configurer configurer
}

// LoadOS is a function that assigns a OS support package to the host and
// typecasts it to a suitable interface
func (h *Host) LoadOS() error {
bf, err := registry.GetOSModuleBuilder(*h.OSVersion)
if err != nil {
return err
}

h.Configurer = bf().(configurer)

return nil
}

func main() {
dh := flag.String("host", "127.0.0.1", "target host [+ :port], can give multiple comma separated")
usr := flag.String("user", "root", "user name")
kp := flag.String("keypath", "", "keypath")
pc := flag.Bool("askpass", false, "ask passwords")

fn := fmt.Sprintf("test_%s.txt", time.Now().Format("20060102150405"))

flag.Parse()

if *dh == "" {
println("see -help")
goos.Exit(1)
}

if configPath := goos.Getenv("SSH_CONFIG"); configPath != "" {
f, err := goos.Open(configPath)
if err != nil {
panic(err)
}
cfg, err := ssh_config.Decode(f)
if err != nil {
panic(err)
}
rig.SSHConfigGetAll = func(dst, key string) []string {
res, err := cfg.GetAll(dst, key)
if err != nil {
return nil
}
return res
}
}

var passfunc func() (string, error)
if *pc {
passfunc = func() (string, error) {
var pass string
fmt.Print("Password: ")
fmt.Scanln(&pass)
return pass, nil
}
}

var hosts []Host

for _, address := range strings.Split(*dh, ",") {
port := 22
if addr, portstr, ok := strings.Cut(address, ":"); ok {
address = addr
p, err := strconv.Atoi(portstr)
if err != nil {
panic("invalid port " + portstr)
}
port = p
}

h := Host{
Connection: rig.Connection{
SSH: &rig.SSH{
Address: address,
Port: port,
User: *usr,
KeyPath: kp,
PasswordCallback: passfunc,
},
},
}
hosts = append(hosts, h)
}

for _, h := range hosts {
if err := h.Connect(); err != nil {
panic(err)
}

if err := h.LoadOS(); err != nil {
panic(err)
}

if err := h.Configurer.WriteFile(h, fn, "test\ntest2\ntest3", "0644"); err != nil {
panic(err)
}

if err := h.Configurer.LineIntoFile(h, fn, "test2", "test4"); err != nil {
panic(err)
}

if !h.Configurer.FileExist(h, fn) {
panic("file does not exist")
}

row, err := h.Configurer.ReadFile(h, fn)
if err != nil {
panic(err)
}
if row != "test\ntest4\ntest3" {
panic("file content is not correct")
}

stat, err := h.Configurer.Stat(h, fn)
if err != nil {
panic(err)
}
if !strings.HasSuffix(stat.FName, fn) {
panic("file stat is not correct")
}

if err := h.Configurer.DeleteFile(h, fn); err != nil {
panic(err)
}

if h.Configurer.FileExist(h, fn) {
panic("file still exists")
}
}
}
18 changes: 5 additions & 13 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,8 @@ func (c *Connection) SetDefaults() {
if c.client == nil {
c.client = defaultClient()
}
_ = defaults.Set(c.client)
}

_ = defaults.Set(c.client)
}

// Protocol returns the connection protocol name
Expand Down Expand Up @@ -133,16 +132,11 @@ func (c *Connection) IsConnected() bool {
// String returns a printable representation of the connection, which will look
// like: `[ssh] address:port`
func (c Connection) String() string {
client := c.client
if client == nil {
client = c.configuredClient()
_ = defaults.Set(c)
}
if client == nil {
client = defaultClient()
if c.client == nil {
return fmt.Sprintf("[%s] %s", c.Protocol(), c.Address())
}

return client.String()
return c.client.String()
}

// IsWindows returns true on windows hosts
Expand Down Expand Up @@ -311,9 +305,7 @@ func (c *Connection) configuredClient() client {
}

func defaultClient() client {
c := &Localhost{Enabled: true}
_ = defaults.Set(c)
return c
return &Localhost{Enabled: true}
}

// GroupParams separates exec.Options from other sprintf templating args
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/davidmz/go-pageant v1.0.2
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/kevinburke/ssh_config v1.2.0
github.com/masterzen/winrm v0.0.0-20220917170901-b07f6cb0598d
github.com/mitchellh/go-homedir v1.1.0
github.com/stretchr/testify v1.8.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand Down
11 changes: 11 additions & 0 deletions log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "fmt"

// Logger interface should be implemented by the logging library you wish to use
type Logger interface {
Tracef(string, ...interface{})
Debugf(string, ...interface{})
Infof(string, ...interface{})
Errorf(string, ...interface{})
Expand All @@ -12,6 +13,11 @@ type Logger interface {
// Log can be assigned a proper logger, such as logrus configured to your liking.
var Log Logger

// Tracef logs a trace level log message
func Tracef(t string, args ...interface{}) {
Log.Debugf(t, args...)
}

// Debugf logs a debug level log message
func Debugf(t string, args ...interface{}) {
Log.Debugf(t, args...)
Expand All @@ -32,6 +38,11 @@ type StdLog struct {
Logger
}

// Debugf prints a debug level log message
func (l *StdLog) Tracef(t string, args ...interface{}) {
fmt.Println("TRACE", fmt.Sprintf(t, args...))
}

// Debugf prints a debug level log message
func (l *StdLog) Debugf(t string, args ...interface{}) {
fmt.Println("DEBUG", fmt.Sprintf(t, args...))
Expand Down
Loading