forked from TrueCloudLab/frostfs-s3-gw
Remove enclove as a separate entity; move auth center to app settings
This commit is contained in:
parent
a890d9142d
commit
a43c596f49
4 changed files with 156 additions and 220 deletions
|
@ -1,34 +1,83 @@
|
||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/klauspost/compress/zstd"
|
"github.com/klauspost/compress/zstd"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/refs"
|
||||||
"github.com/nspcc-dev/neofs-api-go/service"
|
"github.com/nspcc-dev/neofs-api-go/service"
|
||||||
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Center is a central app's authentication/authorization management unit.
|
// Center is a central app's authentication/authorization management unit.
|
||||||
type Center struct {
|
type Center struct {
|
||||||
enclave *secureEnclave
|
|
||||||
zstdEncoder *zstd.Encoder
|
zstdEncoder *zstd.Encoder
|
||||||
zstdDecoder *zstd.Decoder
|
zstdDecoder *zstd.Decoder
|
||||||
|
neofsKeys struct {
|
||||||
|
PrivateKey *ecdsa.PrivateKey
|
||||||
|
PublicKey *ecdsa.PublicKey
|
||||||
|
}
|
||||||
|
ownerID refs.OwnerID
|
||||||
|
wifString string
|
||||||
|
userAuthKeys struct {
|
||||||
|
PrivateKey *rsa.PrivateKey
|
||||||
|
PublicKey *rsa.PublicKey
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCenter creates an instance of AuthCenter.
|
// NewCenter creates an instance of AuthCenter.
|
||||||
func NewCenter(pathToRSAKey, pathToECDSAKey string) (*Center, error) {
|
func NewCenter() *Center {
|
||||||
zstdEncoder, _ := zstd.NewWriter(nil)
|
zstdEncoder, _ := zstd.NewWriter(nil)
|
||||||
zstdDecoder, _ := zstd.NewReader(nil)
|
zstdDecoder, _ := zstd.NewReader(nil)
|
||||||
enclave, err := newSecureEnclave(pathToRSAKey, pathToECDSAKey)
|
return &Center{
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to create secure enclave")
|
|
||||||
}
|
|
||||||
center := &Center{
|
|
||||||
enclave: enclave,
|
|
||||||
zstdEncoder: zstdEncoder,
|
zstdEncoder: zstdEncoder,
|
||||||
zstdDecoder: zstdDecoder,
|
zstdDecoder: zstdDecoder,
|
||||||
}
|
}
|
||||||
return center, nil
|
}
|
||||||
|
|
||||||
|
func (center *Center) SetNeoFSKeys(key *ecdsa.PrivateKey) error {
|
||||||
|
publicKey := &key.PublicKey
|
||||||
|
oid, err := refs.NewOwnerID(publicKey)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to get OwnerID")
|
||||||
|
}
|
||||||
|
center.neofsKeys.PrivateKey = key
|
||||||
|
wif, err := crypto.WIFEncode(key)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to get WIF string from given key")
|
||||||
|
}
|
||||||
|
center.neofsKeys.PublicKey = publicKey
|
||||||
|
center.ownerID = oid
|
||||||
|
center.wifString = wif
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (center *Center) GetNeoFSKeyPrivateKey() *ecdsa.PrivateKey {
|
||||||
|
return center.neofsKeys.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (center *Center) GetNeoFSKeyPublicKey() *ecdsa.PublicKey {
|
||||||
|
return center.neofsKeys.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (center *Center) GetOwnerID() refs.OwnerID {
|
||||||
|
return center.ownerID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (center *Center) GetWIFString() string {
|
||||||
|
return center.wifString
|
||||||
|
}
|
||||||
|
|
||||||
|
func (center *Center) SetUserAuthKeys(key *rsa.PrivateKey) {
|
||||||
|
center.userAuthKeys.PrivateKey = key
|
||||||
|
center.userAuthKeys.PublicKey = &key.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (center *Center) PackBearerToken(bearerToken *service.BearerTokenMsg) ([]byte, error) {
|
func (center *Center) PackBearerToken(bearerToken *service.BearerTokenMsg) ([]byte, error) {
|
||||||
|
@ -36,7 +85,7 @@ func (center *Center) PackBearerToken(bearerToken *service.BearerTokenMsg) ([]by
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to marshal bearer token")
|
return nil, errors.Wrap(err, "failed to marshal bearer token")
|
||||||
}
|
}
|
||||||
encryptedKeyID, err := center.enclave.Encrypt(gateUserAuthKey, center.compress(data))
|
encryptedKeyID, err := encrypt(center.userAuthKeys.PublicKey, center.compress(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "")
|
return nil, errors.Wrap(err, "")
|
||||||
}
|
}
|
||||||
|
@ -49,7 +98,7 @@ func (center *Center) UnpackBearerToken(packedBearerToken []byte) (*service.Bear
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to decompress key ID")
|
return nil, errors.Wrap(err, "failed to decompress key ID")
|
||||||
}
|
}
|
||||||
keyID, err := center.enclave.Decrypt(gateUserAuthKey, encryptedKeyID)
|
keyID, err := decrypt(center.userAuthKeys.PrivateKey, encryptedKeyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to decrypt key ID")
|
return nil, errors.Wrap(err, "failed to decrypt key ID")
|
||||||
}
|
}
|
||||||
|
@ -76,8 +125,32 @@ func (center *Center) decompress(data []byte) ([]byte, error) {
|
||||||
return decompressedData, nil
|
return decompressedData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encrypt(key *rsa.PublicKey, data []byte) ([]byte, error) {
|
||||||
|
return rsa.EncryptOAEP(sha256.New(), rand.Reader, key, data, []byte{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func decrypt(key *rsa.PrivateKey, data []byte) ([]byte, error) {
|
||||||
|
return rsa.DecryptOAEP(sha256.New(), rand.Reader, key, data, []byte{})
|
||||||
|
}
|
||||||
|
|
||||||
func sha256Hash(data []byte) []byte {
|
func sha256Hash(data []byte) []byte {
|
||||||
hash := sha256.New()
|
hash := sha256.New()
|
||||||
hash.Write(data)
|
hash.Write(data)
|
||||||
return hash.Sum(nil)
|
return hash.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReadRSAPrivateKeyFromPEMFile(filePath string) (*rsa.PrivateKey, error) {
|
||||||
|
kbs, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to read file %s", filePath)
|
||||||
|
}
|
||||||
|
pemBlock, _ := pem.Decode(kbs)
|
||||||
|
if pemBlock == nil {
|
||||||
|
return nil, errors.Errorf("failed to decode PEM data from file %s", filePath)
|
||||||
|
}
|
||||||
|
rsaKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to parse private key bytes from pem data from file %s", filePath)
|
||||||
|
}
|
||||||
|
return rsaKey, nil
|
||||||
|
}
|
||||||
|
|
130
auth/enclave.go
130
auth/enclave.go
|
@ -1,130 +0,0 @@
|
||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/sha256"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/pem"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
gatewayEncryptionKeySize = 4096
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
_ encryptionKeyName = iota
|
|
||||||
// Indicates that the key is used to encrypt
|
|
||||||
// a bearer token to pass auth procedure.
|
|
||||||
gateUserAuthKey
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
_ signatureKeyName = iota
|
|
||||||
// Indicates that the key is a NeoFS ECDSA key.
|
|
||||||
gateNeoFSECDSAKey
|
|
||||||
// Indicates that the key is a NeoFS Ed25519 key.
|
|
||||||
gateNeoFSEd25519Key
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
signatureKeyName byte
|
|
||||||
encryptionKeyName byte
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
signatureKeyPair struct {
|
|
||||||
PrivateKey *ecdsa.PrivateKey
|
|
||||||
PublicKey *ecdsa.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
encryptionKeyPair struct {
|
|
||||||
PrivateKey *rsa.PrivateKey
|
|
||||||
PublicKey *rsa.PublicKey
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type secureEnclave struct {
|
|
||||||
signatureKeys map[signatureKeyName]signatureKeyPair
|
|
||||||
encryptionKeys map[encryptionKeyName]encryptionKeyPair
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSecureEnclave(pathToRSAKey, pathToECDSAKey string) (*secureEnclave, error) {
|
|
||||||
var (
|
|
||||||
rsaKey *rsa.PrivateKey
|
|
||||||
ecdsaKey *ecdsa.PrivateKey
|
|
||||||
)
|
|
||||||
if key1bs, err := ioutil.ReadFile(pathToRSAKey); err != nil {
|
|
||||||
// No file found.
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
if rsaKey, err = rsa.GenerateKey(rand.Reader, gatewayEncryptionKeySize); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to generate RSA key")
|
|
||||||
}
|
|
||||||
key1bs := x509.MarshalPKCS1PrivateKey(rsaKey)
|
|
||||||
data := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: key1bs})
|
|
||||||
if err := ioutil.WriteFile(pathToRSAKey, data, 0o600); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to write file %s", pathToRSAKey)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, errors.Wrapf(err, "failed to open file %s", pathToRSAKey)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pemBlock, _ := pem.Decode(key1bs)
|
|
||||||
if pemBlock == nil {
|
|
||||||
return nil, errors.Errorf("failed to decode PEM data from file %s", pathToRSAKey)
|
|
||||||
}
|
|
||||||
rsaKey, err = x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to parse private key bytes from pem data from file %s", pathToRSAKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if key2bs, err := ioutil.ReadFile(pathToECDSAKey); err != nil {
|
|
||||||
// No file found.
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
if ecdsaKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to generate ECDSA key")
|
|
||||||
}
|
|
||||||
key2bs, err := x509.MarshalECPrivateKey(ecdsaKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("failed to marshal ECDSA private key")
|
|
||||||
}
|
|
||||||
data := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: key2bs})
|
|
||||||
if err := ioutil.WriteFile(pathToECDSAKey, data, 0o600); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to write file %s", pathToECDSAKey)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, errors.Wrapf(err, "failed to open file %s", pathToECDSAKey)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pemBlock, _ := pem.Decode(key2bs)
|
|
||||||
if pemBlock == nil {
|
|
||||||
return nil, errors.Errorf("failed to decode PEM data from file %s", pathToECDSAKey)
|
|
||||||
}
|
|
||||||
ecdsaKey, err = x509.ParseECPrivateKey(pemBlock.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to parse private key bytes from pem data from file %s", pathToECDSAKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &secureEnclave{
|
|
||||||
encryptionKeys: map[encryptionKeyName]encryptionKeyPair{
|
|
||||||
gateUserAuthKey: {rsaKey, &rsaKey.PublicKey},
|
|
||||||
},
|
|
||||||
signatureKeys: map[signatureKeyName]signatureKeyPair{
|
|
||||||
gateNeoFSECDSAKey: {ecdsaKey, &ecdsaKey.PublicKey},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (se *secureEnclave) Encrypt(keyName encryptionKeyName, data []byte) ([]byte, error) {
|
|
||||||
return rsa.EncryptOAEP(sha256.New(), rand.Reader, se.encryptionKeys[keyName].PublicKey, data, []byte{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (se *secureEnclave) Decrypt(keyName encryptionKeyName, data []byte) ([]byte, error) {
|
|
||||||
return rsa.DecryptOAEP(sha256.New(), rand.Reader, se.encryptionKeys[keyName].PrivateKey, data, []byte{})
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -11,19 +12,18 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
s3auth "github.com/minio/minio/auth"
|
||||||
"github.com/minio/minio/neofs/pool"
|
"github.com/minio/minio/neofs/pool"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/minio/minio/misc"
|
"github.com/minio/minio/misc"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/refs"
|
|
||||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type empty int
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
devNull = empty(0)
|
devNull = empty(0)
|
||||||
generated = "generated"
|
generated = "generated"
|
||||||
|
@ -55,7 +55,11 @@ const ( // settings
|
||||||
cfgKeepaliveTimeout = "keepalive.timeout"
|
cfgKeepaliveTimeout = "keepalive.timeout"
|
||||||
cfgKeepalivePermitWithoutStream = "keepalive.permit_without_stream"
|
cfgKeepalivePermitWithoutStream = "keepalive.permit_without_stream"
|
||||||
|
|
||||||
// HTTPS/TLS:
|
// Keys
|
||||||
|
cfgNeoFSPrivateKey = "neofs-ecdsa-key"
|
||||||
|
cfgUserAuthPrivateKey = "userauth-rsa-key"
|
||||||
|
|
||||||
|
// HTTPS/TLS
|
||||||
cfgTLSKeyFile = "tls.key_file"
|
cfgTLSKeyFile = "tls.key_file"
|
||||||
cfgTLSCertFile = "tls.cert_file"
|
cfgTLSCertFile = "tls.cert_file"
|
||||||
|
|
||||||
|
@ -67,7 +71,6 @@ const ( // settings
|
||||||
|
|
||||||
// gRPC
|
// gRPC
|
||||||
cfgGRPCVerbose = "verbose"
|
cfgGRPCVerbose = "verbose"
|
||||||
cfgGRPCPrivateKey = "key"
|
|
||||||
|
|
||||||
// Metrics / Profiler / Web
|
// Metrics / Profiler / Web
|
||||||
cfgEnableMetrics = "metrics"
|
cfgEnableMetrics = "metrics"
|
||||||
|
@ -80,33 +83,37 @@ const ( // settings
|
||||||
cfgApplicationBuildTime = "app.build_time"
|
cfgApplicationBuildTime = "app.build_time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type empty int
|
||||||
|
|
||||||
func (empty) Read([]byte) (int, error) { return 0, io.EOF }
|
func (empty) Read([]byte) (int, error) { return 0, io.EOF }
|
||||||
|
|
||||||
func fetchKey(l *zap.Logger, v *viper.Viper) *ecdsa.PrivateKey {
|
func fetchAuthCenter(l *zap.Logger, v *viper.Viper) (*s3auth.Center, error) {
|
||||||
switch val := v.GetString("key"); val {
|
var (
|
||||||
|
err error
|
||||||
|
neofsPrivateKey *ecdsa.PrivateKey
|
||||||
|
userAuthPrivateKey *rsa.PrivateKey
|
||||||
|
)
|
||||||
|
switch nfspk := v.GetString(cfgNeoFSPrivateKey); nfspk {
|
||||||
case generated:
|
case generated:
|
||||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
neofsPrivateKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Fatal("could not generate private key", zap.Error(err))
|
return nil, errors.Wrap(err, "could not generate NeoFS private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := refs.NewOwnerID(&key.PublicKey)
|
|
||||||
l.Info("generate new key",
|
|
||||||
zap.Stringer("key", id),
|
|
||||||
zap.Error(err))
|
|
||||||
|
|
||||||
return key
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
key, err := crypto.LoadPrivateKey(val)
|
neofsPrivateKey, err = crypto.LoadPrivateKey(nfspk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Fatal("could not load private key",
|
return nil, errors.Wrap(err, "could not load NeoFS private key")
|
||||||
zap.String("key", v.GetString("key")),
|
|
||||||
zap.Error(err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return key
|
|
||||||
}
|
}
|
||||||
|
uapk := v.GetString(cfgUserAuthPrivateKey)
|
||||||
|
userAuthPrivateKey, err = s3auth.ReadRSAPrivateKeyFromPEMFile(uapk)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not load UserAuth private key")
|
||||||
|
}
|
||||||
|
center := s3auth.NewCenter()
|
||||||
|
center.SetUserAuthKeys(userAuthPrivateKey)
|
||||||
|
center.SetNeoFSKeys(neofsPrivateKey)
|
||||||
|
return center, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchPeers(l *zap.Logger, v *viper.Viper) []pool.Peer {
|
func fetchPeers(l *zap.Logger, v *viper.Viper) []pool.Peer {
|
||||||
|
@ -145,22 +152,23 @@ func newSettings() *viper.Viper {
|
||||||
flags.SortFlags = false
|
flags.SortFlags = false
|
||||||
|
|
||||||
flags.Bool(cfgEnableProfiler, false, "enable pprof")
|
flags.Bool(cfgEnableProfiler, false, "enable pprof")
|
||||||
flags.Bool(cfgEnableMetrics, false, "enable prometheus")
|
flags.Bool(cfgEnableMetrics, false, "enable prometheus metrics")
|
||||||
|
|
||||||
help := flags.BoolP("help", "h", false, "show help")
|
help := flags.BoolP("help", "h", false, "show help")
|
||||||
version := flags.BoolP("version", "v", false, "show version")
|
version := flags.BoolP("version", "v", false, "show version")
|
||||||
|
|
||||||
flags.String(cfgGRPCPrivateKey, generated, `"`+generated+`" to generate key, path to private key file, hex string or wif`)
|
flags.String(cfgNeoFSPrivateKey, generated, fmt.Sprintf(`set value to hex string, WIF string, or path to NeoFS private key file (use "%s" to generate key)`, generated))
|
||||||
|
flags.String(cfgUserAuthPrivateKey, "", "set path to file with private key to use in auth scheme")
|
||||||
|
|
||||||
flags.Bool(cfgGRPCVerbose, false, "debug gRPC connections")
|
flags.Bool(cfgGRPCVerbose, false, "set debug mode of gRPC connections")
|
||||||
flags.Duration(cfgRequestTimeout, defaultRequestTimeout, "gRPC request timeout")
|
flags.Duration(cfgRequestTimeout, defaultRequestTimeout, "set gRPC request timeout")
|
||||||
flags.Duration(cfgConnectTimeout, defaultConnectTimeout, "gRPC connect timeout")
|
flags.Duration(cfgConnectTimeout, defaultConnectTimeout, "set gRPC connect timeout")
|
||||||
flags.Duration(cfgRebalanceTimer, defaultRebalanceTimer, "gRPC connection rebalance timer")
|
flags.Duration(cfgRebalanceTimer, defaultRebalanceTimer, "set gRPC connection rebalance timer")
|
||||||
|
|
||||||
ttl := flags.DurationP(cfgConnectionTTL, "t", defaultTTL, "gRPC connection time to live")
|
ttl := flags.DurationP(cfgConnectionTTL, "t", defaultTTL, "set gRPC connection time to live")
|
||||||
|
|
||||||
flags.String(cfgListenAddress, "0.0.0.0:8080", "S3 Gateway listen address")
|
flags.String(cfgListenAddress, "0.0.0.0:8080", "set address to listen")
|
||||||
peers := flags.StringArrayP("peers", "p", nil, "NeoFS nodes")
|
peers := flags.StringArrayP("peers", "p", nil, "set NeoFS nodes")
|
||||||
|
|
||||||
// set prefers:
|
// set prefers:
|
||||||
v.Set(cfgApplicationName, misc.ApplicationName)
|
v.Set(cfgApplicationName, misc.ApplicationName)
|
||||||
|
|
|
@ -7,13 +7,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
s3auth "github.com/minio/minio/auth"
|
||||||
minio "github.com/minio/minio/legacy"
|
minio "github.com/minio/minio/legacy"
|
||||||
"github.com/minio/minio/legacy/config"
|
"github.com/minio/minio/legacy/config"
|
||||||
"github.com/minio/minio/neofs/layer"
|
"github.com/minio/minio/neofs/layer"
|
||||||
"github.com/minio/minio/neofs/pool"
|
"github.com/minio/minio/neofs/pool"
|
||||||
"github.com/minio/minio/pkg/auth"
|
"github.com/minio/minio/pkg/auth"
|
||||||
"github.com/nspcc-dev/neofs-api-go/refs"
|
|
||||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"google.golang.org/grpc/keepalive"
|
"google.golang.org/grpc/keepalive"
|
||||||
|
@ -21,6 +20,7 @@ import (
|
||||||
|
|
||||||
type (
|
type (
|
||||||
App struct {
|
App struct {
|
||||||
|
center *s3auth.Center
|
||||||
cli pool.Pool
|
cli pool.Pool
|
||||||
log *zap.Logger
|
log *zap.Logger
|
||||||
cfg *viper.Viper
|
cfg *viper.Viper
|
||||||
|
@ -45,20 +45,21 @@ type (
|
||||||
func newApp(l *zap.Logger, v *viper.Viper) *App {
|
func newApp(l *zap.Logger, v *viper.Viper) *App {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
wif string
|
|
||||||
cli pool.Pool
|
cli pool.Pool
|
||||||
tls *tlsConfig
|
tls *tlsConfig
|
||||||
uid refs.OwnerID
|
|
||||||
obj minio.ObjectLayer
|
obj minio.ObjectLayer
|
||||||
|
|
||||||
key = fetchKey(l, v)
|
|
||||||
|
|
||||||
reBalance = defaultRebalanceTimer
|
reBalance = defaultRebalanceTimer
|
||||||
|
|
||||||
conTimeout = defaultConnectTimeout
|
conTimeout = defaultConnectTimeout
|
||||||
reqTimeout = defaultRequestTimeout
|
reqTimeout = defaultRequestTimeout
|
||||||
)
|
)
|
||||||
|
|
||||||
|
center, err := fetchAuthCenter(l, v)
|
||||||
|
if err != nil {
|
||||||
|
l.Fatal("failed to initialize auth center", zap.Error(err))
|
||||||
|
}
|
||||||
|
uid := center.GetOwnerID()
|
||||||
|
wif := center.GetWIFString()
|
||||||
|
|
||||||
if v.IsSet(cfgTLSKeyFile) && v.IsSet(cfgTLSCertFile) {
|
if v.IsSet(cfgTLSKeyFile) && v.IsSet(cfgTLSCertFile) {
|
||||||
tls = &tlsConfig{
|
tls = &tlsConfig{
|
||||||
KeyFile: v.GetString(cfgTLSKeyFile),
|
KeyFile: v.GetString(cfgTLSKeyFile),
|
||||||
|
@ -82,7 +83,7 @@ func newApp(l *zap.Logger, v *viper.Viper) *App {
|
||||||
Peers: fetchPeers(l, v),
|
Peers: fetchPeers(l, v),
|
||||||
|
|
||||||
Logger: l,
|
Logger: l,
|
||||||
PrivateKey: key,
|
PrivateKey: center.GetNeoFSKeyPrivateKey(),
|
||||||
|
|
||||||
GRPCLogger: gRPCLogger(l),
|
GRPCLogger: gRPCLogger(l),
|
||||||
GRPCVerbose: v.GetBool(cfgGRPCVerbose),
|
GRPCVerbose: v.GetBool(cfgGRPCVerbose),
|
||||||
|
@ -95,8 +96,7 @@ func newApp(l *zap.Logger, v *viper.Viper) *App {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cli, err = pool.New(poolConfig); err != nil {
|
if cli, err = pool.New(poolConfig); err != nil {
|
||||||
l.Fatal("could not prepare pool connections",
|
l.Fatal("could not prepare pool connections", zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // should establish connection with NeoFS Storage Nodes
|
{ // should establish connection with NeoFS Storage Nodes
|
||||||
|
@ -112,37 +112,22 @@ func newApp(l *zap.Logger, v *viper.Viper) *App {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // should prepare object layer
|
{ // should prepare object layer
|
||||||
if uid, err = refs.NewOwnerID(&key.PublicKey); err != nil {
|
|
||||||
l.Fatal("could not fetch OwnerID",
|
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
if wif, err = crypto.WIFEncode(key); err != nil {
|
|
||||||
l.Fatal("could not encode key to WIF",
|
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // Temporary solution, to resolve problems with MinIO GW access/secret keys:
|
{ // Temporary solution, to resolve problems with MinIO GW access/secret keys:
|
||||||
if err = os.Setenv(config.EnvAccessKey, uid.String()); err != nil {
|
if err = os.Setenv(config.EnvAccessKey, uid.String()); err != nil {
|
||||||
l.Fatal("could not set "+config.EnvAccessKey,
|
l.Fatal("could not set "+config.EnvAccessKey, zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
} else if err = os.Setenv(config.EnvSecretKey, wif); err != nil {
|
} else if err = os.Setenv(config.EnvSecretKey, wif); err != nil {
|
||||||
l.Fatal("could not set "+config.EnvSecretKey,
|
l.Fatal("could not set "+config.EnvSecretKey, zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
}
|
||||||
|
l.Info("used credentials", zap.String("AccessKey", uid.String()), zap.String("SecretKey", wif))
|
||||||
l.Info("used credentials",
|
|
||||||
zap.String("AccessKey", uid.String()),
|
|
||||||
zap.String("SecretKey", wif))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if obj, err = layer.NewLayer(cli, l, auth.Credentials{AccessKey: uid.String(), SecretKey: wif}); err != nil {
|
if obj, err = layer.NewLayer(cli, l, auth.Credentials{AccessKey: uid.String(), SecretKey: wif}); err != nil {
|
||||||
l.Fatal("could not prepare ObjectLayer",
|
l.Fatal("could not prepare ObjectLayer", zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &App{
|
return &App{
|
||||||
|
center: center,
|
||||||
cli: cli,
|
cli: cli,
|
||||||
log: l,
|
log: l,
|
||||||
cfg: v,
|
cfg: v,
|
||||||
|
|
Loading…
Reference in a new issue