[#1184] node: Add audit package

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2024-06-18 12:38:39 +03:00
parent 7b8937ec35
commit ac1f014747
5 changed files with 208 additions and 1 deletions

2
go.mod
View file

@ -6,6 +6,7 @@ require (
code.gitea.io/sdk/gitea v0.17.1
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240530152826-2f6d3209e1d3
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409111539-e7a05a49ff45
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20231101111734-b3ad3335ff65
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240617140730-1a5886e776de
git.frostfs.info/TrueCloudLab/hrw v1.2.1
@ -54,7 +55,6 @@ require (
)
require (
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 // indirect
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect

7
internal/audit/consts.go Normal file
View file

@ -0,0 +1,7 @@
package audit
const (
InvalidValue = "invalid_value"
NotDefined = "not_defined"
Empty = "empty"
)

41
internal/audit/request.go Normal file
View file

@ -0,0 +1,41 @@
package audit
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
crypto "git.frostfs.info/TrueCloudLab/frostfs-crypto"
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"go.uber.org/zap"
)
type Request interface {
GetVerificationHeader() *session.RequestVerificationHeader
}
type Target interface {
String() string
}
func LogRequest(log *logger.Logger, operation string, req Request, target Target, status bool) {
LogRequestWithKey(log, operation, req.GetVerificationHeader().GetBodySignature().GetKey(), target, status)
}
func LogRequestWithKey(log *logger.Logger, operation string, key []byte, target Target, status bool) {
object, subject := NotDefined, NotDefined
publicKey := crypto.UnmarshalPublicKey(key)
if publicKey != nil {
subject = ((*keys.PublicKey)(publicKey)).StringCompressed()
}
if target != nil {
object = target.String()
}
log.Info(logs.AuditEventLogRecord,
zap.String("operation", operation),
zap.String("object", object),
zap.String("subject", subject),
zap.Bool("success", status))
}

158
internal/audit/target.go Normal file
View file

@ -0,0 +1,158 @@
package audit
import (
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
"github.com/mr-tron/base58"
)
type ModelType[T any] interface {
ReadFromV2(m T) error
String() string
}
func TargetFromRef[T any](ref *T, model ModelType[T]) Target {
if ref == nil {
return stringTarget{s: NotDefined}
}
if err := model.ReadFromV2(*ref); err != nil {
return stringTarget{s: InvalidValue}
}
return stringTarget{s: model.String()}
}
func TargetFromRefs[T any](refs []*T, model ModelType[T]) Target {
if len(refs) == 0 {
return stringTarget{s: NotDefined}
}
sb := &strings.Builder{}
for idx, ref := range refs {
if idx > 0 {
sb.WriteString(";")
}
if ref == nil {
sb.WriteString(Empty)
continue
}
if err := model.ReadFromV2(*ref); err != nil {
sb.WriteString(InvalidValue)
} else {
sb.WriteString(model.String())
}
}
return sb
}
type stringTarget struct {
s string
}
func (t stringTarget) String() string {
return t.s
}
func TargetFromString(s string) Target {
if len(s) == 0 {
s = Empty
}
return stringTarget{s: s}
}
func TargetFromStringSlice(s []string) Target {
if len(s) == 0 {
return stringTarget{s: NotDefined}
}
sb := &strings.Builder{}
for i, v := range s {
if i > 0 {
sb.WriteString(";")
}
if len(v) == 0 {
sb.WriteString(Empty)
} else {
sb.WriteString(v)
}
}
return sb
}
func TargetFromChainID(chainTargetType, chainTargetName string, chainID []byte) Target {
if len(chainTargetType) == 0 && len(chainTargetName) == 0 && len(chainID) == 0 {
return stringTarget{s: NotDefined}
}
t, n, c := Empty, Empty, Empty
if len(chainTargetType) > 0 {
t = chainTargetType
}
if len(chainTargetName) > 0 {
n = chainTargetName
}
if len(chainID) > 0 {
c = string(chainID)
}
return stringTarget{s: t + ":" + n + ":" + c}
}
func TargetFromShardIDs(v [][]byte) Target {
if len(v) == 0 {
return stringTarget{s: NotDefined}
}
sb := &strings.Builder{}
for i, s := range v {
if i > 0 {
sb.WriteString(";")
}
if len(s) == 0 {
sb.WriteString(Empty)
} else {
sb.WriteString(base58.Encode(s))
}
}
return sb
}
func TargetFromTreeID(containerID []byte, treeID string) Target {
if len(containerID) == 0 && len(treeID) == 0 {
return stringTarget{s: NotDefined}
}
c, t := Empty, Empty
if len(containerID) > 0 {
var cnr cid.ID
if err := cnr.Decode(containerID); err != nil {
c = InvalidValue
} else {
c = cnr.EncodeToString()
}
}
if len(treeID) > 0 {
t = treeID
}
return stringTarget{s: c + ":" + t}
}
func TargetFromContainerIDObjectID(containerID *refs.ContainerID, objectID *refs.ObjectID) Target {
if containerID == nil && objectID == nil {
return stringTarget{s: NotDefined}
}
c, o := Empty, Empty
if containerID != nil {
var cnr cid.ID
if err := cnr.ReadFromV2(*containerID); err != nil {
c = InvalidValue
} else {
c = cnr.EncodeToString()
}
}
if objectID != nil {
var obj oid.ID
if err := obj.ReadFromV2(*objectID); err != nil {
o = InvalidValue
} else {
o = obj.EncodeToString()
}
}
return stringTarget{s: c + "/" + o}
}

View file

@ -539,4 +539,5 @@ const (
PolicerFailedToRestoreObject = "failed to restore EC object"
PolicerCouldNotGetChunk = "could not get EC chunk"
PolicerCouldNotGetChunks = "could not get EC chunks"
AuditEventLogRecord = "audit event log record"
)