mirror of
https://github.com/wavetermdev/ssh_config.git
synced 2026-08-05 13:43:40 -07:00
Add reload config (#2)
* add function that can clear cached config files Once the first call to `Get()`, `GetStrict()`, `GetAll()`, or`GetAllStrict()` has been made, the contents of the config files will be cached for all future calls to any of those functions. This can be frustrating if the user wants to capture changes to the config file that were made externally. This change adds the `ClearCachedConfigs()` function to provide control over that. * change ClearCachedConfigs to ReloadConfigs Clearing cached data is somewhat vague and could be more confusing to users who are not familiar with this library. But Reloading the config data is very straightforward. For this reason, the ability to clear the cache has been replaced with the ability to reload. The reload simply clears the cache and then loads the contents again. Additionally, this contains a bug fix that ensure the loadConfigs pointer is set to a non-null value before it is used. * add tests for reloading ssh config files This adds 2 tests. The first checks that ssh config data is cached and does not update if the file changes afterward. The second checks that the `ReloadConfigs()` function will discard the cached data and load the current config file contents.
This commit is contained in:
@@ -42,6 +42,16 @@ Some SSH arguments have default values - for example, the default value for
|
||||
given Host/keyword pair exists in the config, we'll return a default for the
|
||||
keyword if one exists.
|
||||
|
||||
### Reloading SSH config files
|
||||
Once the first call to `Get()`, `GetStrict()`, `GetAll()`, or `GetAllStrict()`
|
||||
has been made, the contents of the config files will be cached for all future
|
||||
calls to any of those functions. The `ReloadConfigs()` function will reset
|
||||
this cache and replace it with the current config file contents.
|
||||
|
||||
```go
|
||||
ssh_config.ReloadConfigs()
|
||||
```
|
||||
|
||||
### Manipulating SSH config files
|
||||
|
||||
Here's how you can manipulate an SSH config file, and then write it back to
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// the host name to match on ("example.com"), and the second argument is the key
|
||||
// you want to retrieve ("Port"). The keywords are case insensitive.
|
||||
//
|
||||
// port := ssh_config.Get("myhost", "Port")
|
||||
// port := ssh_config.Get("myhost", "Port")
|
||||
//
|
||||
// You can also manipulate an SSH config file and then print it or write it back
|
||||
// to disk.
|
||||
@@ -59,7 +59,7 @@ type UserSettings struct {
|
||||
systemConfigFinder configFinder
|
||||
userConfig *Config
|
||||
userConfigFinder configFinder
|
||||
loadConfigs sync.Once
|
||||
loadConfigs *sync.Once
|
||||
onceErr error
|
||||
}
|
||||
|
||||
@@ -167,6 +167,14 @@ func GetAllStrict(alias, key string) ([]string, error) {
|
||||
return DefaultUserSettings.GetAllStrict(alias, key)
|
||||
}
|
||||
|
||||
// ReloadConfigs clears the cached config data and freshly loads the config
|
||||
// files again.
|
||||
//
|
||||
// ReloadConfigs is a wrapper around DefaultUserSettings.ReloadConfigs.
|
||||
func ReloadConfigs() {
|
||||
DefaultUserSettings.ReloadConfigs()
|
||||
}
|
||||
|
||||
// Get finds the first value for key within a declaration that matches the
|
||||
// alias. Get returns the empty string if no value was found, or if IgnoreErrors
|
||||
// is false and we could not parse the configuration file. Use GetStrict to
|
||||
@@ -272,6 +280,9 @@ func (u *UserSettings) ConfigFinder(f func() string) {
|
||||
}
|
||||
|
||||
func (u *UserSettings) doLoadConfigs() {
|
||||
if u.loadConfigs == nil {
|
||||
u.loadConfigs = new(sync.Once)
|
||||
}
|
||||
u.loadConfigs.Do(func() {
|
||||
var filename string
|
||||
var err error
|
||||
@@ -310,6 +321,13 @@ func (u *UserSettings) doLoadConfigs() {
|
||||
})
|
||||
}
|
||||
|
||||
// ReloadConfigs clears the cached config data and freshly loads the config
|
||||
// files again.
|
||||
func (u *UserSettings) ReloadConfigs() {
|
||||
u.loadConfigs = new(sync.Once)
|
||||
u.doLoadConfigs()
|
||||
}
|
||||
|
||||
func parseFile(filename string) (*Config, error) {
|
||||
return parseWithDepth(filename, 0)
|
||||
}
|
||||
|
||||
@@ -259,6 +259,72 @@ func TestGetEqsign(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var modified1 = []byte(`
|
||||
Host wap
|
||||
User modified1
|
||||
KexAlgorithms diffie-hellman-group1-sha1
|
||||
`)
|
||||
|
||||
var modified2 = []byte(`
|
||||
Host wap
|
||||
User modified2
|
||||
KexAlgorithms diffie-hellman-group1-sha1
|
||||
`)
|
||||
|
||||
func TestCachedConfig(t *testing.T) {
|
||||
us := &UserSettings{
|
||||
userConfigFinder: testConfigFinder("testdata/modified"),
|
||||
}
|
||||
|
||||
err1 := os.WriteFile("testdata/modified", modified1, 0644)
|
||||
if err1 != nil {
|
||||
t.Errorf("error writing to file: %v", err1)
|
||||
}
|
||||
|
||||
val1 := us.Get("wap", "User")
|
||||
if val1 != "modified1" {
|
||||
t.Errorf("expected to find User modified1, got %q", val1)
|
||||
}
|
||||
|
||||
err2 := os.WriteFile("testdata/modified", modified2, 0644)
|
||||
if err1 != nil {
|
||||
t.Errorf("error writing to file: %v", err2)
|
||||
}
|
||||
|
||||
val2 := us.Get("wap", "User")
|
||||
if val2 != "modified1" {
|
||||
t.Errorf("expected to find User modified1, got %q", val2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReloadConfigs(t *testing.T) {
|
||||
us := &UserSettings{
|
||||
userConfigFinder: testConfigFinder("testdata/modified"),
|
||||
}
|
||||
|
||||
err1 := os.WriteFile("testdata/modified", modified1, 0644)
|
||||
if err1 != nil {
|
||||
t.Errorf("error writing to file: %v", err1)
|
||||
}
|
||||
|
||||
val1 := us.Get("wap", "User")
|
||||
if val1 != "modified1" {
|
||||
t.Errorf("expected to find User modified1, got %q", val1)
|
||||
}
|
||||
|
||||
err2 := os.WriteFile("testdata/modified", modified2, 0644)
|
||||
if err1 != nil {
|
||||
t.Errorf("error writing to file: %v", err2)
|
||||
}
|
||||
|
||||
us.ReloadConfigs()
|
||||
|
||||
val2 := us.Get("wap", "User")
|
||||
if val2 != "modified2" {
|
||||
t.Errorf("expected to find User modified2, got %q", val2)
|
||||
}
|
||||
}
|
||||
|
||||
var includeFile = []byte(`
|
||||
# This host should not exist, so we can use it for test purposes / it won't
|
||||
# interfere with any other configurations.
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
|
||||
Host wap
|
||||
User modified2
|
||||
KexAlgorithms diffie-hellman-group1-sha1
|
||||
Reference in New Issue
Block a user