add remote selection to store and admin

This commit is contained in:
Umputun
2019-06-25 20:06:30 -05:00
parent 126d2d93da
commit 48fcb0a5d9
2 changed files with 28 additions and 91 deletions
+28 -34
View File
@@ -32,6 +32,7 @@ import (
"github.com/umputun/remark/backend/app/store/admin"
"github.com/umputun/remark/backend/app/store/engine"
"github.com/umputun/remark/backend/app/store/image"
"github.com/umputun/remark/backend/app/store/remote"
"github.com/umputun/remark/backend/app/store/service"
)
@@ -92,10 +93,7 @@ type StoreGroup struct {
Path string `long:"path" env:"PATH" default:"./var" description:"parent dir for bolt files"`
Timeout time.Duration `long:"timeout" env:"TIMEOUT" default:"30s" description:"bolt timeout"`
} `group:"bolt" namespace:"bolt" env-namespace:"BOLT"`
Remote struct {
API string `long:"api" env:"API" description:"remote extension api url"`
TimeOut time.Duration `long:"timeout" env:"TIMEOUT" description:"http timeout"`
} `group:"remote" namespace:"remote" env-namespace:"REMOTE"`
Remote RemoteGroup `group:"remote" namespace:"remote" env-namespace:"REMOTE"`
}
// ImageGroup defines options group for store pictures
@@ -138,11 +136,12 @@ type CacheGroup struct {
// AdminGroup defines options group for admin params
type AdminGroup struct {
Type string `long:"type" env:"TYPE" description:"type of admin store" choice:"shared" choice:"mongo" default:"shared"`
Type string `long:"type" env:"TYPE" description:"type of admin store" choice:"shared" choice:"remote" default:"shared"`
Shared struct {
Admins []string `long:"id" env:"ID" description:"admin(s) ids" env-delim:","`
Email string `long:"email" env:"EMAIL" default:"" description:"admin email"`
} `group:"shared" namespace:"shared" env-namespace:"SHARED"`
Remote RemoteGroup `group:"remote" namespace:"remote" env-namespace:"REMOTE"`
}
// NotifyGroup defines options for notification
@@ -174,6 +173,14 @@ type StreamGroup struct {
MaxActive int `long:"max" env:"MAX" default:"500" description:"max number of parallel streams"`
}
// RemoteGroup defines options for remote modules (plugins)
type RemoteGroup struct {
API string `long:"api" env:"API" description:"remote extension api url"`
TimeOut time.Duration `long:"timeout" env:"TIMEOUT" description:"http timeout"`
AuthUser string `long:"auth_user" env:"AUTH_USER" description:"basic auth user name"`
AuthPassword string `long:"auth_passwd" env:"AUTH_PASSWD" description:"basic auth user password"`
}
// serverApp holds all active objects
type serverApp struct {
*ServerCommand
@@ -410,13 +417,14 @@ func (s *ServerCommand) makeDataStore() (result engine.Interface, err error) {
sites = append(sites, engine.BoltSite{SiteID: site, FileName: fmt.Sprintf("%s/%s.db", s.Store.Bolt.Path, site)})
}
result, err = engine.NewBoltDB(bolt.Options{Timeout: s.Store.Bolt.Timeout}, sites...)
// case "mongo":
// mgServer, e := s.makeMongo()
// if e != nil {
// return result, errors.Wrap(e, "failed to create mongo server")
// }
// conn := mongo.NewConnection(mgServer, s.Mongo.DB, "")
// result, err = engine.NewMongo(conn, 500, 100*time.Millisecond)
case "remote":
r := &engine.Remote{Client: remote.Client{
API: s.Store.Remote.API,
Client: http.Client{Timeout: s.Store.Remote.TimeOut},
AuthUser: s.Store.Remote.AuthUser,
AuthPasswd: s.Store.Remote.AuthPassword,
}}
return r, nil
default:
return nil, errors.Errorf("unsupported store type %s", s.Store.Type)
}
@@ -432,13 +440,6 @@ func (s *ServerCommand) makeAvatarStore() (avatar.Store, error) {
return nil, err
}
return avatar.NewLocalFS(s.Avatar.FS.Path), nil
// case "mongo":
// mgServer, err := s.makeMongo()
// if err != nil {
// return nil, errors.Wrap(err, "failed to create mongo server")
// }
// conn := mongo.NewConnection(mgServer, s.Mongo.DB, "")
// return avatar.NewGridFS(conn), nil
case "bolt":
if err := makeDirs(path.Dir(s.Avatar.Bolt.File)); err != nil {
return nil, err
@@ -481,13 +482,14 @@ func (s *ServerCommand) makeAdminStore() (admin.Store, error) {
}
}
return admin.NewStaticStore(s.SharedSecret, s.Admin.Shared.Admins, s.Admin.Shared.Email), nil
// case "mongo":
// mgServer, e := s.makeMongo()
// if e != nil {
// return nil, errors.Wrap(e, "failed to create mongo server")
// }
// conn := mongo.NewConnection(mgServer, s.Mongo.DB, "admin")
// return admin.NewMongoStore(conn, s.SharedSecret), nil
case "remote":
r := &admin.Remote{Client: remote.Client{
API: s.Admin.Remote.API,
Client: http.Client{Timeout: s.Admin.Remote.TimeOut},
AuthUser: s.Admin.Remote.AuthUser,
AuthPasswd: s.Admin.Remote.AuthPassword,
}}
return r, nil
default:
return nil, errors.Errorf("unsupported admin store type %s", s.Admin.Type)
}
@@ -499,14 +501,6 @@ func (s *ServerCommand) makeCache() (cache.LoadingCache, error) {
case "mem":
return cache.NewMemoryCache(cache.MaxCacheSize(s.Cache.Max.Size), cache.MaxValSize(s.Cache.Max.Value),
cache.MaxKeys(s.Cache.Max.Items))
// case "mongo":
// mgServer, err := s.makeMongo()
// if err != nil {
// return nil, errors.Wrap(err, "failed to create mongo server")
// }
// conn := mongo.NewConnection(mgServer, s.Mongo.DB, "cache")
// return cache.NewMongoCache(conn, cache.MaxCacheSize(s.Cache.Max.Size), cache.MaxValSize(s.Cache.Max.Value),
// cache.MaxKeys(s.Cache.Max.Items))
case "none":
return &cache.Nop{}, nil
}
-57
View File
@@ -14,10 +14,8 @@ import (
"time"
"github.com/dgrijalva/jwt-go"
"github.com/globalsign/mgo"
"github.com/go-pkgz/auth/token"
log "github.com/go-pkgz/lgr"
"github.com/go-pkgz/mongo"
"github.com/jessevdk/go-flags"
"github.com/stretchr/testify/assert"
@@ -131,61 +129,6 @@ func TestServerApp_AnonMode(t *testing.T) {
app.Wait()
}
func TestServerApp_WithMongo(t *testing.T) {
mongoURL := os.Getenv("MONGO_TEST")
if mongoURL == "" {
mongoURL = "mongodb://localhost:27017/test"
}
if mongoURL == "skip" {
t.Skip("skip mongo app test")
}
opts := ServerCommand{}
opts.SetCommon(CommonOpts{RemarkURL: "https://demo.remark42.com", SharedSecret: "123456"})
// prepare options
p := flags.NewParser(&opts, flags.Default)
_, err := p.ParseArgs([]string{"--admin-passwd=password", "--cache.type=none", "--store.type=mongo",
"--avatar.type=mongo", "--mongo.url=" + mongoURL, "--mongo.db=test_remark", "--port=12345", "--admin.type=mongo"})
require.Nil(t, err)
opts.Auth.Github.CSEC, opts.Auth.Github.CID = "csec", "cid"
opts.BackupLocation, opts.Image.FS.Path = "/tmp", "/tmp"
// create app
app, err := opts.newServerApp()
require.Nil(t, err)
defer func() {
s, e := mongo.NewServerWithURL(mongoURL, 10*time.Second)
assert.NoError(t, e)
conn := mongo.NewConnection(s, "test_remark", "")
_ = conn.WithDB(func(dbase *mgo.Database) error {
assert.NoError(t, dbase.DropDatabase())
return nil
})
}()
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(5 * time.Second)
log.Print("[TEST] terminate app")
cancel()
}()
go func() { _ = app.run(ctx) }()
time.Sleep(100 * time.Millisecond) // let server start
// send ping
resp, err := http.Get("http://localhost:12345/api/v1/ping")
require.Nil(t, err)
defer resp.Body.Close()
assert.Equal(t, 200, resp.StatusCode)
body, err := ioutil.ReadAll(resp.Body)
assert.Nil(t, err)
assert.Equal(t, "pong", string(body))
app.Wait()
}
func TestServerApp_WithSSL(t *testing.T) {
opts := ServerCommand{}