list for working dir
This commit is contained in:
parent
15939ea49e
commit
c96750f280
7 changed files with 136 additions and 46 deletions
|
|
@ -1,7 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tg123/sshpiper/sshpiperd/upstream"
|
||||
"os"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func createPipeMgr(load func() (upstream.Provider, error)) interface{} {
|
||||
|
|
@ -33,6 +36,24 @@ func createPipeMgr(load func() (upstream.Provider, error)) interface{} {
|
|||
}{}
|
||||
|
||||
pipeMgrCmd.List.callback = func(args []string) error {
|
||||
p, err := load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// opt := pipeMgrCmd.List
|
||||
pipes, err := p.ListPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t := template.Must(template.New("").Parse(`{{.Username}} -> {{.UpstreamUsername}}@{{.Host}}:{{.Port}}`))
|
||||
|
||||
for _, pipe := range pipes {
|
||||
t.Execute(os.Stdout, pipe)
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -53,14 +74,14 @@ func createPipeMgr(load func() (upstream.Provider, error)) interface{} {
|
|||
}
|
||||
|
||||
pipeMgrCmd.Remove.callback = func(args []string) error {
|
||||
|
||||
name := pipeMgrCmd.Remove.Name
|
||||
p, err := load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.RemovePipe(name)
|
||||
opt := pipeMgrCmd.Remove
|
||||
|
||||
return p.RemovePipe(opt.Name)
|
||||
}
|
||||
|
||||
return &pipeMgrCmd
|
||||
|
|
|
|||
|
|
@ -112,12 +112,16 @@ type testupstream struct {
|
|||
h upstream.Handler
|
||||
}
|
||||
|
||||
func (t *testupstream) ListPipe() ([]upstream.Pipe, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *testupstream) CreatePipe(opt upstream.CreatePipeOption) error {
|
||||
panic("implement me")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *testupstream) RemovePipe(name string) error {
|
||||
panic("implement me")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *testupstream) GetHandler() upstream.Handler {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ type plugin struct {
|
|||
db *gorm.DB
|
||||
}
|
||||
|
||||
func (p *plugin) ListPipe() ([]upstreamprovider.Pipe, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (p *plugin) CreatePipe(opt upstreamprovider.CreatePipeOption) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,12 +21,21 @@ type CreatePipeOption struct {
|
|||
Port uint
|
||||
}
|
||||
|
||||
type Pipe struct {
|
||||
Username string
|
||||
UpstreamUsername string
|
||||
Host string
|
||||
Port uint
|
||||
}
|
||||
|
||||
// Provider is a factory for Upstream Provider
|
||||
type Provider interface {
|
||||
registry.Plugin
|
||||
|
||||
GetHandler() Handler
|
||||
|
||||
ListPipe() ([]Pipe, error)
|
||||
|
||||
CreatePipe(opt CreatePipeOption) error
|
||||
|
||||
RemovePipe(name string) error
|
||||
|
|
|
|||
|
|
@ -14,6 +14,36 @@ var logger *log.Logger
|
|||
type plugin struct {
|
||||
}
|
||||
|
||||
func (p *plugin) ListPipe() ([]upstream.Pipe, error) {
|
||||
files, err := ioutil.ReadDir(config.WorkingDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pipes := make([]upstream.Pipe, 0, len(files))
|
||||
for _, file := range files {
|
||||
if !file.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
data, err := userUpstreamFile.read(file.Name())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
host, port, mappedUser, err := parseUpstreamFile(string(data))
|
||||
|
||||
pipes = append(pipes, upstream.Pipe{
|
||||
Host: host,
|
||||
Port: uint(port),
|
||||
Username: file.Name(),
|
||||
UpstreamUsername: mappedUser,
|
||||
})
|
||||
}
|
||||
|
||||
return pipes, nil
|
||||
}
|
||||
|
||||
func (p *plugin) CreatePipe(opt upstream.CreatePipeOption) error {
|
||||
err := os.MkdirAll(config.WorkingDir+"/"+opt.Username, 0775)
|
||||
if err != nil {
|
||||
|
|
@ -35,7 +65,7 @@ func (p *plugin) CreatePipe(opt upstream.CreatePipeOption) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("upstream file alreay exists")
|
||||
return fmt.Errorf("upstream file of [%v] alreay exists", opt.Username)
|
||||
}
|
||||
|
||||
func (p *plugin) RemovePipe(name string) error {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
|
@ -83,43 +84,48 @@ func checkUsername(user string) bool {
|
|||
return usernameRule.MatchString(user)
|
||||
}
|
||||
|
||||
func parseUpstreamFile(data string) (string, string) {
|
||||
|
||||
var user string
|
||||
var line string
|
||||
|
||||
func parseUpstreamFile(data string) (host string, port int, user string, err error) {
|
||||
r := bufio.NewReader(strings.NewReader(data))
|
||||
|
||||
for {
|
||||
var err error
|
||||
line, err = r.ReadString('\n')
|
||||
host, err = r.ReadString('\n')
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
line = strings.TrimSpace(line)
|
||||
host = strings.TrimSpace(host)
|
||||
|
||||
if line != "" && line[0] != '#' {
|
||||
if host != "" && host[0] != '#' {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
t := strings.SplitN(line, "@", 2)
|
||||
t := strings.SplitN(host, "@", 2)
|
||||
|
||||
if len(t) > 1 {
|
||||
user = t[0]
|
||||
line = t[1]
|
||||
host = t[1]
|
||||
}
|
||||
|
||||
// test if ok
|
||||
if _, _, err := net.SplitHostPort(line); err != nil && line != "" {
|
||||
h, p, err := net.SplitHostPort(host)
|
||||
if err == nil {
|
||||
host = h
|
||||
port, err = strconv.Atoi(p)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else if host != "" {
|
||||
// test valid after concat :22
|
||||
if _, _, err := net.SplitHostPort(line + ":22"); err == nil {
|
||||
line += ":22"
|
||||
if _, _, err := net.SplitHostPort(host + ":22"); err == nil {
|
||||
port = 22
|
||||
}
|
||||
}
|
||||
|
||||
return line, user
|
||||
if host == "" {
|
||||
err = fmt.Errorf("empty addr")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func findUpstreamFromUserfile(conn ssh.ConnMetadata) (net.Conn, *ssh.AuthPipe, error) {
|
||||
|
|
@ -143,11 +149,11 @@ func findUpstreamFromUserfile(conn ssh.ConnMetadata) (net.Conn, *ssh.AuthPipe, e
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
addr, mappedUser := parseUpstreamFile(string(data))
|
||||
|
||||
if addr == "" {
|
||||
return nil, nil, fmt.Errorf("empty addr")
|
||||
host, port, mappedUser, err := parseUpstreamFile(string(data))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
addr := fmt.Sprintf("%v:%v", host, port)
|
||||
|
||||
logger.Printf("mapping user [%v] to [%v@%v]", user, mappedUser, addr)
|
||||
|
||||
|
|
|
|||
|
|
@ -126,58 +126,74 @@ func (s stubConnMetadata) LocalAddr() net.Addr { return nil }
|
|||
|
||||
func TestParseUpstreamFile(t *testing.T) {
|
||||
|
||||
var addr, user string
|
||||
{
|
||||
|
||||
addr, user = parseUpstreamFile(`
|
||||
addr, port, user, _ := parseUpstreamFile(`
|
||||
|
||||
a:123
|
||||
|
||||
`)
|
||||
|
||||
if addr != "a:123" || user != "" {
|
||||
t.Fatalf("parse failed common with port")
|
||||
if addr != "a" || port != 123 || user != "" {
|
||||
t.Fatalf("parse failed common with port")
|
||||
}
|
||||
}
|
||||
|
||||
addr, user = parseUpstreamFile(`
|
||||
{
|
||||
|
||||
addr, port, user, _ := parseUpstreamFile(`
|
||||
a:123
|
||||
b:456
|
||||
`)
|
||||
|
||||
if addr != "a:123" || user != "" {
|
||||
t.Fatalf("parse multi line")
|
||||
if addr != "a" || port != 123 || user != "" {
|
||||
t.Fatalf("parse multi line")
|
||||
}
|
||||
}
|
||||
|
||||
addr, user = parseUpstreamFile(`
|
||||
{
|
||||
|
||||
addr, port, user, _ := parseUpstreamFile(`
|
||||
host
|
||||
`)
|
||||
|
||||
if addr != "host:22" || user != "" {
|
||||
t.Fatalf("parse no port")
|
||||
if addr != "host" || port != 22 || user != "" {
|
||||
t.Fatalf("parse no port")
|
||||
}
|
||||
}
|
||||
|
||||
addr, user = parseUpstreamFile(`
|
||||
{
|
||||
|
||||
addr, port, user, _ := parseUpstreamFile(`
|
||||
user@github.com
|
||||
`)
|
||||
|
||||
if addr != "github.com:22" || user != "user" {
|
||||
t.Fatalf("parse no port with user")
|
||||
if addr != "github.com" || port != 22 || user != "user" {
|
||||
t.Fatalf("parse no port with user")
|
||||
}
|
||||
}
|
||||
|
||||
addr, user = parseUpstreamFile(``)
|
||||
{
|
||||
|
||||
if addr != "" || user != "" {
|
||||
t.Fatalf("empty file")
|
||||
_, _, _, err := parseUpstreamFile(``)
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("empty file")
|
||||
}
|
||||
}
|
||||
|
||||
addr, user = parseUpstreamFile(`
|
||||
{
|
||||
|
||||
addr, port, user, _ := parseUpstreamFile(`
|
||||
|
||||
# comment
|
||||
user@github.com
|
||||
test@linode.com
|
||||
`)
|
||||
|
||||
if addr != "github.com:22" || user != "user" {
|
||||
t.Fatalf("multi line with comment")
|
||||
if addr != "github.com" || port != 22 || user != "user" {
|
||||
t.Fatalf("multi line with comment")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue