forked from TrueCloudLab/frostfs-node
If request has no tag, but request's public key is netmap node's key or one of allowed internal tag keys from config, then request must use internal IO tag. Change-Id: Iff93b626941a81b088d8999b3f2947f9501dcdf8 Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
108 lines
3.3 KiB
Go
108 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
|
|
qosconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/qos"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/qos"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
|
qosTagging "git.frostfs.info/TrueCloudLab/frostfs-qos/tagging"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type cfgQoSService struct {
|
|
netmapSource netmap.Source
|
|
logger *logger.Logger
|
|
allowedCriticalPubs [][]byte
|
|
allowedInternalPubs [][]byte
|
|
}
|
|
|
|
func initQoSService(c *cfg) {
|
|
criticalPubs := qosconfig.CriticalAuthorizedKeys(c.appCfg)
|
|
internalPubs := qosconfig.InternalAuthorizedKeys(c.appCfg)
|
|
rawCriticalPubs := make([][]byte, 0, len(criticalPubs))
|
|
rawInternalPubs := make([][]byte, 0, len(internalPubs))
|
|
for i := range criticalPubs {
|
|
rawCriticalPubs = append(rawCriticalPubs, criticalPubs[i].Bytes())
|
|
}
|
|
for i := range internalPubs {
|
|
rawInternalPubs = append(rawInternalPubs, internalPubs[i].Bytes())
|
|
}
|
|
|
|
c.cfgQoSService = cfgQoSService{
|
|
netmapSource: c.netMapSource,
|
|
logger: c.log,
|
|
allowedCriticalPubs: rawCriticalPubs,
|
|
allowedInternalPubs: rawInternalPubs,
|
|
}
|
|
}
|
|
|
|
func (s *cfgQoSService) AdjustIncomingTag(ctx context.Context, requestSignPublicKey []byte) context.Context {
|
|
rawTag, defined := qosTagging.IOTagFromContext(ctx)
|
|
if !defined {
|
|
if s.isInternalIOTagPublicKey(ctx, requestSignPublicKey) {
|
|
return qosTagging.ContextWithIOTag(ctx, qos.IOTagInternal.String())
|
|
}
|
|
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
|
}
|
|
ioTag, err := qos.FromRawString(rawTag)
|
|
if err != nil {
|
|
s.logger.Debug(ctx, logs.FailedToParseIncomingIOTag, zap.Error(err))
|
|
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
|
}
|
|
|
|
switch ioTag {
|
|
case qos.IOTagClient:
|
|
return ctx
|
|
case qos.IOTagCritical:
|
|
for _, pk := range s.allowedCriticalPubs {
|
|
if bytes.Equal(pk, requestSignPublicKey) {
|
|
return ctx
|
|
}
|
|
}
|
|
nm, err := s.netmapSource.GetNetMap(ctx, 0)
|
|
if err != nil {
|
|
s.logger.Debug(ctx, logs.FailedToGetNetmapToAdjustIOTag, zap.Error(err))
|
|
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
|
}
|
|
for _, node := range nm.Nodes() {
|
|
if bytes.Equal(node.PublicKey(), requestSignPublicKey) {
|
|
return ctx
|
|
}
|
|
}
|
|
s.logger.Debug(ctx, logs.FailedToValidateIncomingIOTag)
|
|
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
|
case qos.IOTagInternal:
|
|
if s.isInternalIOTagPublicKey(ctx, requestSignPublicKey) {
|
|
return ctx
|
|
}
|
|
s.logger.Debug(ctx, logs.FailedToValidateIncomingIOTag)
|
|
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
|
default:
|
|
s.logger.Debug(ctx, logs.NotSupportedIncomingIOTagReplacedWithClient, zap.Stringer("io_tag", ioTag))
|
|
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
|
}
|
|
}
|
|
|
|
func (s *cfgQoSService) isInternalIOTagPublicKey(ctx context.Context, publicKey []byte) bool {
|
|
for _, pk := range s.allowedInternalPubs {
|
|
if bytes.Equal(pk, publicKey) {
|
|
return true
|
|
}
|
|
}
|
|
nm, err := s.netmapSource.GetNetMap(ctx, 0)
|
|
if err != nil {
|
|
s.logger.Debug(ctx, logs.FailedToGetNetmapToAdjustIOTag, zap.Error(err))
|
|
return false
|
|
}
|
|
for _, node := range nm.Nodes() {
|
|
if bytes.Equal(node.PublicKey(), publicKey) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|