forked from TrueCloudLab/frostfs-s3-gw
[#25] Fixes around cmd/gate
closes #25 Signed-off-by: Evgeniy Kulikov <kim@nspcc.ru>
This commit is contained in:
parent
339c3d934d
commit
65b5d6e3d2
4 changed files with 129 additions and 69 deletions
|
@ -1,16 +1,20 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-authmate/accessbox/hcs"
|
||||||
|
|
||||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||||
"github.com/nspcc-dev/neofs-s3-gate/api/pool"
|
"github.com/nspcc-dev/neofs-s3-gate/api/pool"
|
||||||
"github.com/nspcc-dev/neofs-s3-gate/auth"
|
"github.com/nspcc-dev/neofs-s3-gate/auth"
|
||||||
|
@ -91,40 +95,47 @@ type empty int
|
||||||
|
|
||||||
func (empty) Read([]byte) (int, error) { return 0, io.EOF }
|
func (empty) Read([]byte) (int, error) { return 0, io.EOF }
|
||||||
|
|
||||||
func fetchAuthCenter(l *zap.Logger, v *viper.Viper, peers []pool.Peer) (*auth.Center, error) {
|
func fetchGateAuthKeys(v *viper.Viper) (*hcs.X25519Keys, error) {
|
||||||
|
path := v.GetString(cfgGateAuthPrivateKey)
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return hcs.NewKeys(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchNeoFSKey(v *viper.Viper) (*ecdsa.PrivateKey, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
neofsPrivateKey *ecdsa.PrivateKey
|
key *ecdsa.PrivateKey
|
||||||
)
|
)
|
||||||
switch nfspk := v.GetString(cfgNeoFSPrivateKey); nfspk {
|
|
||||||
|
switch val := v.GetString(cfgNeoFSPrivateKey); val {
|
||||||
case generated:
|
case generated:
|
||||||
neofsPrivateKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not generate NeoFS private key")
|
return nil, errors.Wrap(err, "could not generate NeoFS private key")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
neofsPrivateKey, err = crypto.LoadPrivateKey(nfspk)
|
key, err = crypto.LoadPrivateKey(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not load NeoFS private key")
|
return nil, errors.Wrap(err, "could not load NeoFS private key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gapk := v.GetString(cfgGateAuthPrivateKey)
|
|
||||||
gateAuthPrivateKey, err := auth.LoadGateAuthPrivateKey(gapk)
|
return key, nil
|
||||||
if err != nil {
|
}
|
||||||
return nil, errors.Wrapf(err, "could not load gate auth private key %q", gapk)
|
|
||||||
}
|
func fetchAuthCenter(ctx context.Context, p *authCenterParams) (*auth.Center, error) {
|
||||||
// NB: Maybe choose a peer more smarter.
|
return auth.New(ctx, &auth.Params{
|
||||||
center, err := auth.NewCenter(l, peers[0].Address)
|
Con: p.Pool,
|
||||||
if err != nil {
|
Log: p.Logger,
|
||||||
return nil, errors.Wrap(err, "failed to create auth center")
|
Timeout: p.Timeout,
|
||||||
}
|
GAKey: p.GateAuthKeys,
|
||||||
if err = center.SetAuthKeys(gateAuthPrivateKey); err != nil {
|
NFKey: p.NeoFSPrivateKey,
|
||||||
return nil, errors.Wrap(err, "failed to set gate auth keys")
|
})
|
||||||
}
|
|
||||||
if err = center.SetNeoFSKeys(neofsPrivateKey); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to set NeoFS keys")
|
|
||||||
}
|
|
||||||
return center, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchPeers(l *zap.Logger, v *viper.Viper) []pool.Peer {
|
func fetchPeers(l *zap.Logger, v *viper.Viper) []pool.Peer {
|
||||||
|
|
118
cmd/gate/app.go
118
cmd/gate/app.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-authmate/accessbox/hcs"
|
||||||
"github.com/nspcc-dev/neofs-s3-gate/api"
|
"github.com/nspcc-dev/neofs-s3-gate/api"
|
||||||
"github.com/nspcc-dev/neofs-s3-gate/api/handler"
|
"github.com/nspcc-dev/neofs-s3-gate/api/handler"
|
||||||
"github.com/nspcc-dev/neofs-s3-gate/api/layer"
|
"github.com/nspcc-dev/neofs-s3-gate/api/layer"
|
||||||
|
@ -19,13 +20,13 @@ import (
|
||||||
|
|
||||||
type (
|
type (
|
||||||
App struct {
|
App struct {
|
||||||
center *auth.Center
|
cli pool.Pool
|
||||||
cli pool.Pool
|
ctr *auth.Center
|
||||||
log *zap.Logger
|
log *zap.Logger
|
||||||
cfg *viper.Viper
|
cfg *viper.Viper
|
||||||
tls *tlsConfig
|
tls *tlsConfig
|
||||||
obj layer.Client
|
obj layer.Client
|
||||||
api api.Handler
|
api api.Handler
|
||||||
|
|
||||||
conTimeout time.Duration
|
conTimeout time.Duration
|
||||||
reqTimeout time.Duration
|
reqTimeout time.Duration
|
||||||
|
@ -44,14 +45,18 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func newApp(l *zap.Logger, v *viper.Viper) *App {
|
func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
cli pool.Pool
|
cli pool.Pool
|
||||||
tls *tlsConfig
|
tls *tlsConfig
|
||||||
caller api.Handler
|
caller api.Handler
|
||||||
obj layer.Client
|
ctr *auth.Center
|
||||||
key *ecdsa.PrivateKey
|
obj layer.Client
|
||||||
|
|
||||||
|
gaKey *hcs.X25519Keys
|
||||||
|
nfKey *ecdsa.PrivateKey
|
||||||
|
|
||||||
reBalance = defaultRebalanceTimer
|
reBalance = defaultRebalanceTimer
|
||||||
conTimeout = defaultConnectTimeout
|
conTimeout = defaultConnectTimeout
|
||||||
reqTimeout = defaultRequestTimeout
|
reqTimeout = defaultRequestTimeout
|
||||||
|
@ -59,19 +64,6 @@ func newApp(l *zap.Logger, v *viper.Viper) *App {
|
||||||
maxClientsCount = defaultMaxClientsCount
|
maxClientsCount = defaultMaxClientsCount
|
||||||
maxClientsDeadline = defaultMaxClientsDeadline
|
maxClientsDeadline = defaultMaxClientsDeadline
|
||||||
)
|
)
|
||||||
peers := fetchPeers(l, v)
|
|
||||||
center, err := fetchAuthCenter(l, v, peers)
|
|
||||||
if err != nil {
|
|
||||||
l.Fatal("failed to initialize auth center", zap.Error(err))
|
|
||||||
}
|
|
||||||
key = center.GetNeoFSPrivateKey()
|
|
||||||
|
|
||||||
if v.IsSet(cfgTLSKeyFile) && v.IsSet(cfgTLSCertFile) {
|
|
||||||
tls = &tlsConfig{
|
|
||||||
KeyFile: v.GetString(cfgTLSKeyFile),
|
|
||||||
CertFile: v.GetString(cfgTLSCertFile),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := v.GetDuration(cfgConnectTimeout); v > 0 {
|
if v := v.GetDuration(cfgConnectTimeout); v > 0 {
|
||||||
conTimeout = v
|
conTimeout = v
|
||||||
|
@ -89,15 +81,36 @@ func newApp(l *zap.Logger, v *viper.Viper) *App {
|
||||||
maxClientsDeadline = v
|
maxClientsDeadline = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v := v.GetDuration(cfgRebalanceTimer); v > 0 {
|
||||||
|
reBalance = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if nfKey, err = fetchNeoFSKey(v); err != nil {
|
||||||
|
l.Fatal("could not load NeoFS private key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if gaKey, err = fetchGateAuthKeys(v); err != nil {
|
||||||
|
l.Fatal("could not load gate auth key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet(cfgTLSKeyFile) && v.IsSet(cfgTLSCertFile) {
|
||||||
|
tls = &tlsConfig{
|
||||||
|
KeyFile: v.GetString(cfgTLSKeyFile),
|
||||||
|
CertFile: v.GetString(cfgTLSCertFile),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
peers := fetchPeers(l, v)
|
||||||
|
|
||||||
poolConfig := &pool.Config{
|
poolConfig := &pool.Config{
|
||||||
|
ConnectTimeout: conTimeout,
|
||||||
|
RequestTimeout: reqTimeout,
|
||||||
ConnectionTTL: v.GetDuration(cfgConnectionTTL),
|
ConnectionTTL: v.GetDuration(cfgConnectionTTL),
|
||||||
ConnectTimeout: v.GetDuration(cfgConnectTimeout),
|
|
||||||
RequestTimeout: v.GetDuration(cfgRequestTimeout),
|
|
||||||
|
|
||||||
Peers: peers,
|
Peers: peers,
|
||||||
|
|
||||||
Logger: l,
|
Logger: l,
|
||||||
PrivateKey: key,
|
PrivateKey: nfKey,
|
||||||
|
|
||||||
GRPCLogger: gRPCLogger(l),
|
GRPCLogger: gRPCLogger(l),
|
||||||
GRPCVerbose: v.GetBool(cfgGRPCVerbose),
|
GRPCVerbose: v.GetBool(cfgGRPCVerbose),
|
||||||
|
@ -105,27 +118,42 @@ func newApp(l *zap.Logger, v *viper.Viper) *App {
|
||||||
ClientParameters: keepalive.ClientParameters{},
|
ClientParameters: keepalive.ClientParameters{},
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := v.GetDuration(cfgRebalanceTimer); v > 0 {
|
|
||||||
reBalance = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if cli, err = pool.New(poolConfig); err != nil {
|
if cli, err = pool.New(poolConfig); err != nil {
|
||||||
l.Fatal("could not prepare pool connections", zap.Error(err))
|
l.Fatal("could not prepare pool connections", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ // prepare auth center
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, conTimeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
params := &authCenterParams{
|
||||||
|
Logger: l,
|
||||||
|
Pool: cli,
|
||||||
|
|
||||||
|
Timeout: conTimeout,
|
||||||
|
|
||||||
|
GateAuthKeys: gaKey,
|
||||||
|
NeoFSPrivateKey: nfKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctr, err = fetchAuthCenter(ctx, params); err != nil {
|
||||||
|
l.Fatal("failed to initialize auth center", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{ // should establish connection with NeoFS Storage Nodes
|
{ // should establish connection with NeoFS Storage Nodes
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), conTimeout)
|
ctx, cancel := context.WithTimeout(ctx, conTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
cli.ReBalance(ctx)
|
cli.ReBalance(ctx)
|
||||||
|
|
||||||
if _, err = cli.GetConnection(ctx); err != nil {
|
if _, err = cli.Connection(ctx); err != nil {
|
||||||
l.Fatal("could not establish connection",
|
l.Fatal("could not establish connection",
|
||||||
zap.Error(err))
|
zap.Error(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if obj, err = layer.NewLayer(l, cli, key); err != nil {
|
if obj, err = layer.NewLayer(l, cli, nfKey); err != nil {
|
||||||
l.Fatal("could not prepare ObjectLayer", zap.Error(err))
|
l.Fatal("could not prepare ObjectLayer", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,13 +162,13 @@ func newApp(l *zap.Logger, v *viper.Viper) *App {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &App{
|
return &App{
|
||||||
center: center,
|
ctr: ctr,
|
||||||
cli: cli,
|
cli: cli,
|
||||||
log: l,
|
log: l,
|
||||||
cfg: v,
|
cfg: v,
|
||||||
obj: obj,
|
obj: obj,
|
||||||
tls: tls,
|
tls: tls,
|
||||||
api: caller,
|
api: caller,
|
||||||
|
|
||||||
webDone: make(chan struct{}, 1),
|
webDone: make(chan struct{}, 1),
|
||||||
wrkDone: make(chan struct{}, 1),
|
wrkDone: make(chan struct{}, 1),
|
||||||
|
@ -189,7 +217,7 @@ func (a *App) Server(ctx context.Context) {
|
||||||
attachProfiler(router, a.cfg, a.log)
|
attachProfiler(router, a.cfg, a.log)
|
||||||
|
|
||||||
// Attach S3 API:
|
// Attach S3 API:
|
||||||
api.Attach(router, a.maxClients, a.api, a.center, a.log)
|
api.Attach(router, a.maxClients, a.api, a.ctr, a.log)
|
||||||
|
|
||||||
// Use mux.Router as http.Handler
|
// Use mux.Router as http.Handler
|
||||||
srv.Handler = router
|
srv.Handler = router
|
||||||
|
|
21
cmd/gate/app_option.go
Normal file
21
cmd/gate/app_option.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-authmate/accessbox/hcs"
|
||||||
|
"github.com/nspcc-dev/neofs-s3-gate/api/pool"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
authCenterParams struct {
|
||||||
|
Pool pool.Client
|
||||||
|
Logger *zap.Logger
|
||||||
|
Timeout time.Duration
|
||||||
|
|
||||||
|
GateAuthKeys *hcs.X25519Keys
|
||||||
|
NeoFSPrivateKey *ecdsa.PrivateKey
|
||||||
|
}
|
||||||
|
)
|
|
@ -4,8 +4,8 @@ func main() {
|
||||||
var (
|
var (
|
||||||
v = newSettings()
|
v = newSettings()
|
||||||
l = newLogger(v)
|
l = newLogger(v)
|
||||||
a = newApp(l, v)
|
|
||||||
g = newGracefulContext(l)
|
g = newGracefulContext(l)
|
||||||
|
a = newApp(g, l, v)
|
||||||
)
|
)
|
||||||
|
|
||||||
go a.Server(g)
|
go a.Server(g)
|
||||||
|
|
Loading…
Reference in a new issue