Skip to content

for enable/disable/forget, don't read the config, read etcd #46

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

Merged
merged 1 commit into from
May 23, 2025
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
14 changes: 10 additions & 4 deletions cmd/sshproxyctl/sshproxyctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -769,19 +769,25 @@ Should be used like this:
func getHostPortFromCommandLine(allFlag bool, hostsNodeset string, portsNodeset string, configFile string) ([]string, error) {
_, nodesetDlclose, nodesetExpand := nodesets.InitExpander()
defer nodesetDlclose()
cli := mustInitEtcdClient(configFile)
defer cli.Close()

configDests, err := utils.LoadAllDestsFromConfig(configFile)
etcdFlatHosts, err := cli.GetAllHosts()
if err != nil {
return []string{}, fmt.Errorf("%s", err)
return []string{}, fmt.Errorf("ERROR: getting hosts from etcd: %v", err)
}
etcdHosts := make([]string, len(etcdFlatHosts))
for i, h := range etcdFlatHosts {
etcdHosts[i] = h.Hostname
}

if allFlag && portsNodeset == "" {
return configDests, nil
return etcdHosts, nil
}

var hosts []string
var ports []string
for _, configDest := range configDests {
for _, configDest := range etcdHosts {
host, port, err := utils.SplitHostPort(configDest)
if err != nil {
return []string{}, fmt.Errorf("%s", err)
Expand Down
30 changes: 15 additions & 15 deletions doc/sshproxyctl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,30 +42,30 @@ COMMANDS
*enable -all|-host HOST [-port PORT]*::
Enable a destination host in etcd if the host was previously disabled
by the 'disable' command (see below). If '-all' is specified instead
of '-host', all the hosts present in the configuration are enabled. If
no '-port' is specified, all the ports present in the configuration are
used. 'HOST' and 'PORT' can be nodesets. If libnodeset.so (from
https://github.com/fdiakh/nodeset-rs) is available, clustershell groups
can also be used.
of '-host', all the hosts present in etcd are enabled. If no '-port'
is specified, all the ports present in etcd are used. 'HOST' and
'PORT' can be nodesets. If libnodeset.so (from
https://github.com/fdiakh/nodeset-rs) is available, clustershell
groups can also be used.

*disable -all|-host HOST [-port PORT]*::
Disable a destination host in etcd. A disabled host will not be
proposed as a destination. The only way to enable it again is to send
the 'enable' command. It could be used for host maintenance. If
'-all' is specified instead of '-host', all the hosts present in the
configuration are enabled. If no '-port' is specified, all the ports
present in the configuration are used. 'HOST' and 'PORT' can be
nodesets. If libnodeset.so (from https://github.com/fdiakh/nodeset-rs)
is available, clustershell groups can also be used.
'-all' is specified instead of '-host', all the hosts present in etcd
are enabled. If no '-port' is specified, all the ports present in etcd
are used. 'HOST' and 'PORT' can be nodesets. If libnodeset.so (from
https://github.com/fdiakh/nodeset-rs) is available, clustershell
groups can also be used.

*forget host -all|-host HOST [-port PORT]*::
Forget a host in etcd. Remember that if this host is used, it will
appear back in the list. If '-all' is specified instead of '-host',
all the hosts present in the configuration are forgotten. If no '-port'
is specified, all the ports present in the configuration are used.
'HOST' and 'PORT' can be nodesets. If libnodeset.so (from
https://github.com/fdiakh/nodeset-rs) is available, clustershell groups
can also be used.
all the hosts present in etcd are forgotten. If no '-port' is
specified, all the ports present in etcd are used. 'HOST' and 'PORT'
can be nodesets. If libnodeset.so (from
https://github.com/fdiakh/nodeset-rs) is available, clustershell
groups can also be used.

*forget error_banner*::
Remove the error banner in etcd.
Expand Down
25 changes: 0 additions & 25 deletions pkg/utils/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,31 +335,6 @@ func replace(src string, replacer *patternReplacer) string {
return replacer.Regexp.ReplaceAllString(src, replacer.Text)
}

// LoadAllDestsFromConfig loads configuration file and returns all defined destinations.
func LoadAllDestsFromConfig(filename string) ([]string, error) {
yamlFile, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
var config Config
if err := yaml.Unmarshal(yamlFile, &config); err != nil {
return nil, err
}
for _, override := range config.Overrides {
if override.Dest != nil {
config.Dest = append(config.Dest, override.Dest...)
}
}
// expand destination nodesets
_, nodesetDlclose, nodesetExpand := nodesets.InitExpander()
defer nodesetDlclose()
dsts, err := nodesetExpand(strings.Join(config.Dest, ","))
if err != nil {
return nil, fmt.Errorf("invalid nodeset: %s", err)
}
return dsts, nil
}

// LoadConfig load configuration file and adapt it according to specified user/group/sshdHostPort.
func LoadConfig(filename, currentUsername, sid string, start time.Time, groups map[string]bool, sshdHostPort string) (*Config, error) {
if cachedConfig.ready {
Expand Down
51 changes: 0 additions & 51 deletions pkg/utils/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"fmt"
"reflect"
"regexp"
"slices"
"testing"
"time"
)
Expand Down Expand Up @@ -60,56 +59,6 @@ func BenchmarkReplace(b *testing.B) {
}
}

var loadAllDestsFromConfigTests = []struct {
filename string
want []string
err string
}{
{"nonexistingfile.yaml", []string{}, "open nonexistingfile.yaml: no such file or directory"},
{"../../test/configInvalid.yaml", []string{}, "yaml: found character that cannot start any token"},
{"../../test/configDestNodesetError.yaml", []string{}, "invalid nodeset: cannont convert ending range to integer a - rangeset parse error"},
{"../../test/configDefault.yaml", []string{"127.0.0.1"}, ""},
{"../../test/config.yaml", []string{
"192.168.0.1",
"192.168.0.2",
"192.168.0.3",
"192.168.0.4",
"192.168.0.5",
"192.168.0.6",
"192.168.0.7",
"192.168.0.8",
"192.168.0.9",
"host5:4222",
"server1:12345",
}, ""},
}

func TestLoadAllDestsFromConfig(t *testing.T) {
for _, tt := range loadAllDestsFromConfigTests {
config, err := LoadAllDestsFromConfig(tt.filename)
if err == nil && tt.err != "" {
t.Errorf("got no error, want %s", tt.err)
} else if err != nil && err.Error() != tt.err {
t.Errorf("ERROR: %s, want %s", err, tt.err)
} else if err == nil {
slices.Sort(config)
if !reflect.DeepEqual(config, tt.want) {
t.Errorf("want:\n%v\ngot:\n%v", tt.want, config)
}
}
}
}

func BenchmarkLoadAllDestsFromConfig(b *testing.B) {
for _, tt := range loadAllDestsFromConfigTests {
b.Run(tt.filename, func(b *testing.B) {
for i := 0; i < b.N; i++ {
LoadAllDestsFromConfig(tt.filename)
}
})
}
}

var loadConfigTests = []struct {
filename, username string
want []string
Expand Down