[#305] Support checking if accessbox was removed

Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
Denis Kirillov 2024-02-06 16:44:49 +03:00
parent 5121c73d3f
commit 924e87face
13 changed files with 256 additions and 44 deletions

View file

@ -30,6 +30,7 @@ This document outlines major changes between releases.
- Set server IdleTimeout and ReadHeaderTimeout to `30s` and allow to configure them (#220) - Set server IdleTimeout and ReadHeaderTimeout to `30s` and allow to configure them (#220)
- Return `ETag` value in quotes (#219) - Return `ETag` value in quotes (#219)
- Use tombstone when delete multipart upload (#275) - Use tombstone when delete multipart upload (#275)
- Support new parameter `cache.accessbox.removing_check_interval` (#XX)
### Removed ### Removed
- Drop sending whitespace characters during complete multipart upload and related config param `kludge.complete_multipart_keepalive` (#227) - Drop sending whitespace characters during complete multipart upload and related config param `kludge.complete_multipart_keepalive` (#227)

View file

@ -14,14 +14,12 @@ import (
"time" "time"
v4 "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4" v4 "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache"
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
) )
// authorizationFieldRegexp -- is regexp for credentials with Base58 encoded cid and oid and '0' (zero) as delimiter. // authorizationFieldRegexp -- is regexp for credentials with Base58 encoded cid and oid and '0' (zero) as delimiter.
@ -84,9 +82,9 @@ var ContentSHA256HeaderStandardValue = map[string]struct{}{
} }
// New creates an instance of AuthCenter. // New creates an instance of AuthCenter.
func New(frostFS tokens.FrostFS, key *keys.PrivateKey, prefixes []string, config *cache.Config) *Center { func New(creds tokens.Credentials, prefixes []string) *Center {
return &Center{ return &Center{
cli: tokens.New(frostFS, key, config), cli: creds,
reg: NewRegexpMatcher(authorizationFieldRegexp), reg: NewRegexpMatcher(authorizationFieldRegexp),
postReg: NewRegexpMatcher(postPolicyCredentialRegexp), postReg: NewRegexpMatcher(postPolicyCredentialRegexp),
allowedAccessKeyIDPrefixes: prefixes, allowedAccessKeyIDPrefixes: prefixes,

View file

@ -24,6 +24,11 @@ type (
Lifetime time.Duration Lifetime time.Duration
Logger *zap.Logger Logger *zap.Logger
} }
AccessBoxCacheValue struct {
Box *accessbox.Box
PutTime time.Time
}
) )
const ( const (
@ -42,21 +47,21 @@ func DefaultAccessBoxConfig(logger *zap.Logger) *Config {
} }
} }
// NewAccessBoxCache creates an object of BucketCache. // NewAccessBoxCache creates an object of AccessBoxCache.
func NewAccessBoxCache(config *Config) *AccessBoxCache { func NewAccessBoxCache(config *Config) *AccessBoxCache {
gc := gcache.New(config.Size).LRU().Expiration(config.Lifetime).Build() gc := gcache.New(config.Size).LRU().Expiration(config.Lifetime).Build()
return &AccessBoxCache{cache: gc, logger: config.Logger} return &AccessBoxCache{cache: gc, logger: config.Logger}
} }
// Get returns a cached object. // Get returns a cached accessbox.
func (o *AccessBoxCache) Get(address oid.Address) *accessbox.Box { func (o *AccessBoxCache) Get(address oid.Address) *AccessBoxCacheValue {
entry, err := o.cache.Get(address) entry, err := o.cache.Get(address)
if err != nil { if err != nil {
return nil return nil
} }
result, ok := entry.(*accessbox.Box) result, ok := entry.(*AccessBoxCacheValue)
if !ok { if !ok {
o.logger.Warn(logs.InvalidCacheEntryType, zap.String("actual", fmt.Sprintf("%T", entry)), o.logger.Warn(logs.InvalidCacheEntryType, zap.String("actual", fmt.Sprintf("%T", entry)),
zap.String("expected", fmt.Sprintf("%T", result))) zap.String("expected", fmt.Sprintf("%T", result)))
@ -66,7 +71,16 @@ func (o *AccessBoxCache) Get(address oid.Address) *accessbox.Box {
return result return result
} }
// Put stores an object to cache. // Put stores an accessbox to cache.
func (o *AccessBoxCache) Put(address oid.Address, box *accessbox.Box) error { func (o *AccessBoxCache) Put(address oid.Address, box *accessbox.Box) error {
return o.cache.Set(address, box) val := &AccessBoxCacheValue{
Box: box,
PutTime: time.Now(),
}
return o.cache.Set(address, val)
}
// Delete removes an accessbox from cache.
func (o *AccessBoxCache) Delete(address oid.Address) {
o.cache.Remove(address)
} }

View file

@ -22,7 +22,7 @@ func TestAccessBoxCacheType(t *testing.T) {
err := cache.Put(addr, box) err := cache.Put(addr, box)
require.NoError(t, err) require.NoError(t, err)
val := cache.Get(addr) val := cache.Get(addr)
require.Equal(t, box, val) require.Equal(t, box, val.Box)
require.Equal(t, 0, observedLog.Len()) require.Equal(t, 0, observedLog.Len())
err = cache.cache.Set(addr, "tmp") err = cache.cache.Set(addr, "tmp")

View file

@ -279,7 +279,13 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
a.log.Info(logs.StoreBearerTokenIntoFrostFS, a.log.Info(logs.StoreBearerTokenIntoFrostFS,
zap.Stringer("owner_tkn", idOwner)) zap.Stringer("owner_tkn", idOwner))
creds := tokens.New(a.frostFS, secrets.EphemeralKey, cache.DefaultAccessBoxConfig(a.log)) cfg := tokens.Config{
FrostFS: a.frostFS,
Key: secrets.EphemeralKey,
CacheConfig: cache.DefaultAccessBoxConfig(a.log),
}
creds := tokens.New(cfg)
prm := tokens.CredentialsParam{ prm := tokens.CredentialsParam{
OwnerID: idOwner, OwnerID: idOwner,
@ -330,7 +336,13 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
// UpdateSecret updates an auth token (change list of gates that can use credential), puts new cred version to the FrostFS network and writes to io.Writer a result. // UpdateSecret updates an auth token (change list of gates that can use credential), puts new cred version to the FrostFS network and writes to io.Writer a result.
func (a *Agent) UpdateSecret(ctx context.Context, w io.Writer, options *UpdateSecretOptions) error { func (a *Agent) UpdateSecret(ctx context.Context, w io.Writer, options *UpdateSecretOptions) error {
creds := tokens.New(a.frostFS, options.GatePrivateKey, cache.DefaultAccessBoxConfig(a.log)) cfg := tokens.Config{
FrostFS: a.frostFS,
Key: options.GatePrivateKey,
CacheConfig: cache.DefaultAccessBoxConfig(a.log),
}
creds := tokens.New(cfg)
box, err := creds.GetBox(ctx, options.Address) box, err := creds.GetBox(ctx, options.Address)
if err != nil { if err != nil {
@ -406,7 +418,13 @@ func getLifetimeFromGateData(gateData *accessbox.GateData) lifetimeOptions {
// ObtainSecret receives an existing secret access key from FrostFS and // ObtainSecret receives an existing secret access key from FrostFS and
// writes to io.Writer the secret access key. // writes to io.Writer the secret access key.
func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSecretOptions) error { func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSecretOptions) error {
bearerCreds := tokens.New(a.frostFS, options.GatePrivateKey, cache.DefaultAccessBoxConfig(a.log)) cfg := tokens.Config{
FrostFS: a.frostFS,
Key: options.GatePrivateKey,
CacheConfig: cache.DefaultAccessBoxConfig(a.log),
}
bearerCreds := tokens.New(cfg)
var addr oid.Address var addr oid.Address
if err := addr.DecodeString(options.SecretAddress); err != nil { if err := addr.DecodeString(options.SecretAddress); err != nil {

View file

@ -27,6 +27,7 @@ import (
s3middleware "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" s3middleware "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/notifications" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/notifications"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/resolver" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/resolver"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/frostfsid" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/frostfsid"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy"
@ -119,8 +120,15 @@ type (
func newApp(ctx context.Context, log *Logger, v *viper.Viper) *App { func newApp(ctx context.Context, log *Logger, v *viper.Viper) *App {
objPool, treePool, key := getPools(ctx, log.logger, v) objPool, treePool, key := getPools(ctx, log.logger, v)
cfg := tokens.Config{
FrostFS: frostfs.NewAuthmateFrostFS(objPool, key),
Key: key,
CacheConfig: getAccessBoxCacheConfig(v, log.logger),
RemovingCheckAfterDurations: fetchRemovingCheckInterval(v, log.logger),
}
// prepare auth center // prepare auth center
ctr := auth.New(frostfs.NewAuthmateFrostFS(objPool, key), key, v.GetStringSlice(cfgAllowedAccessKeyIDPrefixes), getAccessBoxCacheConfig(v, log.logger)) ctr := auth.New(tokens.New(cfg), v.GetStringSlice(cfgAllowedAccessKeyIDPrefixes))
app := &App{ app := &App{
ctr: ctr, ctr: ctr,

View file

@ -52,6 +52,8 @@ const (
defaultReadHeaderTimeout = 30 * time.Second defaultReadHeaderTimeout = 30 * time.Second
defaultIdleTimeout = 30 * time.Second defaultIdleTimeout = 30 * time.Second
defaultAccessBoxCacheRemovingCheckInterval = 5 * time.Minute
defaultNamespaceHeader = "X-Frostfs-Namespace" defaultNamespaceHeader = "X-Frostfs-Namespace"
defaultConstraintName = "default" defaultConstraintName = "default"
@ -113,6 +115,8 @@ const ( // Settings.
cfgMorphPolicyCacheLifetime = "cache.morph_policy.lifetime" cfgMorphPolicyCacheLifetime = "cache.morph_policy.lifetime"
cfgMorphPolicyCacheSize = "cache.morph_policy.size" cfgMorphPolicyCacheSize = "cache.morph_policy.size"
cfgAccessBoxCacheRemovingCheckInterval = "cache.accessbox.removing_check_interval"
// NATS. // NATS.
cfgEnableNATS = "nats.enabled" cfgEnableNATS = "nats.enabled"
cfgNATSEndpoint = "nats.endpoint" cfgNATSEndpoint = "nats.endpoint"
@ -368,6 +372,24 @@ func fetchCacheSize(v *viper.Viper, l *zap.Logger, cfgEntry string, defaultValue
return defaultValue return defaultValue
} }
func fetchRemovingCheckInterval(v *viper.Viper, l *zap.Logger) time.Duration {
if !v.IsSet(cfgAccessBoxCacheRemovingCheckInterval) {
return defaultAccessBoxCacheRemovingCheckInterval
}
duration := v.GetDuration(cfgAccessBoxCacheRemovingCheckInterval)
if duration >= 0 {
return duration
}
l.Error(logs.InvalidAccessBoxCacheRemovingCheckInterval,
zap.String("parameter", cfgAccessBoxCacheRemovingCheckInterval),
zap.Duration("value in config", duration),
zap.Duration("default", defaultAccessBoxCacheRemovingCheckInterval))
return defaultAccessBoxCacheRemovingCheckInterval
}
func fetchDefaultMaxAge(cfg *viper.Viper, l *zap.Logger) int { func fetchDefaultMaxAge(cfg *viper.Viper, l *zap.Logger) int {
defaultMaxAge := handler.DefaultMaxAge defaultMaxAge := handler.DefaultMaxAge
@ -675,6 +697,8 @@ func newSettings() *viper.Viper {
// set defaults: // set defaults:
v.SetDefault(cfgAccessBoxCacheRemovingCheckInterval, defaultAccessBoxCacheRemovingCheckInterval)
// logger: // logger:
v.SetDefault(cfgLoggerLevel, "debug") v.SetDefault(cfgLoggerLevel, "debug")
v.SetDefault(cfgLoggerDestination, "stdout") v.SetDefault(cfgLoggerDestination, "stdout")

View file

@ -95,6 +95,7 @@ S3_GW_CACHE_NAMES_SIZE=10000
S3_GW_CACHE_SYSTEM_LIFETIME=5m S3_GW_CACHE_SYSTEM_LIFETIME=5m
S3_GW_CACHE_SYSTEM_SIZE=100000 S3_GW_CACHE_SYSTEM_SIZE=100000
# Cache which stores access box with tokens by its address # Cache which stores access box with tokens by its address
S3_GW_CACHE_ACCESSBOX_REMOVING_CHECK_INTERVAL=5m
S3_GW_CACHE_ACCESSBOX_LIFETIME=10m S3_GW_CACHE_ACCESSBOX_LIFETIME=10m
S3_GW_CACHE_ACCESSBOX_SIZE=100 S3_GW_CACHE_ACCESSBOX_SIZE=100
# Cache which stores owner to cache operation mapping # Cache which stores owner to cache operation mapping

View file

@ -118,8 +118,9 @@ cache:
size: 1000 size: 1000
# Cache which stores access box with tokens by its address # Cache which stores access box with tokens by its address
accessbox: accessbox:
lifetime: 5m removing_check_interval: 5m
size: 10 lifetime: 10m
size: 100
# Cache which stores owner to cache operation mapping # Cache which stores owner to cache operation mapping
accesscontrol: accesscontrol:
lifetime: 1m lifetime: 1m

View file

@ -9,11 +9,14 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"go.uber.org/zap"
) )
type ( type (
@ -33,9 +36,18 @@ type (
} }
cred struct { cred struct {
key *keys.PrivateKey key *keys.PrivateKey
frostFS FrostFS frostFS FrostFS
cache *cache.AccessBoxCache cache *cache.AccessBoxCache
removingCheckDuration time.Duration
log *zap.Logger
}
Config struct {
FrostFS FrostFS
Key *keys.PrivateKey
CacheConfig *cache.Config
RemovingCheckAfterDurations time.Duration
} }
) )
@ -90,17 +102,40 @@ var (
ErrEmptyBearerToken = errors.New("Bearer token could not be empty") ErrEmptyBearerToken = errors.New("Bearer token could not be empty")
) )
var _ = New var _ Credentials = (*cred)(nil)
// New creates a new Credentials instance using the given cli and key. // New creates a new Credentials instance using the given cli and key.
func New(frostFS FrostFS, key *keys.PrivateKey, config *cache.Config) Credentials { func New(cfg Config) Credentials {
return &cred{frostFS: frostFS, key: key, cache: cache.NewAccessBoxCache(config)} return &cred{
frostFS: cfg.FrostFS,
key: cfg.Key,
cache: cache.NewAccessBoxCache(cfg.CacheConfig),
removingCheckDuration: cfg.RemovingCheckAfterDurations,
log: cfg.CacheConfig.Logger,
}
} }
func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, error) { func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, error) {
cachedBox := c.cache.Get(addr) cachedBoxValue := c.cache.Get(addr)
if cachedBox != nil { if cachedBoxValue != nil {
return cachedBox, nil if time.Since(cachedBoxValue.PutTime) > c.removingCheckDuration {
if box, err := c.getAccessBox(ctx, addr); err != nil {
if client.IsErrObjectAlreadyRemoved(err) {
c.cache.Delete(addr)
return nil, fmt.Errorf("get access box: %w", err)
}
} else {
cachedBox, err := box.GetBox(c.key)
if err != nil {
c.cache.Delete(addr)
return nil, fmt.Errorf("get gate box: %w", err)
}
// we need this to reset PutTime
// to don't check for removing each time after removingCheckDuration interval
c.putBoxToCache(addr, cachedBox)
}
}
return cachedBoxValue.Box, nil
} }
box, err := c.getAccessBox(ctx, addr) box, err := c.getAccessBox(ctx, addr)
@ -108,18 +143,22 @@ func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, er
return nil, fmt.Errorf("get access box: %w", err) return nil, fmt.Errorf("get access box: %w", err)
} }
cachedBox, err = box.GetBox(c.key) cachedBox, err := box.GetBox(c.key)
if err != nil { if err != nil {
return nil, fmt.Errorf("get box: %w", err) return nil, fmt.Errorf("get gate box: %w", err)
} }
if err = c.cache.Put(addr, cachedBox); err != nil { c.putBoxToCache(addr, cachedBox)
return nil, fmt.Errorf("put box into cache: %w", err)
}
return cachedBox, nil return cachedBox, nil
} }
func (c *cred) putBoxToCache(addr oid.Address, box *accessbox.Box) {
if err := c.cache.Put(addr, box); err != nil {
c.log.Warn(logs.CouldntPutAccessBoxIntoCache, zap.String("address", addr.EncodeToString()))
}
}
func (c *cred) getAccessBox(ctx context.Context, addr oid.Address) (*accessbox.AccessBox, error) { func (c *cred) getAccessBox(ctx context.Context, addr oid.Address) (*accessbox.AccessBox, error) {
data, err := c.frostFS.GetCredsPayload(ctx, addr) data, err := c.frostFS.GetCredsPayload(ctx, addr)
if err != nil { if err != nil {

View file

@ -0,0 +1,91 @@
package tokens
import (
"context"
"encoding/hex"
"errors"
"testing"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
)
type frostfsMock struct {
objects map[oid.Address][]byte
errors map[oid.Address]error
}
func (f *frostfsMock) CreateObject(context.Context, PrmObjectCreate) (oid.ID, error) {
panic("implement me for test")
}
func (f *frostfsMock) GetCredsPayload(_ context.Context, address oid.Address) ([]byte, error) {
if err := f.errors[address]; err != nil {
return nil, err
}
data, ok := f.objects[address]
if !ok {
return nil, errors.New("not found")
}
return data, nil
}
func TestRemovingAccessBox(t *testing.T) {
ctx := context.Background()
key, err := keys.NewPrivateKey()
require.NoError(t, err)
gateData := []*accessbox.GateData{{
BearerToken: &bearer.Token{},
GateKey: key.PublicKey(),
}}
secretKey := "713d0a0b9efc7d22923e17b0402a6a89b4273bc711c8bacb2da1b643d0006aeb"
sk, err := hex.DecodeString(secretKey)
require.NoError(t, err)
accessBox, _, err := accessbox.PackTokens(gateData, sk)
require.NoError(t, err)
data, err := accessBox.Marshal()
require.NoError(t, err)
addr := oidtest.Address()
frostfs := &frostfsMock{
objects: map[oid.Address][]byte{addr: data},
errors: map[oid.Address]error{},
}
cfg := Config{
FrostFS: frostfs,
Key: key,
CacheConfig: &cache.Config{
Size: 10,
Lifetime: 24 * time.Hour,
Logger: zaptest.NewLogger(t),
},
RemovingCheckAfterDurations: 0, // means check always
}
creds := New(cfg)
_, err = creds.GetBox(ctx, addr)
require.NoError(t, err)
frostfs.errors[addr] = errors.New("network error")
_, err = creds.GetBox(ctx, addr)
require.NoError(t, err)
frostfs.errors[addr] = &apistatus.ObjectAlreadyRemoved{}
_, err = creds.GetBox(ctx, addr)
require.Error(t, err)
}

View file

@ -409,8 +409,9 @@ cache:
lifetime: 2m lifetime: 2m
size: 1000 size: 1000
accessbox: accessbox:
lifetime: 5m removing_check_interval: 5m
size: 10 lifetime: 10m
size: 100
accesscontrol: accesscontrol:
lifetime: 1m lifetime: 1m
size: 100000 size: 100000
@ -419,17 +420,17 @@ cache:
size: 10000 size: 10000
``` ```
| Parameter | Type | Default value | Description | | Parameter | Type | Default value | Description |
|-----------------|-----------------------------------|-----------------------------------|----------------------------------------------------------------------------------------| |-----------------|-------------------------------------------------|-----------------------------------|----------------------------------------------------------------------------------------|
| `objects` | [Cache config](#cache-subsection) | `lifetime: 5m`<br>`size: 1000000` | Cache for objects (FrostFS headers). | | `objects` | [Cache config](#cache-subsection) | `lifetime: 5m`<br>`size: 1000000` | Cache for objects (FrostFS headers). |
| `list` | [Cache config](#cache-subsection) | `lifetime: 60s`<br>`size: 100000` | Cache which keeps lists of objects in buckets. | | `list` | [Cache config](#cache-subsection) | `lifetime: 60s`<br>`size: 100000` | Cache which keeps lists of objects in buckets. |
| `list_session` | [Cache config](#cache-subsection) | `lifetime: 60s`<br>`size: 100` | Cache which keeps listing session. | | `list_session` | [Cache config](#cache-subsection) | `lifetime: 60s`<br>`size: 100` | Cache which keeps listing session. |
| `names` | [Cache config](#cache-subsection) | `lifetime: 60s`<br>`size: 10000` | Cache which contains mapping of nice name to object addresses. | | `names` | [Cache config](#cache-subsection) | `lifetime: 60s`<br>`size: 10000` | Cache which contains mapping of nice name to object addresses. |
| `buckets` | [Cache config](#cache-subsection) | `lifetime: 60s`<br>`size: 1000` | Cache which contains mapping of bucket name to bucket info. | | `buckets` | [Cache config](#cache-subsection) | `lifetime: 60s`<br>`size: 1000` | Cache which contains mapping of bucket name to bucket info. |
| `system` | [Cache config](#cache-subsection) | `lifetime: 5m`<br>`size: 10000` | Cache for system objects in a bucket: bucket settings, notification configuration etc. | | `system` | [Cache config](#cache-subsection) | `lifetime: 5m`<br>`size: 10000` | Cache for system objects in a bucket: bucket settings, notification configuration etc. |
| `accessbox` | [Cache config](#cache-subsection) | `lifetime: 10m`<br>`size: 100` | Cache which stores access box with tokens by its address. | | `accessbox` | [Accessbox cache config](#accessbox-subsection) | `lifetime: 10m`<br>`size: 100` | Cache which stores access box with tokens by its address. |
| `accesscontrol` | [Cache config](#cache-subsection) | `lifetime: 1m`<br>`size: 100000` | Cache which stores owner to cache operation mapping. | | `accesscontrol` | [Cache config](#cache-subsection) | `lifetime: 1m`<br>`size: 100000` | Cache which stores owner to cache operation mapping. |
| `morph_policy` | [Cache config](#cache-subsection) | `lifetime: 1m`<br>`size: 10000` | Cache which stores list of policy chains. | | `morph_policy` | [Cache config](#cache-subsection) | `lifetime: 1m`<br>`size: 10000` | Cache which stores list of policy chains. |
#### `cache` subsection #### `cache` subsection
@ -443,6 +444,20 @@ size: 1000
| `lifetime` | `duration` | depends on cache | Lifetime of entries in cache. | | `lifetime` | `duration` | depends on cache | Lifetime of entries in cache. |
| `size` | `int` | depends on cache | LRU cache size. | | `size` | `int` | depends on cache | LRU cache size. |
#### `accessbox` subsection
```yaml
lifetime: 10m
size: 100
```
| Parameter | Type | Default value | Description |
|---------------------------|------------|---------------|-------------------------------------------------------|
| `removing_check_interval` | `duration` | `5m' | Time after which creds should be checked for removal. |
| `lifetime` | `duration` | '10m' | Lifetime of entries in cache. |
| `size` | `int` | '100 | LRU cache size. |
### `nats` section ### `nats` section
This is an advanced section, use with caution. This is an advanced section, use with caution.

View file

@ -139,4 +139,6 @@ const (
ParseTreeNode = "parse tree node" ParseTreeNode = "parse tree node"
FailedToGetRealObjectSize = "failed to get real object size" FailedToGetRealObjectSize = "failed to get real object size"
CouldntDeleteObjectFromStorageContinueDeleting = "couldn't delete object from storage, continue deleting from tree" CouldntDeleteObjectFromStorageContinueDeleting = "couldn't delete object from storage, continue deleting from tree"
CouldntPutAccessBoxIntoCache = "couldn't put accessbox into cache"
InvalidAccessBoxCacheRemovingCheckInterval = "invalid accessbox check removing interval, using default value"
) )