add remote selection to store and admin
This commit is contained in:
+28
-34
@@ -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
|
||||
}
|
||||
|
||||
@@ -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{}
|
||||
|
||||
Reference in New Issue
Block a user