Skip to content

Commit 4bdd05e

Browse files
committed
add get_config function to sshproxyctl
1 parent aa42b7f commit 4bdd05e

File tree

5 files changed

+92
-24
lines changed

5 files changed

+92
-24
lines changed

cmd/sshproxy/sshproxy.go

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -298,28 +298,9 @@ func mainExitCode() int {
298298
syslogformat := fmt.Sprintf("%%{level} %s: %%{message}", sid)
299299
utils.MustSetupLogging("sshproxy", config.Log, logformat, syslogformat, config.Debug)
300300

301-
log.Debugf("groups = %v", groups)
302-
log.Debugf("config.debug = %v", config.Debug)
303-
log.Debugf("config.log = %s", config.Log)
304-
log.Debugf("config.check_interval = %s", config.CheckInterval.Duration())
305-
log.Debugf("config.error_banner = %s", config.ErrorBanner)
306-
log.Debugf("config.dump = %s", config.Dump)
307-
log.Debugf("config.dump_limit_size = %d", config.DumpLimitSize)
308-
log.Debugf("config.dump_limit_window = %s", config.DumpLimitWindow.Duration())
309-
log.Debugf("config.etcd_stats_interval = %s", config.EtcdStatsInterval.Duration())
310-
log.Debugf("config.log_stats_interval = %s", config.LogStatsInterval.Duration())
311-
log.Debugf("config.etcd = %+v", config.Etcd)
312-
log.Debugf("config.bg_command = %s", config.BgCommand)
313-
for k, v := range config.TranslateCommands {
314-
log.Debugf("config.TranslateCommands.%s = %+v", k, v)
315-
}
316-
log.Debugf("config.environment = %v", config.Environment)
317-
for k, v := range config.Routes {
318-
log.Debugf("config.routes.%s = %+v", k, v)
319-
}
320-
log.Debugf("config.max_connections_per_user = %d", config.MaxConnectionsPerUser)
321-
log.Debugf("config.ssh.exe = %s", config.SSH.Exe)
322-
log.Debugf("config.ssh.args = %v", config.SSH.Args)
301+
for _, configLine := range utils.PrintConfig(config, groups) {
302+
log.Debug(configLine)
303+
}
323304

324305
log.Infof("%s connected from %s to sshd listening on %s", username, sshInfos.Src(), sshInfos.Dst())
325306
defer log.Info("disconnected")

cmd/sshproxyctl/sshproxyctl.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ import (
1818
"log"
1919
"net"
2020
"os"
21+
"os/user"
2122
"sort"
2223
"strconv"
24+
"strings"
2325
"time"
2426

2527
"github.com/cea-hpc/sshproxy/pkg/utils"
@@ -443,6 +445,7 @@ The commands are:
443445
forget forget a host in etcd
444446
disable disable a host in etcd
445447
error_banner set the error banner in etcd
448+
get_config display the calculated configuration
446449
447450
The common options are:
448451
`, os.Args[0])
@@ -552,6 +555,24 @@ The options are:
552555
return fs
553556
}
554557

558+
func newGetConfigParser(userFlag *string, groupsFlag *string) *flag.FlagSet {
559+
fs := flag.NewFlagSet("get_config", flag.ExitOnError)
560+
fs.StringVar(userFlag, "user", "", "get the config for this specific user")
561+
fs.StringVar(groupsFlag, "groups", "", "get the config for these specific groups (comma separated)")
562+
fs.Usage = func() {
563+
fmt.Fprintf(flag.CommandLine.Output(), `Usage: %s get_config [-user USER] [-groups GROUPS]
564+
565+
Display the calculated configuration. If a user is given, its system groups (if
566+
any) are added to the given groups.
567+
568+
The options are:
569+
`, os.Args[0])
570+
fs.PrintDefaults()
571+
os.Exit(2)
572+
}
573+
return fs
574+
}
575+
555576
func getHostPortFromCommandLine(args []string) ([]string, []string, error) {
556577
hostsNodeset, portsNodeset := "", defaultHostPort
557578
switch len(args) {
@@ -645,6 +666,8 @@ func main() {
645666
var jsonFlag bool
646667
var allFlag bool
647668
var expire string
669+
var userString string
670+
var groupsString string
648671

649672
parsers := map[string]*flag.FlagSet{
650673
"help": newHelpParser(),
@@ -654,6 +677,7 @@ func main() {
654677
"forget": newForgetParser(),
655678
"disable": newDisableParser(),
656679
"error_banner": newErrorBannerParser(&expire),
680+
"get_config": newGetConfigParser(&userString, &groupsString),
657681
}
658682

659683
cmd := flag.Arg(0)
@@ -759,6 +783,33 @@ func main() {
759783
p.Usage()
760784
}
761785
setErrorBanner(errorBanner, t, *configFile)
786+
case "get_config":
787+
p := parsers[cmd]
788+
p.Parse(args)
789+
groupsMap := make(map[string]bool)
790+
userComment := ""
791+
// get system groups of given user, if it exists
792+
userObject, err := user.Lookup(userString)
793+
if err != nil {
794+
userComment = " (unknown on this system)"
795+
} else {
796+
groupsMap, _ = utils.GetGroupUser(userObject)
797+
}
798+
// add given groups to system groups
799+
for _, group := range strings.Split(groupsString, ",") {
800+
if group != "" {
801+
groupsMap[group] = true
802+
}
803+
}
804+
// get config for given user / groups
805+
config, err := utils.LoadConfig(*configFile, userString, "", time.Now(), groupsMap)
806+
if err != nil {
807+
log.Fatalf("reading configuration file %s: %v", *configFile, err)
808+
}
809+
fmt.Fprintf(os.Stdout, "user = %s%s\n", userString, userComment)
810+
for _, configLine := range utils.PrintConfig(config, groupsMap) {
811+
fmt.Fprintln(os.Stdout, configLine)
812+
}
762813
default:
763814
fmt.Fprintf(os.Stderr, "ERROR: unknown command: %s\n\n", cmd)
764815
usage()

doc/sshproxyctl.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ COMMANDS
5555
appear back in the list. The port by default is 22 if not specified.
5656
Host and port can be nodesets.
5757

58-
*error_banner [-expire] MESSAGE*::
58+
*error_banner [-expire EXPIRATION] MESSAGE*::
5959
Set the error banner in etcd. Removes the error banner in etcd if
6060
'MESSAGE' is absent. 'MESSAGE' can be multiline. The error banner is
6161
displayed to the client when no backend can be reached (more
@@ -83,6 +83,12 @@ COMMANDS
8383
*show error_banner*::
8484
Show error banners stored in etcd and in configuration.
8585

86+
*get_config [-user USER] [-groups GROUPS]*::
87+
Display the calculated configuration. If a user is given, its system
88+
groups (if any) are added to the given groups. If a user and/or groups
89+
are given with '-user' and '-groups' options, the configuration will
90+
be calculated for these specific user/groups.
91+
8692

8793
FILES
8894
-----

misc/sshproxyctl-completion.bash

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ _sshproxyctl() {
55
COMPREPLY=()
66
cur="${COMP_WORDS[COMP_CWORD]}"
77
prev="${COMP_WORDS[COMP_CWORD-1]}"
8-
commands="disable enable error_banner forget help show version"
8+
commands="disable enable error_banner forget get_config help show version"
99
opts="-h -c ${commands}"
1010

1111
case "${prev}" in
@@ -30,6 +30,9 @@ _sshproxyctl() {
3030
error_banner)
3131
COMPREPLY=( $(compgen -W '-expire' -- "${cur}") )
3232
;;
33+
get_config)
34+
COMPREPLY=( $(compgen -W '-user -groups' -- "${cur}") )
35+
;;
3336
-all)
3437
COMPREPLY=( $(compgen -W '-csv -json connections users groups' -- "${cur}") )
3538
;;

pkg/utils/config.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,33 @@ type subConfig struct {
111111
SSH sshConfig
112112
}
113113

114+
// Return slice of strings containing formatted configuration values
115+
func PrintConfig(config *Config, groups map[string]bool) []string {
116+
output := []string{fmt.Sprintf("groups = %v", groups)}
117+
output = append(output, fmt.Sprintf("config.debug = %v", config.Debug))
118+
output = append(output, fmt.Sprintf("config.log = %s", config.Log))
119+
output = append(output, fmt.Sprintf("config.check_interval = %s", config.CheckInterval.Duration()))
120+
output = append(output, fmt.Sprintf("config.error_banner = %s", config.ErrorBanner))
121+
output = append(output, fmt.Sprintf("config.dump = %s", config.Dump))
122+
output = append(output, fmt.Sprintf("config.dump_limit_size = %d", config.DumpLimitSize))
123+
output = append(output, fmt.Sprintf("config.dump_limit_window = %s", config.DumpLimitWindow.Duration()))
124+
output = append(output, fmt.Sprintf("config.etcd_stats_interval = %s", config.EtcdStatsInterval.Duration()))
125+
output = append(output, fmt.Sprintf("config.log_stats_interval = %s", config.LogStatsInterval.Duration()))
126+
output = append(output, fmt.Sprintf("config.etcd = %+v", config.Etcd))
127+
output = append(output, fmt.Sprintf("config.bg_command = %s", config.BgCommand))
128+
for k, v := range config.TranslateCommands {
129+
output = append(output, fmt.Sprintf("config.TranslateCommands.%s = %+v", k, v))
130+
}
131+
output = append(output, fmt.Sprintf("config.environment = %v", config.Environment))
132+
for k, v := range config.Routes {
133+
output = append(output, fmt.Sprintf("config.routes.%s = %+v", k, v))
134+
}
135+
output = append(output, fmt.Sprintf("config.max_connections_per_user = %d", config.MaxConnectionsPerUser))
136+
output = append(output, fmt.Sprintf("config.ssh.exe = %s", config.SSH.Exe))
137+
output = append(output, fmt.Sprintf("config.ssh.args = %v", config.SSH.Args))
138+
return output
139+
}
140+
114141
func parseSubConfig(config *Config, subconfig *subConfig) error {
115142
if subconfig.Debug != nil {
116143
config.Debug = subconfig.Debug.(bool)

0 commit comments

Comments
 (0)