forked from TrueCloudLab/frostfs-node
[#350] object/acl: Make best effort to classify request
Classifier looks at list of inner ring nodes and container nodes from current and previous epoch to classify request. Sometimes these checks might return error. Consider there is a request from unknown key and container's placement policy valid for current epoch and invalid for past epoch. Classifier tries to find if key belongs to container node from current epoch -- it is not. Then it tries to find if key belongs to container node from past epoch and it throws error, because placement policy is invalid for past epoch. This is a legit case and classifier should ignore such errors to provide best effort in matching. The only error classifier should return is an error when request does not contain public key to classify it. Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
6e8f5b9d63
commit
e252f93dbf
2 changed files with 13 additions and 3 deletions
|
@ -287,6 +287,7 @@ func initObjectService(c *cfg) {
|
|||
acl.New(
|
||||
acl.WithSenderClassifier(
|
||||
acl.NewSenderClassifier(
|
||||
c.log,
|
||||
c.cfgNetmap.wrapper,
|
||||
c.cfgNetmap.wrapper,
|
||||
),
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||
core "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -31,14 +32,16 @@ type (
|
|||
}
|
||||
|
||||
SenderClassifier struct {
|
||||
log *zap.Logger
|
||||
innerRing InnerRingFetcher
|
||||
netmap core.Source
|
||||
}
|
||||
)
|
||||
|
||||
// fixme: update classifier constructor
|
||||
func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier {
|
||||
func NewSenderClassifier(l *zap.Logger, ir InnerRingFetcher, nm core.Source) SenderClassifier {
|
||||
return SenderClassifier{
|
||||
log: l,
|
||||
innerRing: ir,
|
||||
netmap: nm,
|
||||
}
|
||||
|
@ -68,14 +71,20 @@ func (c SenderClassifier) Classify(
|
|||
|
||||
isInnerRingNode, err := c.isInnerRingKey(ownerKeyInBytes)
|
||||
if err != nil {
|
||||
return 0, false, nil, errors.Wrap(err, "can't check if request from inner ring")
|
||||
// do not throw error, try best case matching
|
||||
c.log.Debug("can't check if request from inner ring",
|
||||
zap.String("error", err.Error()))
|
||||
} else if isInnerRingNode {
|
||||
return acl.RoleSystem, true, ownerKeyInBytes, nil
|
||||
}
|
||||
|
||||
isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.ToV2().GetValue(), cnr)
|
||||
if err != nil {
|
||||
return 0, false, nil, errors.Wrap(err, "can't check if request from container node")
|
||||
// error might happen if request has `RoleOther` key and placement
|
||||
// is not possible for previous epoch, so
|
||||
// do not throw error, try best case matching
|
||||
c.log.Debug("can't check if request from container node",
|
||||
zap.String("error", err.Error()))
|
||||
} else if isContainerNode {
|
||||
return acl.RoleSystem, false, ownerKeyInBytes, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue