Skip to content

Commit

Permalink
Add known-host support (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
moul committed Apr 27, 2016
1 parent 5fc511d commit 2cf0ed7
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 25 deletions.
11 changes: 4 additions & 7 deletions pkg/commands/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package commands
import (
"fmt"
"os"
"syscall"

"github.com/codegangsta/cli"

Expand Down Expand Up @@ -34,7 +33,7 @@ func cmdWrapper(c *cli.Context) {
args := append(options, target)
args = append(args, command...)
bin := "/usr/bin/ssh"
Logger.Debugf("Wrapper called with target=%v command=%v ssh-options=%v", target, command, options)
Logger.Debugf("Wrapper called with bin=%v target=%v command=%v ssh-options=%v", bin, target, command, options)

// check if config is up-to-date
conf, err := config.Open()
Expand All @@ -44,12 +43,10 @@ func cmdWrapper(c *cli.Context) {

if conf.NeedsARebuildForTarget(target) {
Logger.Debugf("The configuration file is outdated, rebuilding it before calling ssh")
//host := conf.GetHostSafe(target)
//fmt.Println(host)
//fmt.Println(host.name)
//conf.WriteSshConfigTo(os.Stdout)
conf.AddKnownHost(target)
conf.WriteSshConfigTo(os.Stdout)
}

// Execute SSH
syscall.Exec(bin, args, os.Environ())
//syscall.Exec(bin, args, os.Environ())
}
47 changes: 29 additions & 18 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,20 @@ const defaultSshConfigPath string = "~/.ssh/config"

// Config contains a list of Hosts sections and a Defaults section representing a configuration file
type Config struct {
Hosts map[string]Host `yaml:"hosts,omitempty,flow" json:"hosts"`
Templates map[string]Host `yaml:"templates,omitempty,flow" json:"templates"`
Defaults Host `yaml:"defaults,omitempty,flow" json:"defaults,omitempty"`
Includes []string `yaml:"includes,omitempty,flow" json:"includes,omitempty"`
Hosts map[string]*Host `yaml:"hosts,omitempty,flow" json:"hosts"`
Templates map[string]*Host `yaml:"templates,omitempty,flow" json:"templates"`
Defaults Host `yaml:"defaults,omitempty,flow" json:"defaults,omitempty"`
Includes []string `yaml:"includes,omitempty,flow" json:"includes,omitempty"`

includedFiles map[string]bool
sshConfigPath string
}

func (c *Config) AddKnownHost(target string) {
host := c.GetHostSafe(target)
c.Hosts[host.pattern].AddKnownHost(target)
}

// IncludedFiles returns the list of the included files
func (c *Config) IncludedFiles() []string {
includedFiles := []string{}
Expand Down Expand Up @@ -113,7 +118,7 @@ func computeHost(host *Host, config *Config, name string, fullCompute bool) (*Ho
func (c *Config) getHostByName(name string, safe bool, compute bool, allowTemplate bool) (*Host, error) {
if host, ok := c.Hosts[name]; ok {
Logger.Debugf("getHostByName direct matching: %q", name)
return computeHost(&host, c, name, compute)
return computeHost(host, c, name, compute)
}

for origPattern, host := range c.Hosts {
Expand All @@ -126,7 +131,7 @@ func (c *Config) getHostByName(name string, safe bool, compute bool, allowTempla
}
if matched {
Logger.Debugf("getHostByName pattern matching: %q => %q", pattern, name)
return computeHost(&host, c, name, compute)
return computeHost(host, c, name, compute)
}
}
}
Expand All @@ -138,7 +143,7 @@ func (c *Config) getHostByName(name string, safe bool, compute bool, allowTempla
return nil, err
}
if matched {
return computeHost(&template, c, name, compute)
return computeHost(template, c, name, compute)
}
}
}
Expand Down Expand Up @@ -249,16 +254,22 @@ func (c *Config) LoadConfig(source io.Reader) error {
}

func (c *Config) applyMissingNames() {
for key, _ := range c.Hosts {
host := c.Hosts[key]
host.name = key
c.Hosts[key] = host
for key, host := range c.Hosts {
if host == nil {
c.Hosts[key] = &Host{}
host = c.Hosts[key]
}
host.pattern = key
host.name = key // should be removed
}
for key, _ := range c.Templates {
template := c.Templates[key]
template.name = key
for key, template := range c.Templates {
if template == nil {
c.Templates[key] = &Host{}
template = c.Templates[key]
}
template.pattern = key
template.name = key // should be removed
template.isTemplate = true
c.Templates[key] = template
}
c.Defaults.isDefault = true
}
Expand Down Expand Up @@ -378,7 +389,7 @@ func (c *Config) WriteSshConfigTo(w io.Writer) error {
fmt.Fprintln(w, "# host-based configuration")
for _, name := range c.sortedNames() {
host := c.Hosts[name]
computedHost, err := computeHost(&host, c, name, false)
computedHost, err := computeHost(host, c, name, false)
if err != nil {
return err
}
Expand All @@ -396,8 +407,8 @@ func (c *Config) WriteSshConfigTo(w io.Writer) error {
// New returns an instantiated Config object
func New() *Config {
var config Config
config.Hosts = make(map[string]Host)
config.Templates = make(map[string]Host)
config.Hosts = make(map[string]*Host)
config.Templates = make(map[string]*Host)
config.includedFiles = make(map[string]bool)
config.sshConfigPath = defaultSshConfigPath
return &config
Expand Down
9 changes: 9 additions & 0 deletions pkg/config/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ type Host struct {
Aliases []string `yaml:"aliases,omitempty,flow" json:"Aliases,omitempty"`

// private assh fields
knownHosts []string `yaml:"-" json:"-"`
pattern string `yaml:"-" json:"-"`
name string `yaml:"-" json:"-"`
inputName string `yaml:"-" json:"-"`
isDefault bool `yaml:"-" json:"-"`
Expand Down Expand Up @@ -644,10 +646,17 @@ func (h *Host) ApplyDefaults(defaults *Host) {
}
}

func (h *Host) AddKnownHost(target string) {
h.knownHosts = append(h.knownHosts, target)
}

func (h *Host) WriteSshConfigTo(w io.Writer) error {
aliases := append([]string{h.Name()}, h.Aliases...)
aliases = append(aliases, h.knownHosts...)
aliasIdx := 0
for _, alias := range aliases {
// FIXME: skip complex patterns

if aliasIdx > 0 {
fmt.Fprint(w, "\n")
}
Expand Down

0 comments on commit 2cf0ed7

Please sign in to comment.