[#25] Fixes around cmd/gate

closes #25

Signed-off-by: Evgeniy Kulikov <kim@nspcc.ru>
This commit is contained in:
Evgeniy Kulikov 2020-10-13 12:31:23 +03:00
parent 339c3d934d
commit 65b5d6e3d2
4 changed files with 129 additions and 69 deletions

View file

@ -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 {

View file

@ -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
View 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
}
)

View file

@ -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)