forked from TrueCloudLab/frostfs-node
[#1184] node: Add audit package
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
7b8937ec35
commit
ac1f014747
5 changed files with 208 additions and 1 deletions
2
go.mod
2
go.mod
|
@ -6,6 +6,7 @@ require (
|
||||||
code.gitea.io/sdk/gitea v0.17.1
|
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-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-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-observability v0.0.0-20231101111734-b3ad3335ff65
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240617140730-1a5886e776de
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240617140730-1a5886e776de
|
||||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1
|
git.frostfs.info/TrueCloudLab/hrw v1.2.1
|
||||||
|
@ -54,7 +55,6 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 // indirect
|
|
||||||
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 // indirect
|
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 // indirect
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
|
7
internal/audit/consts.go
Normal file
7
internal/audit/consts.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package audit
|
||||||
|
|
||||||
|
const (
|
||||||
|
InvalidValue = "invalid_value"
|
||||||
|
NotDefined = "not_defined"
|
||||||
|
Empty = "empty"
|
||||||
|
)
|
41
internal/audit/request.go
Normal file
41
internal/audit/request.go
Normal 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
158
internal/audit/target.go
Normal 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}
|
||||||
|
}
|
|
@ -539,4 +539,5 @@ const (
|
||||||
PolicerFailedToRestoreObject = "failed to restore EC object"
|
PolicerFailedToRestoreObject = "failed to restore EC object"
|
||||||
PolicerCouldNotGetChunk = "could not get EC chunk"
|
PolicerCouldNotGetChunk = "could not get EC chunk"
|
||||||
PolicerCouldNotGetChunks = "could not get EC chunks"
|
PolicerCouldNotGetChunks = "could not get EC chunks"
|
||||||
|
AuditEventLogRecord = "audit event log record"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue