fix lint
This commit is contained in:
parent
46eef25212
commit
c9027f707e
17 changed files with 106 additions and 249 deletions
|
|
@ -1,5 +1,5 @@
|
|||
package loader
|
||||
|
||||
import (
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/auditor/typescript_logger"
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/auditor/typescriptlogger" // init plugin
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,35 +6,51 @@ import (
|
|||
"github.com/tg123/sshpiper/sshpiperd/registry"
|
||||
)
|
||||
|
||||
type AuditorHook func(conn ssh.ConnMetadata, msg []byte) ([]byte, error)
|
||||
// Hook is called after ssh connection pipe is established and all msg will be
|
||||
// put into the hook and msg will be converted to the return value of this func
|
||||
type Hook func(conn ssh.ConnMetadata, msg []byte) ([]byte, error)
|
||||
|
||||
// Auditor holds Hooks for upstream and downstream
|
||||
type Auditor interface {
|
||||
GetUpstreamHook() AuditorHook
|
||||
GetDownstreamHook() AuditorHook
|
||||
|
||||
// All msg between piper and upstream will be put into the hook
|
||||
// nil for ignore
|
||||
GetUpstreamHook() Hook
|
||||
|
||||
// All msg between piper and downstream will be put into the hook
|
||||
// nil for ignore
|
||||
GetDownstreamHook() Hook
|
||||
|
||||
// Will be called when connection closed
|
||||
Close() error
|
||||
}
|
||||
|
||||
type AuditorProvider interface {
|
||||
// Provider is a factory for Auditor
|
||||
type Provider interface {
|
||||
registry.Plugin
|
||||
|
||||
CreateAuditor(ssh.ConnMetadata) (Auditor, error)
|
||||
// Will be called when piped connection established
|
||||
// nil for no Auditor needed for this connection
|
||||
Create(ssh.ConnMetadata) (Auditor, error)
|
||||
}
|
||||
|
||||
var (
|
||||
drivers = registry.NewRegistry()
|
||||
)
|
||||
|
||||
func Register(name string, driver AuditorProvider) {
|
||||
// Register adds an auditor with given name to registry
|
||||
func Register(name string, driver Provider) {
|
||||
drivers.Register(name, driver)
|
||||
}
|
||||
|
||||
// All return all registerd auditors
|
||||
func All() []string {
|
||||
return drivers.Drivers()
|
||||
}
|
||||
|
||||
func Get(name string) AuditorProvider {
|
||||
if d, ok := drivers.Get(name).(AuditorProvider); ok {
|
||||
// Get returns an auditor by name, return nil if not found
|
||||
func Get(name string) Provider {
|
||||
if d, ok := drivers.Get(name).(Provider); ok {
|
||||
return d
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
package typescript_logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
const (
|
||||
msgChannelData = 94
|
||||
)
|
||||
|
||||
type filePtyLogger struct {
|
||||
typescript *os.File
|
||||
timing *os.File
|
||||
|
||||
oldtime time.Time
|
||||
}
|
||||
|
||||
func newFilePtyLogger(outputdir string) (*filePtyLogger, error) {
|
||||
|
||||
now := time.Now()
|
||||
|
||||
filename := fmt.Sprintf("%d", now.Unix())
|
||||
|
||||
typescript, err := os.OpenFile(path.Join(outputdir, fmt.Sprintf("%v.typescript", filename)), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = typescript.Write([]byte(fmt.Sprintf("Script started on %v\n", now.Format(time.ANSIC))))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
timing, err := os.OpenFile(path.Join(outputdir, fmt.Sprintf("%v.timing", filename)), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &filePtyLogger{
|
||||
typescript: typescript,
|
||||
timing: timing,
|
||||
oldtime: time.Now(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *filePtyLogger) loggingTty(conn ssh.ConnMetadata, msg []byte) ([]byte, error) {
|
||||
|
||||
if msg[0] == msgChannelData {
|
||||
|
||||
buf := msg[9:]
|
||||
|
||||
now := time.Now()
|
||||
|
||||
delta := now.Sub(l.oldtime)
|
||||
|
||||
// see term-utils/script.c
|
||||
fmt.Fprintf(l.timing, "%v.%06v %v\n", int64(delta/time.Second), int64(delta/time.Microsecond), len(buf))
|
||||
|
||||
l.oldtime = now
|
||||
|
||||
_, err := l.typescript.Write(buf)
|
||||
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (l *filePtyLogger) Close() (err error) {
|
||||
_, err = l.typescript.Write([]byte(fmt.Sprintf("Script done on %v\n", time.Now().Format(time.ANSIC))))
|
||||
l.typescript.Close()
|
||||
l.timing.Close()
|
||||
|
||||
return nil // TODO
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
package typescript_logger
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/tg123/sshpiper/sshpiperd/auditor"
|
||||
)
|
||||
|
||||
type plugin struct {
|
||||
Config struct {
|
||||
OutputDir string `long:"auditor-typescriptlogger-outputdir" default:"/var/sshpiper" description:"Place where logged typescript files were saved" env:"SSHPIPERD_AUDITOR_TYPESCRIPTLOGGER_OUTPUTDIR" ini-name:"auditor-typescriptlogger-outputdir"`
|
||||
}
|
||||
}
|
||||
|
||||
func (p *plugin) GetName() string {
|
||||
return "typescript-logger"
|
||||
}
|
||||
|
||||
func (p *plugin) GetOpts() interface{} {
|
||||
return &p.Config
|
||||
}
|
||||
|
||||
func (p *plugin) CreateAuditor(conn ssh.ConnMetadata) (auditor.Auditor, error) {
|
||||
dir := path.Join(p.Config.OutputDir, conn.User())
|
||||
err := os.MkdirAll(dir, 0700)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newFilePtyLogger(dir)
|
||||
}
|
||||
|
||||
func (p *plugin) Init(logger *log.Logger) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *filePtyLogger) GetUpstreamHook() auditor.AuditorHook {
|
||||
return l.loggingTty
|
||||
}
|
||||
|
||||
func (l *filePtyLogger) GetDownstreamHook() auditor.AuditorHook {
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
auditor.Register("typescript-logger", new(plugin))
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package loader
|
||||
|
||||
import (
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/challenger/pam"
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/challenger/welcometext"
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/challenger/pam" // init plugin
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/challenger/welcometext" // init plugin
|
||||
)
|
||||
|
|
|
|||
|
|
@ -70,5 +70,5 @@ func init() {
|
|||
return
|
||||
}
|
||||
|
||||
challenger.Register("pam", challenger.NewFromHandler("pam", func() challenger.ChallengerHandler { return pamChallenger }, nil, nil))
|
||||
challenger.Register("pam", challenger.NewFromHandler("pam", func() challenger.Handler { return pamChallenger }, nil, nil))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ type plugin struct {
|
|||
name string
|
||||
init func(logger *log.Logger) error
|
||||
opts interface{}
|
||||
gethandler func() ChallengerHandler
|
||||
gethandler func() Handler
|
||||
}
|
||||
|
||||
func (p *plugin) GetName() string {
|
||||
|
|
@ -19,7 +19,7 @@ func (p *plugin) GetOpts() interface{} {
|
|||
return p.opts
|
||||
}
|
||||
|
||||
func (p *plugin) GetChallengerHandler() ChallengerHandler {
|
||||
func (p *plugin) GetHandler() Handler {
|
||||
return p.gethandler()
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,8 @@ func (p *plugin) Init(logger *log.Logger) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func NewFromHandler(name string, gethandler func() ChallengerHandler, opts interface{}, init func(glogger *log.Logger) error) Challenger {
|
||||
// NewFromHandler creates a Challenger with given functions
|
||||
func NewFromHandler(name string, gethandler func() Handler, opts interface{}, init func(glogger *log.Logger) error) Provider {
|
||||
return &plugin{
|
||||
name: name,
|
||||
init: init,
|
||||
|
|
|
|||
|
|
@ -6,28 +6,35 @@ import (
|
|||
"github.com/tg123/sshpiper/sshpiperd/registry"
|
||||
)
|
||||
|
||||
type ChallengerHandler func(conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge) (bool, error)
|
||||
// Handler is the callback for additional challenger
|
||||
// use args client ssh.KeyboardInteractiveChallenge to interact with downstream
|
||||
// return bool to indicate whether if the challenge is passed
|
||||
type Handler func(conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge) (bool, error)
|
||||
|
||||
type Challenger interface {
|
||||
// Provider is a factory for Challenger
|
||||
type Provider interface {
|
||||
registry.Plugin
|
||||
|
||||
GetChallengerHandler() ChallengerHandler
|
||||
GetHandler() Handler
|
||||
}
|
||||
|
||||
var (
|
||||
drivers = registry.NewRegistry()
|
||||
)
|
||||
|
||||
func Register(name string, driver Challenger) {
|
||||
// Register adds an challenger with given name to registry
|
||||
func Register(name string, driver Provider) {
|
||||
drivers.Register(name, driver)
|
||||
}
|
||||
|
||||
// All return all registerd challenger
|
||||
func All() []string {
|
||||
return drivers.Drivers()
|
||||
}
|
||||
|
||||
func Get(name string) Challenger {
|
||||
if d, ok := drivers.Get(name).(Challenger); ok {
|
||||
// Get returns an challenger by name, return nil if not found
|
||||
func Get(name string) Provider {
|
||||
if d, ok := drivers.Get(name).(Provider); ok {
|
||||
return d
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/tg123/sshpiper/sshpiperd/challenger"
|
||||
)
|
||||
|
||||
func makeWelcomeChallenger(text string) challenger.ChallengerHandler {
|
||||
func makeWelcomeChallenger(text string) challenger.Handler {
|
||||
return func(conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge) (bool, error) {
|
||||
|
||||
client(conn.User(), text, nil, nil)
|
||||
|
|
@ -19,13 +19,13 @@ func makeWelcomeChallenger(text string) challenger.ChallengerHandler {
|
|||
|
||||
func init() {
|
||||
|
||||
var h challenger.ChallengerHandler
|
||||
var h challenger.Handler
|
||||
|
||||
config := &struct {
|
||||
WelcomeText string `long:"challenger-welcometext" description:"Show a welcome text when connect to sshpiper server" env:"SSHPIPERD_CHALLENGER_WELCOMETEXT" ini-name:"challenger-welcometext"`
|
||||
}{}
|
||||
|
||||
challenger.Register("welcometext", challenger.NewFromHandler("welcometext", func() challenger.ChallengerHandler {
|
||||
challenger.Register("welcometext", challenger.NewFromHandler("welcometext", func() challenger.Handler {
|
||||
return h
|
||||
}, config, func(logger *log.Logger) error {
|
||||
h = makeWelcomeChallenger(config.WelcomeText)
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ func main() {
|
|||
if command == nil {
|
||||
|
||||
if len(args) > 0 {
|
||||
return fmt.Errorf("Unknown command %v", args)
|
||||
return fmt.Errorf("unknown command %v", args)
|
||||
}
|
||||
|
||||
// init log
|
||||
|
|
|
|||
|
|
@ -26,15 +26,15 @@ func startPiper(config *piperdConfig) {
|
|||
|
||||
logger.Println("sshpiper is about to start")
|
||||
|
||||
// install upstream driver
|
||||
upstream := upstream.Get(config.UpstreamDriver)
|
||||
if upstream == nil {
|
||||
logger.Fatalf("upstream driver %v not found", config.UpstreamDriver)
|
||||
// install upstreamProvider driver
|
||||
upstreamProvider := upstream.Get(config.UpstreamDriver)
|
||||
if upstreamProvider == nil {
|
||||
logger.Fatalf("upstreamProvider driver %v not found", config.UpstreamDriver)
|
||||
}
|
||||
upstream.Init(logger)
|
||||
upstreamProvider.Init(logger)
|
||||
|
||||
piper := &ssh.SSHPiperConfig{
|
||||
FindUpstream: upstream.GetFindUpstreamHandle(),
|
||||
FindUpstream: upstreamProvider.GetHandler(),
|
||||
}
|
||||
|
||||
// install challenger
|
||||
|
|
@ -47,10 +47,10 @@ func startPiper(config *piperdConfig) {
|
|||
logger.Printf("using additional challenger %s", config.ChallengerDriver)
|
||||
ac.Init(logger)
|
||||
|
||||
piper.AdditionalChallenge = ac.GetChallengerHandler()
|
||||
piper.AdditionalChallenge = ac.GetHandler()
|
||||
}
|
||||
|
||||
var bigbro auditor.AuditorProvider
|
||||
var bigbro auditor.Provider
|
||||
// install auditor
|
||||
if config.AuditorDriver != "" {
|
||||
bigbro = auditor.Get(config.AuditorDriver)
|
||||
|
|
@ -100,7 +100,7 @@ func startPiper(config *piperdConfig) {
|
|||
}
|
||||
|
||||
if bigbro != nil {
|
||||
a, err := bigbro.CreateAuditor(p.DownstreamConnMeta())
|
||||
a, err := bigbro.Create(p.DownstreamConnMeta())
|
||||
if err != nil {
|
||||
logger.Printf("connection from %v failed to create auditor reason: %v", c.RemoteAddr(), err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package loader
|
||||
|
||||
import (
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/upstream/mysql"
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/upstream/workingdir"
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/upstream/mysql" // init plugin
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/upstream/workingdir" // init plugin
|
||||
)
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ type PubkeyUpstreamMap struct {
|
|||
tx *sql.Tx
|
||||
}
|
||||
|
||||
func NewPubkeyUpstreamMap(db *sql.DB) *PubkeyUpstreamMap {
|
||||
return &PubkeyUpstreamMap{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
//func NewPubkeyUpstreamMap(db *sql.DB) *PubkeyUpstreamMap {
|
||||
// return &PubkeyUpstreamMap{
|
||||
// db: db,
|
||||
// }
|
||||
//}
|
||||
|
||||
// Function to help make the api feel cleaner
|
||||
func (t *PubkeyUpstreamMap) Commit() error {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ type plugin struct {
|
|||
Dbname string `long:"upstream-mysql-dbname" default:"sshpiper" description:"mysql dbname for driver" env:"SSHPIPERD_UPSTREAM_MYSQL_DBNAME" ini-name:"upstream-mysql-dbname"`
|
||||
}
|
||||
|
||||
w MysqlWorkingDir
|
||||
w mysqlWorkingDir
|
||||
}
|
||||
|
||||
func (p *plugin) GetName() string {
|
||||
|
|
@ -30,7 +30,7 @@ func (p *plugin) GetOpts() interface{} {
|
|||
return &p.Config
|
||||
}
|
||||
|
||||
func (p *plugin) GetFindUpstreamHandle() upstream.UpstreamHandler {
|
||||
func (p *plugin) GetHandler() upstream.Handler {
|
||||
return p.w.FindUpstream
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/tg123/sshpiper/sshpiperd/upstream/mysql/crud"
|
||||
)
|
||||
|
||||
type MysqlWorkingDir struct {
|
||||
type mysqlWorkingDir struct {
|
||||
ConnectDB func() (*sql.DB, error)
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ func connectServer(db *sql.DB, sid int64) (net.Conn, error) {
|
|||
|
||||
return net.Dial("tcp", addr)
|
||||
}
|
||||
func (w *MysqlWorkingDir) connectUpstream(db *sql.DB, uid int64, defuser string) (net.Conn, *ssh.SSHPiperAuthPipe, error) {
|
||||
func (w *mysqlWorkingDir) connectUpstream(db *sql.DB, uid int64, defuser string) (net.Conn, *ssh.SSHPiperAuthPipe, error) {
|
||||
|
||||
o := crud.NewUpstream(db)
|
||||
|
||||
|
|
@ -98,26 +98,26 @@ func findPKId(db *sql.DB, key ssh.PublicKey) (int64, error) {
|
|||
return -1, nil
|
||||
}
|
||||
|
||||
func findByPublicKey(db *sql.DB, downkey ssh.PublicKey) (int64, error) {
|
||||
kid, err := findPKId(db, downkey)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
if kid > 0 {
|
||||
opum := crud.NewPubkeyUpstreamMap(db)
|
||||
u, err := opum.GetFirstByPubkeyId(kid)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
if u != nil {
|
||||
return u.UpstreamId, nil
|
||||
}
|
||||
}
|
||||
|
||||
return -1, nil
|
||||
}
|
||||
//func findByPublicKey(db *sql.DB, downkey ssh.PublicKey) (int64, error) {
|
||||
// kid, err := findPKId(db, downkey)
|
||||
// if err != nil {
|
||||
// return -1, err
|
||||
// }
|
||||
//
|
||||
// if kid > 0 {
|
||||
// opum := crud.NewPubkeyUpstreamMap(db)
|
||||
// u, err := opum.GetFirstByPubkeyId(kid)
|
||||
// if err != nil {
|
||||
// return -1, err
|
||||
// }
|
||||
//
|
||||
// if u != nil {
|
||||
// return u.UpstreamId, nil
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return -1, nil
|
||||
//}
|
||||
|
||||
func findByUsername(db *sql.DB, username string) (int64, error) {
|
||||
ouum := crud.NewUserUpstreamMap(db)
|
||||
|
|
@ -133,8 +133,8 @@ func findByUsername(db *sql.DB, username string) (int64, error) {
|
|||
return -1, nil
|
||||
}
|
||||
|
||||
//func (w *MysqlWorkingDir) FindUpstream(conn ssh.ConnMetadata, downkey ssh.PublicKey) (net.Conn, *ssh.SSHPiperAuthPipe, error) {
|
||||
func (w *MysqlWorkingDir) FindUpstream(conn ssh.ConnMetadata) (net.Conn, *ssh.SSHPiperAuthPipe, error) {
|
||||
//func (w *mysqlWorkingDir) FindUpstream(conn ssh.ConnMetadata, downkey ssh.PublicKey) (net.Conn, *ssh.SSHPiperAuthPipe, error) {
|
||||
func (w *mysqlWorkingDir) FindUpstream(conn ssh.ConnMetadata) (net.Conn, *ssh.SSHPiperAuthPipe, error) {
|
||||
|
||||
db, err := w.ConnectDB()
|
||||
defer db.Close()
|
||||
|
|
@ -171,7 +171,7 @@ func (w *MysqlWorkingDir) FindUpstream(conn ssh.ConnMetadata) (net.Conn, *ssh.SS
|
|||
return nil, nil, fmt.Errorf("no upstream found")
|
||||
}
|
||||
|
||||
func (w *MysqlWorkingDir) MapPublicKey(conn ssh.ConnMetadata, key ssh.PublicKey) (ssh.Signer, error) {
|
||||
func (w *mysqlWorkingDir) MapPublicKey(conn ssh.ConnMetadata, key ssh.PublicKey) (ssh.Signer, error) {
|
||||
db, err := w.ConnectDB()
|
||||
defer db.Close()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -8,28 +8,36 @@ import (
|
|||
"github.com/tg123/sshpiper/sshpiperd/registry"
|
||||
)
|
||||
|
||||
type UpstreamHandler func(conn ssh.ConnMetadata) (net.Conn, *ssh.SSHPiperAuthPipe, error)
|
||||
// Handler will be installed into sshpiper and help to establish the connection to upstream
|
||||
// the returned auth pipe is to map/convert downstream auth method to another auth for
|
||||
// connecting to upstrem.
|
||||
// e.g. map downstream public key to another upstream private key
|
||||
type Handler func(conn ssh.ConnMetadata) (net.Conn, *ssh.SSHPiperAuthPipe, error)
|
||||
|
||||
type UpstreamProvider interface {
|
||||
// Provider is a factory for Upstream Provider
|
||||
type Provider interface {
|
||||
registry.Plugin
|
||||
|
||||
GetFindUpstreamHandle() UpstreamHandler
|
||||
GetHandler() Handler
|
||||
}
|
||||
|
||||
var (
|
||||
drivers = registry.NewRegistry()
|
||||
)
|
||||
|
||||
func Register(name string, driver UpstreamProvider) {
|
||||
// Register adds an upstream provider with given name to registry
|
||||
func Register(name string, driver Provider) {
|
||||
drivers.Register(name, driver)
|
||||
}
|
||||
|
||||
// All return all registerd upstream providers
|
||||
func All() []string {
|
||||
return drivers.Drivers()
|
||||
}
|
||||
|
||||
func Get(name string) UpstreamProvider {
|
||||
if d, ok := drivers.Get(name).(UpstreamProvider); ok {
|
||||
// Get returns an upstream provider by name, return nil if not found
|
||||
func Get(name string) Provider {
|
||||
if d, ok := drivers.Get(name).(Provider); ok {
|
||||
return d
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
package workingdir
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/tg123/sshpiper/sshpiperd/upstream"
|
||||
)
|
||||
|
||||
var logger *log.Logger
|
||||
|
||||
type plugin struct {
|
||||
}
|
||||
|
||||
func (p *plugin) GetName() string {
|
||||
return "workingdir"
|
||||
}
|
||||
|
||||
func (p *plugin) GetOpts() interface{} {
|
||||
return &config
|
||||
}
|
||||
|
||||
func (p *plugin) GetFindUpstreamHandle() upstream.UpstreamHandler {
|
||||
return findUpstreamFromUserfile
|
||||
}
|
||||
|
||||
func (p *plugin) Init(glogger *log.Logger) error {
|
||||
|
||||
logger = glogger
|
||||
|
||||
logger.Printf("upstream provider: workingdir %v init", config.WorkingDir)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
upstream.Register("workingdir", &plugin{})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue