diff --git a/cmd/gate/app-settings.go b/cmd/gate/app-settings.go index 4e121e48c..6518c43c2 100644 --- a/cmd/gate/app-settings.go +++ b/cmd/gate/app-settings.go @@ -1,16 +1,20 @@ package main import ( + "context" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "fmt" "io" + "io/ioutil" "os" "strconv" "strings" "time" + "github.com/nspcc-dev/neofs-authmate/accessbox/hcs" + crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-s3-gate/api/pool" "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 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 ( - err error - neofsPrivateKey *ecdsa.PrivateKey + err error + key *ecdsa.PrivateKey ) - switch nfspk := v.GetString(cfgNeoFSPrivateKey); nfspk { + + switch val := v.GetString(cfgNeoFSPrivateKey); val { case generated: - neofsPrivateKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return nil, errors.Wrap(err, "could not generate NeoFS private key") } default: - neofsPrivateKey, err = crypto.LoadPrivateKey(nfspk) + key, err = crypto.LoadPrivateKey(val) if err != nil { return nil, errors.Wrap(err, "could not load NeoFS private key") } } - gapk := v.GetString(cfgGateAuthPrivateKey) - gateAuthPrivateKey, err := auth.LoadGateAuthPrivateKey(gapk) - if err != nil { - return nil, errors.Wrapf(err, "could not load gate auth private key %q", gapk) - } - // NB: Maybe choose a peer more smarter. - center, err := auth.NewCenter(l, peers[0].Address) - if err != nil { - return nil, errors.Wrap(err, "failed to create auth center") - } - if err = center.SetAuthKeys(gateAuthPrivateKey); err != nil { - 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 + + return key, nil +} + +func fetchAuthCenter(ctx context.Context, p *authCenterParams) (*auth.Center, error) { + return auth.New(ctx, &auth.Params{ + Con: p.Pool, + Log: p.Logger, + Timeout: p.Timeout, + GAKey: p.GateAuthKeys, + NFKey: p.NeoFSPrivateKey, + }) } func fetchPeers(l *zap.Logger, v *viper.Viper) []pool.Peer { diff --git a/cmd/gate/app.go b/cmd/gate/app.go index 043d58e2d..baf2cddf2 100644 --- a/cmd/gate/app.go +++ b/cmd/gate/app.go @@ -7,6 +7,7 @@ import ( "net/http" "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/handler" "github.com/nspcc-dev/neofs-s3-gate/api/layer" @@ -19,13 +20,13 @@ import ( type ( App struct { - center *auth.Center - cli pool.Pool - log *zap.Logger - cfg *viper.Viper - tls *tlsConfig - obj layer.Client - api api.Handler + cli pool.Pool + ctr *auth.Center + log *zap.Logger + cfg *viper.Viper + tls *tlsConfig + obj layer.Client + api api.Handler conTimeout 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 ( - err error - cli pool.Pool - tls *tlsConfig - caller api.Handler - obj layer.Client - key *ecdsa.PrivateKey + err error + cli pool.Pool + tls *tlsConfig + caller api.Handler + ctr *auth.Center + obj layer.Client + + gaKey *hcs.X25519Keys + nfKey *ecdsa.PrivateKey + reBalance = defaultRebalanceTimer conTimeout = defaultConnectTimeout reqTimeout = defaultRequestTimeout @@ -59,19 +64,6 @@ func newApp(l *zap.Logger, v *viper.Viper) *App { maxClientsCount = defaultMaxClientsCount 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 { conTimeout = v @@ -89,15 +81,36 @@ func newApp(l *zap.Logger, v *viper.Viper) *App { 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{ + ConnectTimeout: conTimeout, + RequestTimeout: reqTimeout, ConnectionTTL: v.GetDuration(cfgConnectionTTL), - ConnectTimeout: v.GetDuration(cfgConnectTimeout), - RequestTimeout: v.GetDuration(cfgRequestTimeout), Peers: peers, Logger: l, - PrivateKey: key, + PrivateKey: nfKey, GRPCLogger: gRPCLogger(l), GRPCVerbose: v.GetBool(cfgGRPCVerbose), @@ -105,27 +118,42 @@ func newApp(l *zap.Logger, v *viper.Viper) *App { ClientParameters: keepalive.ClientParameters{}, } - if v := v.GetDuration(cfgRebalanceTimer); v > 0 { - reBalance = v - } - if cli, err = pool.New(poolConfig); err != nil { 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 - ctx, cancel := context.WithTimeout(context.Background(), conTimeout) + ctx, cancel := context.WithTimeout(ctx, conTimeout) defer cancel() cli.ReBalance(ctx) - if _, err = cli.GetConnection(ctx); err != nil { + if _, err = cli.Connection(ctx); err != nil { l.Fatal("could not establish connection", 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)) } @@ -134,13 +162,13 @@ func newApp(l *zap.Logger, v *viper.Viper) *App { } return &App{ - center: center, - cli: cli, - log: l, - cfg: v, - obj: obj, - tls: tls, - api: caller, + ctr: ctr, + cli: cli, + log: l, + cfg: v, + obj: obj, + tls: tls, + api: caller, webDone: 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) // 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 srv.Handler = router diff --git a/cmd/gate/app_option.go b/cmd/gate/app_option.go new file mode 100644 index 000000000..188a228fd --- /dev/null +++ b/cmd/gate/app_option.go @@ -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 + } +) diff --git a/cmd/gate/main.go b/cmd/gate/main.go index a2b06b11c..e49f090ba 100644 --- a/cmd/gate/main.go +++ b/cmd/gate/main.go @@ -4,8 +4,8 @@ func main() { var ( v = newSettings() l = newLogger(v) - a = newApp(l, v) g = newGracefulContext(l) + a = newApp(g, l, v) ) go a.Server(g)