forked from TrueCloudLab/frostfs-node
[#872] object: Introduce APE middlewar for object service
Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>
This commit is contained in:
parent
e43609c616
commit
c8baf76fae
13 changed files with 1456 additions and 175 deletions
159
pkg/services/object/ape/request.go
Normal file
159
pkg/services/object/ape/request.go
Normal file
|
@ -0,0 +1,159 @@
|
|||
package ape
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
aperesource "git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource"
|
||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||
)
|
||||
|
||||
type request struct {
|
||||
operation string
|
||||
resource *resource
|
||||
properties map[string]string
|
||||
}
|
||||
|
||||
var _ aperesource.Request = (*request)(nil)
|
||||
|
||||
type resource struct {
|
||||
name string
|
||||
properties map[string]string
|
||||
}
|
||||
|
||||
var _ aperesource.Resource = (*resource)(nil)
|
||||
|
||||
func (r *resource) Name() string {
|
||||
return r.name
|
||||
}
|
||||
|
||||
func (r *resource) Property(key string) string {
|
||||
return r.properties[key]
|
||||
}
|
||||
|
||||
func (r *request) Operation() string {
|
||||
return r.operation
|
||||
}
|
||||
|
||||
func (r *request) Property(key string) string {
|
||||
return r.properties[key]
|
||||
}
|
||||
|
||||
func (r *request) Resource() aperesource.Resource {
|
||||
return r.resource
|
||||
}
|
||||
|
||||
func nativeSchemaRole(role acl.Role) string {
|
||||
switch role {
|
||||
case acl.RoleOwner:
|
||||
return nativeschema.PropertyValueContainerRoleOwner
|
||||
case acl.RoleContainer:
|
||||
return nativeschema.PropertyValueContainerRoleContainer
|
||||
case acl.RoleInnerRing:
|
||||
return nativeschema.PropertyValueContainerRoleIR
|
||||
case acl.RoleOthers:
|
||||
return nativeschema.PropertyValueContainerRoleOthers
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func resourceName(cid cid.ID, oid *oid.ID, namespace string) string {
|
||||
if namespace == "root" || namespace == "" {
|
||||
if oid != nil {
|
||||
return fmt.Sprintf(nativeschema.ResourceFormatRootContainerObject, cid.EncodeToString(), oid.EncodeToString())
|
||||
}
|
||||
return fmt.Sprintf(nativeschema.ResourceFormatRootContainerObjects, cid.EncodeToString())
|
||||
}
|
||||
if oid != nil {
|
||||
return fmt.Sprintf(nativeschema.ResourceFormatNamespaceContainerObject, namespace, cid.EncodeToString(), oid.EncodeToString())
|
||||
}
|
||||
return fmt.Sprintf(nativeschema.ResourceFormatNamespaceContainerObjects, namespace, cid.EncodeToString())
|
||||
}
|
||||
|
||||
// objectProperties collects object properties from address parameters and a header if it is passed.
|
||||
func objectProperties(cnr cid.ID, oid *oid.ID, header *objectV2.Header) map[string]string {
|
||||
objectProps := map[string]string{
|
||||
nativeschema.PropertyKeyObjectContainerID: cnr.EncodeToString(),
|
||||
}
|
||||
|
||||
if oid != nil {
|
||||
objectProps[nativeschema.PropertyKeyObjectID] = oid.String()
|
||||
}
|
||||
|
||||
if header == nil {
|
||||
return objectProps
|
||||
}
|
||||
|
||||
objV2 := new(objectV2.Object)
|
||||
objV2.SetHeader(header)
|
||||
objSDK := objectSDK.NewFromV2(objV2)
|
||||
|
||||
objectProps[nativeschema.PropertyKeyObjectVersion] = objSDK.Version().String()
|
||||
objectProps[nativeschema.PropertyKeyObjectOwnerID] = objSDK.OwnerID().EncodeToString()
|
||||
objectProps[nativeschema.PropertyKeyObjectCreationEpoch] = strconv.Itoa(int(objSDK.CreationEpoch()))
|
||||
objectProps[nativeschema.PropertyKeyObjectPayloadLength] = strconv.Itoa(int(objSDK.PayloadSize()))
|
||||
objectProps[nativeschema.PropertyKeyObjectType] = objSDK.Type().String()
|
||||
|
||||
pcs, isSet := objSDK.PayloadChecksum()
|
||||
if isSet {
|
||||
objectProps[nativeschema.PropertyKeyObjectPayloadHash] = pcs.String()
|
||||
}
|
||||
hcs, isSet := objSDK.PayloadHomomorphicHash()
|
||||
if isSet {
|
||||
objectProps[nativeschema.PropertyKeyObjectHomomorphicHash] = hcs.String()
|
||||
}
|
||||
|
||||
for _, attr := range header.GetAttributes() {
|
||||
objectProps[attr.GetKey()] = attr.GetValue()
|
||||
}
|
||||
|
||||
return objectProps
|
||||
}
|
||||
|
||||
// newAPERequest creates an APE request to be passed to a chain router. It collects resource properties from
|
||||
// header provided by headerProvider. If it cannot be found in headerProvider, then properties are
|
||||
// initialized from header given in prm (if it is set). Otherwise, just CID and OID are set to properties.
|
||||
func (c *checkerImpl) newAPERequest(ctx context.Context, prm Prm) (*request, error) {
|
||||
switch prm.Method {
|
||||
case nativeschema.MethodGetObject,
|
||||
nativeschema.MethodHeadObject,
|
||||
nativeschema.MethodRangeObject,
|
||||
nativeschema.MethodHashObject,
|
||||
nativeschema.MethodDeleteObject:
|
||||
if prm.Object == nil {
|
||||
return nil, fmt.Errorf("method %s: %w", prm.Method, errMissingOID)
|
||||
}
|
||||
case nativeschema.MethodSearchObject, nativeschema.MethodPutObject:
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown method: %s", prm.Method)
|
||||
}
|
||||
|
||||
var header *objectV2.Header
|
||||
if prm.Header != nil {
|
||||
header = prm.Header
|
||||
} else if prm.Object != nil {
|
||||
headerObjSDK, err := c.headerProvider.GetHeader(ctx, prm.Container, *prm.Object)
|
||||
if err == nil {
|
||||
header = headerObjSDK.ToV2().GetHeader()
|
||||
}
|
||||
}
|
||||
|
||||
return &request{
|
||||
operation: prm.Method,
|
||||
resource: &resource{
|
||||
name: resourceName(prm.Container, prm.Object, prm.Namespace),
|
||||
properties: objectProperties(prm.Container, prm.Object, header),
|
||||
},
|
||||
properties: map[string]string{
|
||||
nativeschema.PropertyKeyActorPublicKey: prm.SenderKey,
|
||||
nativeschema.PropertyKeyActorRole: prm.Role,
|
||||
},
|
||||
}, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue