Refactor plugin/yaml/main.go and plugin/yaml/yaml.go to support multiple YAML config files (#477)
This commit is contained in:
parent
23e18f4f7c
commit
4694964c11
3 changed files with 62 additions and 43 deletions
|
|
@ -14,12 +14,12 @@ func main() {
|
|||
Name: "yaml",
|
||||
Usage: "sshpiperd yaml plugin",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
&cli.StringSliceFlag{
|
||||
Name: "config",
|
||||
Usage: "path to yaml config file",
|
||||
Usage: "path to yaml config files, can be globs as well",
|
||||
Required: true,
|
||||
EnvVars: []string{"SSHPIPERD_YAML_CONFIG"},
|
||||
Destination: &plugin.File,
|
||||
Destination: &plugin.FileGlobs,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "no-check-perm",
|
||||
|
|
|
|||
|
|
@ -9,12 +9,11 @@ import (
|
|||
)
|
||||
|
||||
type skelpipeWrapper struct {
|
||||
plugin *plugin
|
||||
|
||||
pipe *yamlPipe
|
||||
pipe *yamlPipe
|
||||
config *piperConfig
|
||||
}
|
||||
type skelpipeFromWrapper struct {
|
||||
plugin *plugin
|
||||
config *piperConfig
|
||||
|
||||
from *yamlPipeFrom
|
||||
to *yamlPipeTo
|
||||
|
|
@ -28,7 +27,7 @@ type skelpipePublicKeyWrapper struct {
|
|||
}
|
||||
|
||||
type skelpipeToWrapper struct {
|
||||
plugin *plugin
|
||||
config *piperConfig
|
||||
|
||||
username string
|
||||
to *yamlPipeTo
|
||||
|
|
@ -39,7 +38,7 @@ func (s *skelpipeWrapper) From() []libplugin.SkelPipeFrom {
|
|||
for _, f := range s.pipe.From {
|
||||
|
||||
w := &skelpipeFromWrapper{
|
||||
plugin: s.plugin,
|
||||
config: s.config,
|
||||
from: &f,
|
||||
to: &s.pipe.To,
|
||||
}
|
||||
|
|
@ -70,7 +69,7 @@ func (s *skelpipeToWrapper) IgnoreHostKey(conn libplugin.ConnMetadata) bool {
|
|||
}
|
||||
|
||||
func (s *skelpipeToWrapper) KnownHosts(conn libplugin.ConnMetadata) ([]byte, error) {
|
||||
return s.plugin.loadFileOrDecodeMany(s.to.KnownHosts, s.to.KnownHostsData, map[string]string{
|
||||
return s.config.loadFileOrDecodeMany(s.to.KnownHosts, s.to.KnownHostsData, map[string]string{
|
||||
"DOWNSTREAM_USER": conn.User(),
|
||||
"UPSTREAM_USER": s.username,
|
||||
})
|
||||
|
|
@ -101,7 +100,7 @@ func (s *skelpipeFromWrapper) MatchConn(conn libplugin.ConnMetadata) (libplugin.
|
|||
|
||||
if matched {
|
||||
return &skelpipeToWrapper{
|
||||
plugin: s.plugin,
|
||||
config: s.config,
|
||||
username: targetuser,
|
||||
to: s.to,
|
||||
}, nil
|
||||
|
|
@ -115,19 +114,19 @@ func (s *skelpipePasswordWrapper) TestPassword(conn libplugin.ConnMetadata, pass
|
|||
}
|
||||
|
||||
func (s *skelpipePublicKeyWrapper) AuthorizedKeys(conn libplugin.ConnMetadata) ([]byte, error) {
|
||||
return s.plugin.loadFileOrDecodeMany(s.from.AuthorizedKeys, s.from.AuthorizedKeysData, map[string]string{
|
||||
return s.config.loadFileOrDecodeMany(s.from.AuthorizedKeys, s.from.AuthorizedKeysData, map[string]string{
|
||||
"DOWNSTREAM_USER": conn.User(),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *skelpipePublicKeyWrapper) TrustedUserCAKeys(conn libplugin.ConnMetadata) ([]byte, error) {
|
||||
return s.plugin.loadFileOrDecodeMany(s.from.TrustedUserCAKeys, s.from.TrustedUserCAKeysData, map[string]string{
|
||||
return s.config.loadFileOrDecodeMany(s.from.TrustedUserCAKeys, s.from.TrustedUserCAKeysData, map[string]string{
|
||||
"DOWNSTREAM_USER": conn.User(),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *skelpipeToWrapper) PrivateKey(conn libplugin.ConnMetadata) ([]byte, []byte, error) {
|
||||
p, err := s.plugin.loadFileOrDecode(s.to.PrivateKey, s.to.PrivateKeyData, map[string]string{
|
||||
p, err := s.config.loadFileOrDecode(s.to.PrivateKey, s.to.PrivateKeyData, map[string]string{
|
||||
"DOWNSTREAM_USER": conn.User(),
|
||||
"UPSTREAM_USER": s.username,
|
||||
})
|
||||
|
|
@ -144,19 +143,21 @@ func (s *skelpipeToWrapper) OverridePassword(conn libplugin.ConnMetadata) ([]byt
|
|||
}
|
||||
|
||||
func (p *plugin) listPipe(_ libplugin.ConnMetadata) ([]libplugin.SkelPipe, error) {
|
||||
config, err := p.loadConfig()
|
||||
configs, err := p.loadConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pipes []libplugin.SkelPipe
|
||||
for _, pipe := range config.Pipes {
|
||||
wrapper := &skelpipeWrapper{
|
||||
plugin: p,
|
||||
pipe: &pipe,
|
||||
}
|
||||
pipes = append(pipes, wrapper)
|
||||
for _, config := range configs {
|
||||
for _, pipe := range config.Pipes {
|
||||
wrapper := &skelpipeWrapper{
|
||||
config: &config,
|
||||
pipe: &pipe,
|
||||
}
|
||||
pipes = append(pipes, wrapper)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return pipes, nil
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
|
|
@ -76,10 +77,12 @@ type yamlPipe struct {
|
|||
type piperConfig struct {
|
||||
Version string `yaml:"version"`
|
||||
Pipes []yamlPipe `yaml:"pipes,flow"`
|
||||
|
||||
filename string
|
||||
}
|
||||
|
||||
type plugin struct {
|
||||
File string
|
||||
FileGlobs cli.StringSlice
|
||||
NoCheckPerm bool
|
||||
}
|
||||
|
||||
|
|
@ -87,8 +90,7 @@ func newYamlPlugin() *plugin {
|
|||
return &plugin{}
|
||||
}
|
||||
|
||||
func (p *plugin) checkPerm() error {
|
||||
filename := p.File
|
||||
func (p *plugin) checkPerm(filename string) error {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -111,28 +113,44 @@ func (p *plugin) checkPerm() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) loadConfig() (piperConfig, error) {
|
||||
var config piperConfig
|
||||
func (p *plugin) loadConfig() ([]piperConfig, error) {
|
||||
var allconfig []piperConfig
|
||||
|
||||
err := p.checkPerm()
|
||||
if err != nil {
|
||||
return config, err
|
||||
for _, fg := range p.FileGlobs.Value() {
|
||||
files, err := filepath.Glob(fg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
|
||||
if err := p.checkPerm(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configbyte, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config piperConfig
|
||||
|
||||
err = yaml.Unmarshal(configbyte, &config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config.filename = file
|
||||
|
||||
allconfig = append(allconfig, config)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
configbyte, err := os.ReadFile(p.File)
|
||||
if err != nil {
|
||||
return config, err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(configbyte, &config)
|
||||
if err != nil {
|
||||
return config, err
|
||||
}
|
||||
|
||||
return config, nil
|
||||
return allconfig, nil
|
||||
}
|
||||
|
||||
func (p *plugin) loadFileOrDecode(file string, base64data string, vars map[string]string) ([]byte, error) {
|
||||
func (p *piperConfig) loadFileOrDecode(file string, base64data string, vars map[string]string) ([]byte, error) {
|
||||
if file != "" {
|
||||
|
||||
file = os.Expand(file, func(placeholderName string) string {
|
||||
|
|
@ -145,7 +163,7 @@ func (p *plugin) loadFileOrDecode(file string, base64data string, vars map[strin
|
|||
})
|
||||
|
||||
if !filepath.IsAbs(file) {
|
||||
file = filepath.Join(filepath.Dir(p.File), file)
|
||||
file = filepath.Join(filepath.Dir(p.filename), file)
|
||||
}
|
||||
|
||||
return os.ReadFile(file)
|
||||
|
|
@ -158,7 +176,7 @@ func (p *plugin) loadFileOrDecode(file string, base64data string, vars map[strin
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *plugin) loadFileOrDecodeMany(files listOrString, base64data listOrString, vars map[string]string) ([]byte, error) {
|
||||
func (p *piperConfig) loadFileOrDecodeMany(files listOrString, base64data listOrString, vars map[string]string) ([]byte, error) {
|
||||
var byteSlices [][]byte
|
||||
|
||||
for _, file := range files.Combine() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue