diff options
Diffstat (limited to 'lib/ssh')
| -rw-r--r-- | lib/ssh/client_test.go | 2 | ||||
| -rw-r--r-- | lib/ssh/config/config.go | 47 | ||||
| -rw-r--r-- | lib/ssh/config/config_test.go | 13 | ||||
| -rw-r--r-- | lib/ssh/config/parser.go | 15 | ||||
| -rw-r--r-- | lib/ssh/config/parser_test.go | 2 | ||||
| -rw-r--r-- | lib/ssh/config/section.go | 35 | ||||
| -rw-r--r-- | lib/ssh/config/section_match.go | 5 | ||||
| -rw-r--r-- | lib/ssh/config/section_match_test.go | 16 | ||||
| -rw-r--r-- | lib/ssh/config/section_test.go | 9 |
9 files changed, 88 insertions, 56 deletions
diff --git a/lib/ssh/client_test.go b/lib/ssh/client_test.go index 062a32cc..feead9cc 100644 --- a/lib/ssh/client_test.go +++ b/lib/ssh/client_test.go @@ -20,7 +20,7 @@ func TestNewClient_KeyError_notExist(t *testing.T) { t.Skip(`Require active SSH server`) var ( - section = config.NewSection(`localhost`) + section = config.NewSection(nil, `localhost`) wd string err error diff --git a/lib/ssh/config/config.go b/lib/ssh/config/config.go index 21116d44..1c156da5 100644 --- a/lib/ssh/config/config.go +++ b/lib/ssh/config/config.go @@ -30,12 +30,31 @@ var ( type Config struct { envs map[string]string + // workDir store the current working directory. workDir string + homeDir string sections []*Section } +// newConfig create new SSH Config instance from file. +func newConfig(file string) (cfg *Config, err error) { + cfg = &Config{} + + cfg.workDir, err = os.Getwd() + if err != nil { + return nil, err + } + + cfg.homeDir, err = os.UserHomeDir() + if err != nil { + return nil, err + } + + return cfg, nil +} + // Load SSH configuration from file. func Load(file string) (cfg *Config, err error) { if len(file) == 0 { @@ -47,26 +66,32 @@ func Load(file string) (cfg *Config, err error) { section *Section ) - cfg = &Config{ - sections: make([]*Section, 0), + cfg, err = newConfig(file) + if err != nil { + return nil, fmt.Errorf("%s %s: %w", logp, file, err) } cfg.loadEnvironments() - p, err := newParser() + var p *parser + + p, err = newParser(cfg) if err != nil { return nil, fmt.Errorf("%s %s: %w", logp, file, err) } - cfg.workDir = p.workDir - cfg.homeDir = p.homeDir + var lines []string - lines, err := p.load("", file) + lines, err = p.load("", file) if err != nil { return nil, fmt.Errorf("%s %s: %w", logp, file, err) } - for x, line := range lines { + var ( + line string + x int + ) + for x, line = range lines { if line[0] == '#' { continue } @@ -81,13 +106,13 @@ func Load(file string) (cfg *Config, err error) { cfg.sections = append(cfg.sections, section) section = nil } - section = newSectionHost(value) + section = newSectionHost(cfg, value) case keyMatch: if section != nil { cfg.sections = append(cfg.sections, section) section = nil } - section, err = newSectionMatch(value) + section, err = newSectionMatch(cfg, value) if err != nil { return nil, fmt.Errorf("%s %s line %d: %w", logp, file, x+1, err) } @@ -114,13 +139,13 @@ func Load(file string) (cfg *Config, err error) { // If no Host or Match found, it still return non-nil Section but with empty // fields. func (cfg *Config) Get(s string) (section *Section) { - section = NewSection(s) + section = NewSection(cfg, s) for _, hostMatch := range cfg.sections { if hostMatch.isMatch(s) { section.mergeField(hostMatch) } } - section.setDefaults(cfg.workDir, cfg.homeDir) + section.setDefaults() if s != `` && section.Field[KeyHostname] == `` { section.Set(KeyHostname, s) diff --git a/lib/ssh/config/config_test.go b/lib/ssh/config/config_test.go index f31e5050..bf9aed9b 100644 --- a/lib/ssh/config/config_test.go +++ b/lib/ssh/config/config_test.go @@ -14,19 +14,26 @@ import ( ) var ( - testDefaultSection = NewSection(``) + dummyConfig *Config + testDefaultSection *Section testParser *parser ) func TestMain(m *testing.M) { var err error - testParser, err = newParser() + dummyConfig, err = newConfig(``) if err != nil { log.Fatal(err) } - testDefaultSection.setDefaults(testParser.workDir, testParser.homeDir) + testParser, err = newParser(dummyConfig) + if err != nil { + log.Fatal(err) + } + + testDefaultSection = NewSection(dummyConfig, ``) + testDefaultSection.setDefaults() os.Exit(m.Run()) } diff --git a/lib/ssh/config/parser.go b/lib/ssh/config/parser.go index 260f0b46..3ffef0a7 100644 --- a/lib/ssh/config/parser.go +++ b/lib/ssh/config/parser.go @@ -21,18 +21,11 @@ type parser struct { homeDir string } -func newParser() (p *parser, err error) { +func newParser(cfg *Config) (p *parser, err error) { p = &parser{ - files: make(map[string]struct{}), - } - - p.workDir, err = os.Getwd() - if err != nil { - return nil, err - } - p.homeDir, err = os.UserHomeDir() - if err != nil { - return nil, err + files: make(map[string]struct{}), + workDir: cfg.workDir, + homeDir: cfg.homeDir, } return p, nil diff --git a/lib/ssh/config/parser_test.go b/lib/ssh/config/parser_test.go index dea0db82..21bef8cd 100644 --- a/lib/ssh/config/parser_test.go +++ b/lib/ssh/config/parser_test.go @@ -134,7 +134,7 @@ func TestConfigParser_load(t *testing.T) { }} for _, c := range cases { - p, err := newParser() + p, err := newParser(dummyConfig) if err != nil { t.Fatal(err) } diff --git a/lib/ssh/config/section.go b/lib/ssh/config/section.go index dc0b9654..6b359bf5 100644 --- a/lib/ssh/config/section.go +++ b/lib/ssh/config/section.go @@ -232,27 +232,39 @@ type Section struct { } // NewSection create an empty Host or Match section. -func NewSection(name string) *Section { +// +// The Config parameter is optional, if not set the section will assume that +// any path is relative to current working directory or using absolute path. +func NewSection(cfg *Config, name string) (section *Section) { name = strings.TrimSpace(name) if len(name) == 0 { name = `*` } - return &Section{ + section = &Section{ Field: map[string]string{}, env: map[string]string{}, name: name, } -} -func newSectionHost(rawPattern string) (host *Section) { - patterns := strings.Fields(rawPattern) + if cfg != nil { + section.homeDir = cfg.homeDir + section.WorkingDir = cfg.workDir + } + + return section +} - host = NewSection(rawPattern) - host.patterns = make([]*pattern, 0, len(patterns)) +func newSectionHost(cfg *Config, rawPattern string) (host *Section) { + host = NewSection(cfg, rawPattern) - for _, pattern := range patterns { - pat := newPattern(pattern) + var ( + patterns = strings.Fields(rawPattern) + s string + pat *pattern + ) + for _, s = range patterns { + pat = newPattern(s) host.patterns = append(host.patterns, pat) } return host @@ -465,10 +477,7 @@ func (section *Section) isMatch(s string) bool { } // setDefaults set and expand all of the fields values if its not set. -func (section *Section) setDefaults(workDir, homeDir string) { - section.homeDir = homeDir - section.WorkingDir = workDir - +func (section *Section) setDefaults() { if len(section.IdentityFile) == 0 { section.IdentityFile = defaultIdentityFile() } diff --git a/lib/ssh/config/section_match.go b/lib/ssh/config/section_match.go index 7c28188d..9626e20c 100644 --- a/lib/ssh/config/section_match.go +++ b/lib/ssh/config/section_match.go @@ -22,14 +22,13 @@ var ( // Other criteria may be combined arbitrarily. // All criteria but "all", "canonical", and "final" require an argument. // Criteria may be negated by prepending an exclamation mark (`!'). -func newSectionMatch(rawPattern string) (match *Section, err error) { +func newSectionMatch(cfg *Config, rawPattern string) (match *Section, err error) { var ( prevCriteria *matchCriteria criteria *matchCriteria ) - match = NewSection(rawPattern) - match.criteria = make([]*matchCriteria, 0) + match = NewSection(cfg, rawPattern) match.useCriteria = true args := parseArgs(rawPattern, ' ') diff --git a/lib/ssh/config/section_match_test.go b/lib/ssh/config/section_match_test.go index d2742698..b1df06d9 100644 --- a/lib/ssh/config/section_match_test.go +++ b/lib/ssh/config/section_match_test.go @@ -21,7 +21,7 @@ func TestNewSectionMatch(t *testing.T) { }} for _, c := range cases { - got, err := newSectionMatch(c.raw) + got, err := newSectionMatch(dummyConfig, c.raw) if err != nil { if c.expError != err.Error() { t.Fatalf("parseCriteriaWithArg: expecting error %s, got %s", @@ -29,7 +29,7 @@ func TestNewSectionMatch(t *testing.T) { } continue } - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() test.Assert(t, c.raw, *c.exp, *got) } @@ -84,7 +84,7 @@ func TestParseCriteriaAll(t *testing.T) { }} for _, c := range cases { - got, err := newSectionMatch(c.raw) + got, err := newSectionMatch(dummyConfig, c.raw) if err != nil { if c.expError != err.Error() { t.Fatalf("parseCriteriaWithArg: expecting error %s, got %s", @@ -92,7 +92,7 @@ func TestParseCriteriaAll(t *testing.T) { } continue } - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, c.raw, *exp, *got) @@ -129,7 +129,7 @@ func TestNewSectionMatch_ParseCriteriaExec(t *testing.T) { }} for _, c := range cases { - got, err := newSectionMatch(c.raw) + got, err := newSectionMatch(dummyConfig, c.raw) if err != nil { if c.expError != err.Error() { t.Fatalf("parseCriteriaWithArg: expecting error %s, got %s", @@ -137,7 +137,7 @@ func TestNewSectionMatch_ParseCriteriaExec(t *testing.T) { } continue } - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, c.raw, *exp, *got) @@ -198,7 +198,7 @@ func TestParseCriteriaWithArg(t *testing.T) { }} for _, c := range cases { - got, err := newSectionMatch(c.raw) + got, err := newSectionMatch(dummyConfig, c.raw) if err != nil { if c.expError != err.Error() { t.Fatalf("parseCriteriaWithArg: expecting error %s, got %s", @@ -206,7 +206,7 @@ func TestParseCriteriaWithArg(t *testing.T) { } continue } - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, c.raw, *exp, *got) diff --git a/lib/ssh/config/section_test.go b/lib/ssh/config/section_test.go index 760d93d6..e89cc7b5 100644 --- a/lib/ssh/config/section_test.go +++ b/lib/ssh/config/section_test.go @@ -17,7 +17,6 @@ func TestNewSectionHost(t *testing.T) { }{{ rawPattern: "", exp: func(exp Section) *Section { - exp.patterns = make([]*pattern, 0) return &exp }, }, { @@ -53,8 +52,8 @@ func TestNewSectionHost(t *testing.T) { }} for _, c := range cases { - got := newSectionHost(c.rawPattern) - got.setDefaults(testParser.workDir, testParser.homeDir) + got := newSectionHost(dummyConfig, c.rawPattern) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, c.rawPattern, *exp, *got) @@ -81,7 +80,7 @@ func TestSectionSetDefaults(t *testing.T) { }} for _, c := range cases { got := c.section(*testDefaultSection) - got.setDefaults(testParser.workDir, testParser.homeDir) + got.setDefaults() exp := c.exp(*testDefaultSection) test.Assert(t, `setDefaults`, exp.IdentityFile, got.IdentityFile) @@ -167,7 +166,7 @@ func TestSection_UserKnownHostsFile(t *testing.T) { }} var ( - section = NewSection(`test`) + section = NewSection(dummyConfig, `test`) c testCase err error |
