forked from TrueCloudLab/frostfs-s3-gw
Compare commits
15 commits
master
...
support/v0
Author | SHA1 | Date | |
---|---|---|---|
f02bad65a8 | |||
13d00dd7ce | |||
02122892ca | |||
272e3a0f03 | |||
65a8e2dadc | |||
b7e15402a1 | |||
0cc6b41b2d | |||
51be9d9778 | |||
1cad101609 | |||
d631ee55c9 | |||
85c8210ffd | |||
bcfbcdc82f | |||
fd310f5e9f | |||
1f5f2bd3d5 | |||
a32b41716f |
41 changed files with 575 additions and 2362 deletions
|
@ -11,7 +11,6 @@ This document outlines major changes between releases.
|
||||||
- Fix possibility of panic during SIGHUP (#288)
|
- Fix possibility of panic during SIGHUP (#288)
|
||||||
- Fix flaky `TestErrorTimeoutChecking` (`make test` sometimes failed) (#290)
|
- Fix flaky `TestErrorTimeoutChecking` (`make test` sometimes failed) (#290)
|
||||||
- Fix user owner ID in billing metrics (#321)
|
- Fix user owner ID in billing metrics (#321)
|
||||||
- Fix HTTP/2 requests (#341)
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Add new `frostfs.buffer_max_size_for_put` config param and sync TZ hash for PUT operations (#197)
|
- Add new `frostfs.buffer_max_size_for_put` config param and sync TZ hash for PUT operations (#197)
|
||||||
|
@ -27,8 +26,6 @@ This document outlines major changes between releases.
|
||||||
- Support `policy` contract (#259)
|
- Support `policy` contract (#259)
|
||||||
- Support `proxy` contract (#287)
|
- Support `proxy` contract (#287)
|
||||||
- Authmate: support custom attributes (#292)
|
- Authmate: support custom attributes (#292)
|
||||||
- Add new `reconnect_interval` config param (#291)
|
|
||||||
- Support `GetBucketPolicyStatus` (#301)
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Generalise config param `use_default_xmlns_for_complete_multipart` to `use_default_xmlns` so that use default xmlns for all requests (#221)
|
- Generalise config param `use_default_xmlns_for_complete_multipart` to `use_default_xmlns` so that use default xmlns for all requests (#221)
|
||||||
|
|
|
@ -91,7 +91,6 @@ const (
|
||||||
ErrBucketNotEmpty
|
ErrBucketNotEmpty
|
||||||
ErrAllAccessDisabled
|
ErrAllAccessDisabled
|
||||||
ErrMalformedPolicy
|
ErrMalformedPolicy
|
||||||
ErrMalformedPolicyNotPrincipal
|
|
||||||
ErrMissingFields
|
ErrMissingFields
|
||||||
ErrMissingCredTag
|
ErrMissingCredTag
|
||||||
ErrCredMalformed
|
ErrCredMalformed
|
||||||
|
@ -666,12 +665,6 @@ var errorCodes = errorCodeMap{
|
||||||
Description: "Policy has invalid resource.",
|
Description: "Policy has invalid resource.",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrMalformedPolicyNotPrincipal: {
|
|
||||||
ErrCode: ErrMalformedPolicyNotPrincipal,
|
|
||||||
Code: "MalformedPolicy",
|
|
||||||
Description: "Allow with NotPrincipal is not allowed.",
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
},
|
|
||||||
ErrMissingFields: {
|
ErrMissingFields: {
|
||||||
ErrCode: ErrMissingFields,
|
ErrCode: ErrMissingFields,
|
||||||
Code: "MissingFields",
|
Code: "MissingFields",
|
||||||
|
|
|
@ -650,48 +650,6 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
reqInfo := middleware.GetReqInfo(r.Context())
|
|
||||||
|
|
||||||
bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName)
|
|
||||||
if err != nil {
|
|
||||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonPolicy, err := h.ape.GetBucketPolicy(reqInfo.Namespace, bktInfo.CID)
|
|
||||||
if err != nil {
|
|
||||||
if strings.Contains(err.Error(), "not found") {
|
|
||||||
err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchBucketPolicy), err.Error())
|
|
||||||
}
|
|
||||||
h.logAndSendError(w, "failed to get policy from storage", reqInfo, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var bktPolicy engineiam.Policy
|
|
||||||
if err = json.Unmarshal(jsonPolicy, &bktPolicy); err != nil {
|
|
||||||
h.logAndSendError(w, "could not parse bucket policy", reqInfo, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
policyStatus := &PolicyStatus{
|
|
||||||
IsPublic: PolicyStatusIsPublicFalse,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, st := range bktPolicy.Statement {
|
|
||||||
// https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html#access-control-block-public-access-policy-status
|
|
||||||
if _, ok := st.Principal[engineiam.Wildcard]; ok {
|
|
||||||
policyStatus.IsPublic = PolicyStatusIsPublicTrue
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = middleware.EncodeToResponse(w, policyStatus); err != nil {
|
|
||||||
h.logAndSendError(w, "encode and write response", reqInfo, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
|
func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
reqInfo := middleware.GetReqInfo(r.Context())
|
reqInfo := middleware.GetReqInfo(r.Context())
|
||||||
|
|
||||||
|
@ -774,11 +732,6 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(stat.NotPrincipal) != 0 && stat.Effect == engineiam.AllowEffect {
|
|
||||||
h.logAndSendError(w, "invalid NotPrincipal", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicyNotPrincipal))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, resource := range stat.Resource {
|
for _, resource := range stat.Resource {
|
||||||
if reqInfo.BucketName != strings.Split(strings.TrimPrefix(resource, arnAwsPrefix), "/")[0] {
|
if reqInfo.BucketName != strings.Split(strings.TrimPrefix(resource, arnAwsPrefix), "/")[0] {
|
||||||
h.logAndSendError(w, "policy resource mismatched bucket", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicy))
|
h.logAndSendError(w, "policy resource mismatched bucket", reqInfo, errors.GetAPIError(errors.ErrMalformedPolicy))
|
||||||
|
@ -1630,26 +1583,6 @@ func isWriteOperation(op eacl.Operation) bool {
|
||||||
return op == eacl.OperationDelete || op == eacl.OperationPut
|
return op == eacl.OperationDelete || op == eacl.OperationPut
|
||||||
}
|
}
|
||||||
|
|
||||||
type access struct {
|
|
||||||
recipient string
|
|
||||||
operations []eacl.Operation
|
|
||||||
}
|
|
||||||
|
|
||||||
type accessList struct {
|
|
||||||
list []access
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *accessList) addAccess(recipient string, operation eacl.Operation) {
|
|
||||||
for i, v := range c.list {
|
|
||||||
if v.recipient == recipient {
|
|
||||||
c.list[i].operations = append(c.list[i].operations, operation)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.list = append(c.list, access{recipient, []eacl.Operation{operation}})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketACL, bucketName, objectVersion string) *AccessControlPolicy {
|
func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketACL, bucketName, objectVersion string) *AccessControlPolicy {
|
||||||
res := &AccessControlPolicy{
|
res := &AccessControlPolicy{
|
||||||
Owner: Owner{
|
Owner: Owner{
|
||||||
|
@ -1658,7 +1591,7 @@ func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketAC
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
m := &accessList{}
|
m := make(map[string][]eacl.Operation)
|
||||||
|
|
||||||
astList := tableToAst(bucketACL.EACL, bucketName)
|
astList := tableToAst(bucketACL.EACL, bucketName)
|
||||||
|
|
||||||
|
@ -1673,20 +1606,22 @@ func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketAC
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(op.Users) == 0 {
|
if len(op.Users) == 0 {
|
||||||
m.addAccess(allUsersGroup, op.Op)
|
list := append(m[allUsersGroup], op.Op)
|
||||||
|
m[allUsersGroup] = list
|
||||||
} else {
|
} else {
|
||||||
for _, user := range op.Users {
|
for _, user := range op.Users {
|
||||||
m.addAccess(user, op.Op)
|
list := append(m[user], op.Op)
|
||||||
|
m[user] = list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, val := range m.list {
|
for key, val := range m {
|
||||||
permission := aclFullControl
|
permission := aclFullControl
|
||||||
read := true
|
read := true
|
||||||
for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ {
|
for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ {
|
||||||
if !contains(val.operations, op) && !isWriteOperation(op) {
|
if !contains(val, op) && !isWriteOperation(op) {
|
||||||
read = false
|
read = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1698,12 +1633,12 @@ func (h *handler) encodeObjectACL(ctx context.Context, bucketACL *layer.BucketAC
|
||||||
}
|
}
|
||||||
|
|
||||||
var grantee *Grantee
|
var grantee *Grantee
|
||||||
if val.recipient == allUsersGroup {
|
if key == allUsersGroup {
|
||||||
grantee = NewGrantee(acpGroup)
|
grantee = NewGrantee(acpGroup)
|
||||||
grantee.URI = allUsersGroup
|
grantee.URI = allUsersGroup
|
||||||
} else {
|
} else {
|
||||||
grantee = NewGrantee(acpCanonicalUser)
|
grantee = NewGrantee(acpCanonicalUser)
|
||||||
grantee.ID = val.recipient
|
grantee.ID = key
|
||||||
}
|
}
|
||||||
|
|
||||||
grant := &Grant{
|
grant := &Grant{
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -1469,42 +1468,6 @@ func TestBucketPolicy(t *testing.T) {
|
||||||
require.Equal(t, newPolicy, bktPolicy)
|
require.Equal(t, newPolicy, bktPolicy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBucketPolicyStatus(t *testing.T) {
|
|
||||||
hc := prepareHandlerContext(t)
|
|
||||||
bktName := "bucket-for-policy"
|
|
||||||
|
|
||||||
createTestBucket(hc, bktName)
|
|
||||||
|
|
||||||
getBucketPolicy(hc, bktName, s3errors.ErrNoSuchBucketPolicy)
|
|
||||||
|
|
||||||
newPolicy := engineiam.Policy{
|
|
||||||
Version: "2012-10-17",
|
|
||||||
Statement: []engineiam.Statement{{
|
|
||||||
NotPrincipal: engineiam.Principal{engineiam.Wildcard: {}},
|
|
||||||
Effect: engineiam.AllowEffect,
|
|
||||||
Action: engineiam.Action{"s3:PutObject"},
|
|
||||||
Resource: engineiam.Resource{arnAwsPrefix + bktName + "/*"},
|
|
||||||
}},
|
|
||||||
}
|
|
||||||
|
|
||||||
putBucketPolicy(hc, bktName, newPolicy, s3errors.ErrMalformedPolicyNotPrincipal)
|
|
||||||
|
|
||||||
newPolicy.Statement[0].NotPrincipal = nil
|
|
||||||
newPolicy.Statement[0].Principal = map[engineiam.PrincipalType][]string{engineiam.Wildcard: {}}
|
|
||||||
putBucketPolicy(hc, bktName, newPolicy)
|
|
||||||
bktPolicyStatus := getBucketPolicyStatus(hc, bktName)
|
|
||||||
require.True(t, PolicyStatusIsPublicTrue == bktPolicyStatus.IsPublic)
|
|
||||||
|
|
||||||
key, err := keys.NewPrivateKey()
|
|
||||||
require.NoError(t, err)
|
|
||||||
hc.Handler().frostfsid.(*frostfsidMock).data["devenv"] = key.PublicKey()
|
|
||||||
|
|
||||||
newPolicy.Statement[0].Principal = map[engineiam.PrincipalType][]string{engineiam.AWSPrincipalType: {"arn:aws:iam:::user/devenv"}}
|
|
||||||
putBucketPolicy(hc, bktName, newPolicy)
|
|
||||||
bktPolicyStatus = getBucketPolicyStatus(hc, bktName)
|
|
||||||
require.True(t, PolicyStatusIsPublicFalse == bktPolicyStatus.IsPublic)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeleteBucketWithPolicy(t *testing.T) {
|
func TestDeleteBucketWithPolicy(t *testing.T) {
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
|
@ -1624,22 +1587,6 @@ func getBucketPolicy(hc *handlerContext, bktName string, errCode ...s3errors.Err
|
||||||
return policy
|
return policy
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBucketPolicyStatus(hc *handlerContext, bktName string, errCode ...s3errors.ErrorCode) PolicyStatus {
|
|
||||||
w, r := prepareTestRequest(hc, bktName, "", nil)
|
|
||||||
hc.Handler().GetBucketPolicyStatusHandler(w, r)
|
|
||||||
|
|
||||||
var policyStatus PolicyStatus
|
|
||||||
if len(errCode) == 0 {
|
|
||||||
assertStatus(hc.t, w, http.StatusOK)
|
|
||||||
err := xml.NewDecoder(w.Result().Body).Decode(&policyStatus)
|
|
||||||
require.NoError(hc.t, err)
|
|
||||||
} else {
|
|
||||||
assertS3Error(hc.t, w, s3errors.GetAPIError(errCode[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return policyStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
func putBucketPolicy(hc *handlerContext, bktName string, bktPolicy engineiam.Policy, errCode ...s3errors.ErrorCode) {
|
func putBucketPolicy(hc *handlerContext, bktName string, bktPolicy engineiam.Policy, errCode ...s3errors.ErrorCode) {
|
||||||
body, err := json.Marshal(bktPolicy)
|
body, err := json.Marshal(bktPolicy)
|
||||||
require.NoError(hc.t, err)
|
require.NoError(hc.t, err)
|
||||||
|
|
|
@ -4,10 +4,8 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -179,11 +177,10 @@ func prepareHandlerContextBase(t *testing.T, cacheCfg *layer.CachesConfig) *hand
|
||||||
defaultPolicy: pp,
|
defaultPolicy: pp,
|
||||||
}
|
}
|
||||||
h := &handler{
|
h := &handler{
|
||||||
log: l,
|
log: l,
|
||||||
obj: layer.NewLayer(l, tp, layerCfg),
|
obj: layer.NewLayer(l, tp, layerCfg),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
ape: newAPEMock(),
|
ape: newAPEMock(),
|
||||||
frostfsid: newFrostfsIDMock(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &handlerContext{
|
return &handlerContext{
|
||||||
|
@ -310,32 +307,6 @@ func (a *apeMock) SaveACLChains(cid string, chains []*chain.Chain) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type frostfsidMock struct {
|
|
||||||
data map[string]*keys.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func newFrostfsIDMock() *frostfsidMock {
|
|
||||||
return &frostfsidMock{data: map[string]*keys.PublicKey{}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *frostfsidMock) GetUserAddress(account, user string) (string, error) {
|
|
||||||
res, ok := f.data[account+user]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.Address(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *frostfsidMock) GetUserKey(account, user string) (string, error) {
|
|
||||||
res, ok := f.data[account+user]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
return hex.EncodeToString(res.Bytes()), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createTestBucket(hc *handlerContext, bktName string) *data.BucketInfo {
|
func createTestBucket(hc *handlerContext, bktName string) *data.BucketInfo {
|
||||||
info := createBucket(hc, bktName)
|
info := createBucket(hc, bktName)
|
||||||
return info.BktInfo
|
return info.BktInfo
|
||||||
|
|
|
@ -55,19 +55,6 @@ type Bucket struct {
|
||||||
CreationDate string // time string of format "2006-01-02T15:04:05.000Z"
|
CreationDate string // time string of format "2006-01-02T15:04:05.000Z"
|
||||||
}
|
}
|
||||||
|
|
||||||
// PolicyStatus contains status of bucket policy.
|
|
||||||
type PolicyStatus struct {
|
|
||||||
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PolicyStatus" json:"-"`
|
|
||||||
IsPublic PolicyStatusIsPublic `xml:"IsPublic"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PolicyStatusIsPublic string
|
|
||||||
|
|
||||||
const (
|
|
||||||
PolicyStatusIsPublicFalse = "FALSE"
|
|
||||||
PolicyStatusIsPublicTrue = "TRUE"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AccessControlPolicy contains ACL.
|
// AccessControlPolicy contains ACL.
|
||||||
type AccessControlPolicy struct {
|
type AccessControlPolicy struct {
|
||||||
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlPolicy" json:"-"`
|
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlPolicy" json:"-"`
|
||||||
|
|
|
@ -9,7 +9,6 @@ const (
|
||||||
HeadBucketOperation = "HeadBucket"
|
HeadBucketOperation = "HeadBucket"
|
||||||
ListMultipartUploadsOperation = "ListMultipartUploads"
|
ListMultipartUploadsOperation = "ListMultipartUploads"
|
||||||
GetBucketLocationOperation = "GetBucketLocation"
|
GetBucketLocationOperation = "GetBucketLocation"
|
||||||
GetBucketPolicyStatusOperation = "GetBucketPolicyStatus"
|
|
||||||
GetBucketPolicyOperation = "GetBucketPolicy"
|
GetBucketPolicyOperation = "GetBucketPolicy"
|
||||||
GetBucketLifecycleOperation = "GetBucketLifecycle"
|
GetBucketLifecycleOperation = "GetBucketLifecycle"
|
||||||
GetBucketEncryptionOperation = "GetBucketEncryption"
|
GetBucketEncryptionOperation = "GetBucketEncryption"
|
||||||
|
@ -78,7 +77,6 @@ const (
|
||||||
const (
|
const (
|
||||||
UploadsQuery = "uploads"
|
UploadsQuery = "uploads"
|
||||||
LocationQuery = "location"
|
LocationQuery = "location"
|
||||||
PolicyStatusQuery = "policyStatus"
|
|
||||||
PolicyQuery = "policy"
|
PolicyQuery = "policy"
|
||||||
LifecycleQuery = "lifecycle"
|
LifecycleQuery = "lifecycle"
|
||||||
EncryptionQuery = "encryption"
|
EncryptionQuery = "encryption"
|
||||||
|
|
|
@ -20,13 +20,6 @@ import (
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
QueryVersionID = "versionId"
|
|
||||||
QueryPrefix = "prefix"
|
|
||||||
QueryDelimiter = "delimiter"
|
|
||||||
QueryMaxKeys = "max-keys"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PolicySettings interface {
|
type PolicySettings interface {
|
||||||
PolicyDenyByDefault() bool
|
PolicyDenyByDefault() bool
|
||||||
ACLEnabled() bool
|
ACLEnabled() bool
|
||||||
|
@ -67,7 +60,7 @@ func PolicyCheck(cfg PolicyConfig) Func {
|
||||||
|
|
||||||
func policyCheck(r *http.Request, cfg PolicyConfig) error {
|
func policyCheck(r *http.Request, cfg PolicyConfig) error {
|
||||||
reqType, bktName, objName := getBucketObject(r, cfg.Domains)
|
reqType, bktName, objName := getBucketObject(r, cfg.Domains)
|
||||||
req, err := getPolicyRequest(r, cfg.FrostfsID, reqType, bktName, objName, cfg.Log)
|
req, userKey, userGroups, err := getPolicyRequest(r, cfg.FrostfsID, reqType, bktName, objName, cfg.Log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -87,6 +80,19 @@ func policyCheck(r *http.Request, cfg PolicyConfig) error {
|
||||||
target.Container = &cnrTarget
|
target.Container = &cnrTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if userKey != nil {
|
||||||
|
entityName := fmt.Sprintf("%s:%s", reqInfo.Namespace, userKey.Address())
|
||||||
|
uTarget := engine.UserTarget(entityName)
|
||||||
|
target.User = &uTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
gts := make([]engine.Target, len(userGroups))
|
||||||
|
for i, group := range userGroups {
|
||||||
|
entityName := fmt.Sprintf("%s:%s", reqInfo.Namespace, group)
|
||||||
|
gts[i] = engine.GroupTarget(entityName)
|
||||||
|
}
|
||||||
|
target.Groups = gts
|
||||||
|
|
||||||
st, found, err := cfg.Storage.IsAllowed(chain.S3, target, req)
|
st, found, err := cfg.Storage.IsAllowed(chain.S3, target, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -115,24 +121,25 @@ func policyCheck(r *http.Request, cfg PolicyConfig) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPolicyRequest(r *http.Request, frostfsid FrostFSIDInformer, reqType ReqType, bktName string, objName string, log *zap.Logger) (*testutil.Request, error) {
|
func getPolicyRequest(r *http.Request, frostfsid FrostFSIDInformer, reqType ReqType, bktName string, objName string, log *zap.Logger) (*testutil.Request, *keys.PublicKey, []string, error) {
|
||||||
var (
|
var (
|
||||||
owner string
|
owner string
|
||||||
groups []string
|
groups []string
|
||||||
|
pk *keys.PublicKey
|
||||||
)
|
)
|
||||||
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
bd, err := GetBoxData(ctx)
|
bd, err := GetBoxData(ctx)
|
||||||
if err == nil && bd.Gate.BearerToken != nil {
|
if err == nil && bd.Gate.BearerToken != nil {
|
||||||
pk, err := keys.NewPublicKeyFromBytes(bd.Gate.BearerToken.SigningKeyBytes(), elliptic.P256())
|
pk, err = keys.NewPublicKeyFromBytes(bd.Gate.BearerToken.SigningKeyBytes(), elliptic.P256())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse pubclic key from btoken: %w", err)
|
return nil, nil, nil, fmt.Errorf("parse pubclic key from btoken: %w", err)
|
||||||
}
|
}
|
||||||
owner = pk.Address()
|
owner = pk.Address()
|
||||||
|
|
||||||
groups, err = frostfsid.GetUserGroupIDs(pk.GetScriptHash())
|
groups, err = frostfsid.GetUserGroupIDs(pk.GetScriptHash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get group ids: %w", err)
|
return nil, nil, nil, fmt.Errorf("get group ids: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,12 +152,15 @@ func getPolicyRequest(r *http.Request, frostfsid FrostFSIDInformer, reqType ReqT
|
||||||
res = fmt.Sprintf(s3.ResourceFormatS3Bucket, bktName)
|
res = fmt.Sprintf(s3.ResourceFormatS3Bucket, bktName)
|
||||||
}
|
}
|
||||||
|
|
||||||
properties := determineProperties(ctx, reqType, op, owner, groups)
|
|
||||||
|
|
||||||
reqLogOrDefault(r.Context(), log).Debug(logs.PolicyRequest, zap.String("action", op),
|
reqLogOrDefault(r.Context(), log).Debug(logs.PolicyRequest, zap.String("action", op),
|
||||||
zap.String("resource", res), zap.Any("properties", properties))
|
zap.String("resource", res), zap.String("owner", owner))
|
||||||
|
|
||||||
return testutil.NewRequest(op, testutil.NewResource(res, nil), properties), nil
|
return testutil.NewRequest(op, testutil.NewResource(res, nil),
|
||||||
|
map[string]string{
|
||||||
|
s3.PropertyKeyOwner: owner,
|
||||||
|
common.PropertyKeyFrostFSIDGroupID: chain.FormCondSliceContainsValue(groups),
|
||||||
|
},
|
||||||
|
), pk, groups, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReqType int
|
type ReqType int
|
||||||
|
@ -375,32 +385,3 @@ func determineGeneralOperation(r *http.Request) string {
|
||||||
}
|
}
|
||||||
return "UnmatchedOperation"
|
return "UnmatchedOperation"
|
||||||
}
|
}
|
||||||
|
|
||||||
func determineProperties(ctx context.Context, reqType ReqType, op, owner string, groups []string) map[string]string {
|
|
||||||
res := map[string]string{
|
|
||||||
s3.PropertyKeyOwner: owner,
|
|
||||||
common.PropertyKeyFrostFSIDGroupID: chain.FormCondSliceContainsValue(groups),
|
|
||||||
}
|
|
||||||
queries := GetReqInfo(ctx).URL.Query()
|
|
||||||
|
|
||||||
if reqType == objectType {
|
|
||||||
if versionID := queries.Get(QueryVersionID); len(versionID) > 0 {
|
|
||||||
res[s3.PropertyKeyVersionID] = versionID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if reqType == bucketType && (strings.HasSuffix(op, ListObjectsV1Operation) || strings.HasSuffix(op, ListObjectsV2Operation) ||
|
|
||||||
strings.HasSuffix(op, ListBucketObjectVersionsOperation) || strings.HasSuffix(op, ListMultipartUploadsOperation)) {
|
|
||||||
if prefix := queries.Get(QueryPrefix); len(prefix) > 0 {
|
|
||||||
res[s3.PropertyKeyPrefix] = prefix
|
|
||||||
}
|
|
||||||
if delimiter := queries.Get(QueryDelimiter); len(delimiter) > 0 {
|
|
||||||
res[s3.PropertyKeyDelimiter] = delimiter
|
|
||||||
}
|
|
||||||
if maxKeys := queries.Get(QueryMaxKeys); len(maxKeys) > 0 {
|
|
||||||
res[s3.PropertyKeyMaxKeys] = maxKeys
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ type (
|
||||||
PutObjectHandler(http.ResponseWriter, *http.Request)
|
PutObjectHandler(http.ResponseWriter, *http.Request)
|
||||||
DeleteObjectHandler(http.ResponseWriter, *http.Request)
|
DeleteObjectHandler(http.ResponseWriter, *http.Request)
|
||||||
GetBucketLocationHandler(http.ResponseWriter, *http.Request)
|
GetBucketLocationHandler(http.ResponseWriter, *http.Request)
|
||||||
GetBucketPolicyStatusHandler(http.ResponseWriter, *http.Request)
|
|
||||||
GetBucketPolicyHandler(http.ResponseWriter, *http.Request)
|
GetBucketPolicyHandler(http.ResponseWriter, *http.Request)
|
||||||
GetBucketLifecycleHandler(http.ResponseWriter, *http.Request)
|
GetBucketLifecycleHandler(http.ResponseWriter, *http.Request)
|
||||||
GetBucketEncryptionHandler(http.ResponseWriter, *http.Request)
|
GetBucketEncryptionHandler(http.ResponseWriter, *http.Request)
|
||||||
|
@ -231,9 +230,6 @@ func bucketRouter(h Handler, log *zap.Logger) chi.Router {
|
||||||
Add(NewFilter().
|
Add(NewFilter().
|
||||||
Queries(s3middleware.LocationQuery).
|
Queries(s3middleware.LocationQuery).
|
||||||
Handler(named(s3middleware.GetBucketLocationOperation, h.GetBucketLocationHandler))).
|
Handler(named(s3middleware.GetBucketLocationOperation, h.GetBucketLocationHandler))).
|
||||||
Add(NewFilter().
|
|
||||||
Queries(s3middleware.PolicyStatusQuery).
|
|
||||||
Handler(named(s3middleware.GetBucketPolicyStatusOperation, h.GetBucketPolicyStatusHandler))).
|
|
||||||
Add(NewFilter().
|
Add(NewFilter().
|
||||||
Queries(s3middleware.PolicyQuery).
|
Queries(s3middleware.PolicyQuery).
|
||||||
Handler(named(s3middleware.GetBucketPolicyOperation, h.GetBucketPolicyHandler))).
|
Handler(named(s3middleware.GetBucketPolicyOperation, h.GetBucketPolicyHandler))).
|
||||||
|
|
|
@ -186,11 +186,6 @@ func (h *handlerMock) GetBucketLocationHandler(http.ResponseWriter, *http.Reques
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handlerMock) GetBucketPolicyStatusHandler(http.ResponseWriter, *http.Request) {
|
|
||||||
//TODO implement me
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handlerMock) GetBucketPolicyHandler(http.ResponseWriter, *http.Request) {
|
func (h *handlerMock) GetBucketPolicyHandler(http.ResponseWriter, *http.Request) {
|
||||||
//TODO implement me
|
//TODO implement me
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -272,7 +271,7 @@ func TestACLAPE(t *testing.T) {
|
||||||
listBucketsErr(router, ns, apiErrors.ErrAccessDenied)
|
listBucketsErr(router, ns, apiErrors.ErrAccessDenied)
|
||||||
|
|
||||||
// Allow operations and check
|
// Allow operations and check
|
||||||
allowOperations(router, ns, []string{"s3:CreateBucket", "s3:ListAllMyBuckets"}, nil)
|
allowOperations(router, ns, []string{"s3:CreateBucket", "s3:ListAllMyBuckets"})
|
||||||
createBucket(router, ns, bktName)
|
createBucket(router, ns, bktName)
|
||||||
listBuckets(router, ns)
|
listBuckets(router, ns)
|
||||||
})
|
})
|
||||||
|
@ -298,7 +297,7 @@ func TestACLAPE(t *testing.T) {
|
||||||
listBuckets(router, ns)
|
listBuckets(router, ns)
|
||||||
|
|
||||||
// Deny operations and check
|
// Deny operations and check
|
||||||
denyOperations(router, ns, []string{"s3:CreateBucket", "s3:ListAllMyBuckets"}, nil)
|
denyOperations(router, ns, []string{"s3:CreateBucket", "s3:ListAllMyBuckets"})
|
||||||
createBucketErr(router, ns, bktName, apiErrors.ErrAccessDenied)
|
createBucketErr(router, ns, bktName, apiErrors.ErrAccessDenied)
|
||||||
listBucketsErr(router, ns, apiErrors.ErrAccessDenied)
|
listBucketsErr(router, ns, apiErrors.ErrAccessDenied)
|
||||||
})
|
})
|
||||||
|
@ -346,136 +345,22 @@ func TestACLAPE(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRequestParametersCheck(t *testing.T) {
|
func allowOperations(router *routerMock, ns string, operations []string) {
|
||||||
t.Run("prefix parameter, allow specific value", func(t *testing.T) {
|
addPolicy(router, ns, "allow", engineiam.AllowEffect, operations)
|
||||||
router := prepareRouter(t)
|
|
||||||
|
|
||||||
ns, bktName, prefix := "", "bucket", "prefix"
|
|
||||||
router.middlewareSettings.denyByDefault = true
|
|
||||||
|
|
||||||
allowOperations(router, ns, []string{"s3:CreateBucket"}, nil)
|
|
||||||
createBucket(router, ns, bktName)
|
|
||||||
|
|
||||||
// Add policies and check
|
|
||||||
denyOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondStringNotEquals: engineiam.Condition{s3.PropertyKeyPrefix: []string{prefix}},
|
|
||||||
})
|
|
||||||
allowOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondStringEquals: engineiam.Condition{s3.PropertyKeyPrefix: []string{prefix}},
|
|
||||||
})
|
|
||||||
|
|
||||||
listObjectsV1(router, ns, bktName, prefix, "", "")
|
|
||||||
listObjectsV1Err(router, ns, bktName, "", "", "", apiErrors.ErrAccessDenied)
|
|
||||||
listObjectsV1Err(router, ns, bktName, "invalid", "", "", apiErrors.ErrAccessDenied)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("delimiter parameter, prohibit specific value", func(t *testing.T) {
|
|
||||||
router := prepareRouter(t)
|
|
||||||
|
|
||||||
ns, bktName, delimiter := "", "bucket", "delimiter"
|
|
||||||
router.middlewareSettings.denyByDefault = true
|
|
||||||
|
|
||||||
allowOperations(router, ns, []string{"s3:CreateBucket"}, nil)
|
|
||||||
createBucket(router, ns, bktName)
|
|
||||||
|
|
||||||
// Add policies and check
|
|
||||||
denyOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondStringEquals: engineiam.Condition{s3.PropertyKeyDelimiter: []string{delimiter}},
|
|
||||||
})
|
|
||||||
allowOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondStringNotEquals: engineiam.Condition{s3.PropertyKeyDelimiter: []string{delimiter}},
|
|
||||||
})
|
|
||||||
|
|
||||||
listObjectsV1(router, ns, bktName, "", "", "")
|
|
||||||
listObjectsV1(router, ns, bktName, "", "some-delimiter", "")
|
|
||||||
listObjectsV1Err(router, ns, bktName, "", delimiter, "", apiErrors.ErrAccessDenied)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("max-keys parameter, allow specific value", func(t *testing.T) {
|
|
||||||
router := prepareRouter(t)
|
|
||||||
|
|
||||||
ns, bktName, maxKeys := "", "bucket", 10
|
|
||||||
router.middlewareSettings.denyByDefault = true
|
|
||||||
|
|
||||||
allowOperations(router, ns, []string{"s3:CreateBucket"}, nil)
|
|
||||||
createBucket(router, ns, bktName)
|
|
||||||
|
|
||||||
// Add policies and check
|
|
||||||
denyOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondNumericNotEquals: engineiam.Condition{s3.PropertyKeyMaxKeys: []string{strconv.Itoa(maxKeys)}},
|
|
||||||
})
|
|
||||||
allowOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondNumericEquals: engineiam.Condition{s3.PropertyKeyMaxKeys: []string{strconv.Itoa(maxKeys)}},
|
|
||||||
})
|
|
||||||
|
|
||||||
listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys))
|
|
||||||
listObjectsV1Err(router, ns, bktName, "", "", "", apiErrors.ErrAccessDenied)
|
|
||||||
listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1), apiErrors.ErrAccessDenied)
|
|
||||||
listObjectsV1Err(router, ns, bktName, "", "", "invalid", apiErrors.ErrAccessDenied)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("max-keys parameter, allow range of values", func(t *testing.T) {
|
|
||||||
router := prepareRouter(t)
|
|
||||||
|
|
||||||
ns, bktName, maxKeys := "", "bucket", 10
|
|
||||||
router.middlewareSettings.denyByDefault = true
|
|
||||||
|
|
||||||
allowOperations(router, ns, []string{"s3:CreateBucket"}, nil)
|
|
||||||
createBucket(router, ns, bktName)
|
|
||||||
|
|
||||||
// Add policies and check
|
|
||||||
denyOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondNumericGreaterThan: engineiam.Condition{s3.PropertyKeyMaxKeys: []string{strconv.Itoa(maxKeys)}},
|
|
||||||
})
|
|
||||||
allowOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondNumericLessThanEquals: engineiam.Condition{s3.PropertyKeyMaxKeys: []string{strconv.Itoa(maxKeys)}},
|
|
||||||
})
|
|
||||||
|
|
||||||
listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys))
|
|
||||||
listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1))
|
|
||||||
listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys+1), apiErrors.ErrAccessDenied)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("max-keys parameter, prohibit specific value", func(t *testing.T) {
|
|
||||||
router := prepareRouter(t)
|
|
||||||
|
|
||||||
ns, bktName, maxKeys := "", "bucket", 10
|
|
||||||
router.middlewareSettings.denyByDefault = true
|
|
||||||
|
|
||||||
allowOperations(router, ns, []string{"s3:CreateBucket"}, nil)
|
|
||||||
createBucket(router, ns, bktName)
|
|
||||||
|
|
||||||
// Add policies and check
|
|
||||||
denyOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondNumericEquals: engineiam.Condition{s3.PropertyKeyMaxKeys: []string{strconv.Itoa(maxKeys)}},
|
|
||||||
})
|
|
||||||
allowOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
|
||||||
engineiam.CondNumericNotEquals: engineiam.Condition{s3.PropertyKeyMaxKeys: []string{strconv.Itoa(maxKeys)}},
|
|
||||||
})
|
|
||||||
|
|
||||||
listObjectsV1(router, ns, bktName, "", "", "")
|
|
||||||
listObjectsV1(router, ns, bktName, "", "", strconv.Itoa(maxKeys-1))
|
|
||||||
listObjectsV1Err(router, ns, bktName, "", "", strconv.Itoa(maxKeys), apiErrors.ErrAccessDenied)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func allowOperations(router *routerMock, ns string, operations []string, conditions engineiam.Conditions) {
|
func denyOperations(router *routerMock, ns string, operations []string) {
|
||||||
addPolicy(router, ns, "allow", engineiam.AllowEffect, operations, conditions)
|
addPolicy(router, ns, "deny", engineiam.DenyEffect, operations)
|
||||||
}
|
}
|
||||||
|
|
||||||
func denyOperations(router *routerMock, ns string, operations []string, conditions engineiam.Conditions) {
|
func addPolicy(router *routerMock, ns string, id string, effect engineiam.Effect, operations []string) {
|
||||||
addPolicy(router, ns, "deny", engineiam.DenyEffect, operations, conditions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func addPolicy(router *routerMock, ns string, id string, effect engineiam.Effect, operations []string, conditions engineiam.Conditions) {
|
|
||||||
policy := engineiam.Policy{
|
policy := engineiam.Policy{
|
||||||
Version: "2012-10-17",
|
Version: "2012-10-17",
|
||||||
Statement: []engineiam.Statement{{
|
Statement: []engineiam.Statement{{
|
||||||
Principal: map[engineiam.PrincipalType][]string{engineiam.Wildcard: {}},
|
Principal: map[engineiam.PrincipalType][]string{engineiam.Wildcard: {}},
|
||||||
Effect: effect,
|
Effect: effect,
|
||||||
Action: engineiam.Action(operations),
|
Action: engineiam.Action(operations),
|
||||||
Resource: engineiam.Resource{fmt.Sprintf(s3.ResourceFormatS3All)},
|
Resource: engineiam.Resource{fmt.Sprintf(s3.ResourceFormatS3All)},
|
||||||
Conditions: conditions,
|
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,38 +442,6 @@ func putObjectBase(router *routerMock, namespace, bktName, objName string) *http
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func listObjectsV1(router *routerMock, namespace, bktName, prefix, delimiter, maxKeys string) handlerResult {
|
|
||||||
w := listObjectsV1Base(router, namespace, bktName, prefix, delimiter, maxKeys)
|
|
||||||
resp := readResponse(router.t, w)
|
|
||||||
require.Equal(router.t, s3middleware.ListObjectsV1Operation, resp.Method)
|
|
||||||
return resp
|
|
||||||
}
|
|
||||||
|
|
||||||
func listObjectsV1Err(router *routerMock, namespace, bktName, prefix, delimiter, maxKeys string, errCode apiErrors.ErrorCode) {
|
|
||||||
w := listObjectsV1Base(router, namespace, bktName, prefix, delimiter, maxKeys)
|
|
||||||
assertAPIError(router.t, w, errCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func listObjectsV1Base(router *routerMock, namespace, bktName, prefix, delimiter, maxKeys string) *httptest.ResponseRecorder {
|
|
||||||
queries := url.Values{}
|
|
||||||
if len(prefix) > 0 {
|
|
||||||
queries.Add(s3middleware.QueryPrefix, prefix)
|
|
||||||
}
|
|
||||||
if len(delimiter) > 0 {
|
|
||||||
queries.Add(s3middleware.QueryDelimiter, delimiter)
|
|
||||||
}
|
|
||||||
if len(maxKeys) > 0 {
|
|
||||||
queries.Add(s3middleware.QueryMaxKeys, maxKeys)
|
|
||||||
}
|
|
||||||
encoded := queries.Encode()
|
|
||||||
|
|
||||||
w, r := httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/"+bktName, nil)
|
|
||||||
r.URL.RawQuery = encoded
|
|
||||||
r.Header.Set(FrostfsNamespaceHeader, namespace)
|
|
||||||
router.ServeHTTP(w, r)
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOwnerIDRetrieving(t *testing.T) {
|
func TestOwnerIDRetrieving(t *testing.T) {
|
||||||
chiRouter := prepareRouter(t)
|
chiRouter := prepareRouter(t)
|
||||||
|
|
||||||
|
|
139
cmd/s3-gw/app.go
139
cmd/s3-gw/app.go
|
@ -71,9 +71,7 @@ type (
|
||||||
|
|
||||||
policyStorage *policy.Storage
|
policyStorage *policy.Storage
|
||||||
|
|
||||||
servers []Server
|
servers []Server
|
||||||
unbindServers []ServerInfo
|
|
||||||
mu sync.RWMutex
|
|
||||||
|
|
||||||
controlAPI *grpc.Server
|
controlAPI *grpc.Server
|
||||||
|
|
||||||
|
@ -90,7 +88,6 @@ type (
|
||||||
logLevel zap.AtomicLevel
|
logLevel zap.AtomicLevel
|
||||||
maxClient maxClientsConfig
|
maxClient maxClientsConfig
|
||||||
defaultMaxAge int
|
defaultMaxAge int
|
||||||
reconnectInterval time.Duration
|
|
||||||
notificatorEnabled bool
|
notificatorEnabled bool
|
||||||
resolveZoneList []string
|
resolveZoneList []string
|
||||||
isResolveListAllow bool // True if ResolveZoneList contains allowed zones
|
isResolveListAllow bool // True if ResolveZoneList contains allowed zones
|
||||||
|
@ -208,7 +205,6 @@ func newAppSettings(log *Logger, v *viper.Viper, key *keys.PrivateKey) *appSetti
|
||||||
logLevel: log.lvl,
|
logLevel: log.lvl,
|
||||||
maxClient: newMaxClients(v),
|
maxClient: newMaxClients(v),
|
||||||
defaultMaxAge: fetchDefaultMaxAge(v, log.logger),
|
defaultMaxAge: fetchDefaultMaxAge(v, log.logger),
|
||||||
reconnectInterval: fetchReconnectInterval(v),
|
|
||||||
notificatorEnabled: v.GetBool(cfgEnableNATS),
|
notificatorEnabled: v.GetBool(cfgEnableNATS),
|
||||||
frostfsidValidation: v.GetBool(cfgFrostfsIDValidationEnabled),
|
frostfsidValidation: v.GetBool(cfgFrostfsIDValidationEnabled),
|
||||||
}
|
}
|
||||||
|
@ -703,23 +699,17 @@ func (a *App) Serve(ctx context.Context) {
|
||||||
|
|
||||||
a.startServices()
|
a.startServices()
|
||||||
|
|
||||||
servs := a.getServers()
|
for i := range a.servers {
|
||||||
|
|
||||||
for i := range servs {
|
|
||||||
go func(i int) {
|
go func(i int) {
|
||||||
a.log.Info(logs.StartingServer, zap.String("address", servs[i].Address()))
|
a.log.Info(logs.StartingServer, zap.String("address", a.servers[i].Address()))
|
||||||
|
|
||||||
if err := srv.Serve(servs[i].Listener()); err != nil && err != http.ErrServerClosed {
|
if err := srv.Serve(a.servers[i].Listener()); err != nil && err != http.ErrServerClosed {
|
||||||
a.metrics.MarkUnhealthy(servs[i].Address())
|
a.metrics.MarkUnhealthy(a.servers[i].Address())
|
||||||
a.log.Fatal(logs.ListenAndServe, zap.Error(err))
|
a.log.Fatal(logs.ListenAndServe, zap.Error(err))
|
||||||
}
|
}
|
||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(a.unbindServers) != 0 {
|
|
||||||
a.scheduleReconnect(ctx, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
address := a.cfg.GetString(cfgControlGRPCEndpoint)
|
address := a.cfg.GetString(cfgControlGRPCEndpoint)
|
||||||
a.log.Info(logs.StartingControlAPI, zap.String("address", address))
|
a.log.Info(logs.StartingControlAPI, zap.String("address", address))
|
||||||
|
@ -836,7 +826,7 @@ func (a *App) startServices() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) initServers(ctx context.Context) {
|
func (a *App) initServers(ctx context.Context) {
|
||||||
serversInfo := fetchServers(a.cfg, a.log)
|
serversInfo := fetchServers(a.cfg)
|
||||||
|
|
||||||
a.servers = make([]Server, 0, len(serversInfo))
|
a.servers = make([]Server, 0, len(serversInfo))
|
||||||
for _, serverInfo := range serversInfo {
|
for _, serverInfo := range serversInfo {
|
||||||
|
@ -846,7 +836,6 @@ func (a *App) initServers(ctx context.Context) {
|
||||||
}
|
}
|
||||||
srv, err := newServer(ctx, serverInfo)
|
srv, err := newServer(ctx, serverInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.unbindServers = append(a.unbindServers, serverInfo)
|
|
||||||
a.metrics.MarkUnhealthy(serverInfo.Address)
|
a.metrics.MarkUnhealthy(serverInfo.Address)
|
||||||
a.log.Warn(logs.FailedToAddServer, append(fields, zap.Error(err))...)
|
a.log.Warn(logs.FailedToAddServer, append(fields, zap.Error(err))...)
|
||||||
continue
|
continue
|
||||||
|
@ -863,24 +852,21 @@ func (a *App) initServers(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) updateServers() error {
|
func (a *App) updateServers() error {
|
||||||
serversInfo := fetchServers(a.cfg, a.log)
|
serversInfo := fetchServers(a.cfg)
|
||||||
|
|
||||||
a.mu.Lock()
|
|
||||||
defer a.mu.Unlock()
|
|
||||||
|
|
||||||
var found bool
|
var found bool
|
||||||
for _, serverInfo := range serversInfo {
|
for _, serverInfo := range serversInfo {
|
||||||
ser := a.getServer(serverInfo.Address)
|
index := a.serverIndex(serverInfo.Address)
|
||||||
if ser != nil {
|
if index == -1 {
|
||||||
if serverInfo.TLS.Enabled {
|
continue
|
||||||
if err := ser.UpdateCert(serverInfo.TLS.CertFile, serverInfo.TLS.KeyFile); err != nil {
|
|
||||||
return fmt.Errorf("failed to update tls certs: %w", err)
|
|
||||||
}
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
} else if unbind := a.updateUnbindServerInfo(serverInfo); unbind {
|
|
||||||
found = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if serverInfo.TLS.Enabled {
|
||||||
|
if err := a.servers[index].UpdateCert(serverInfo.TLS.CertFile, serverInfo.TLS.KeyFile); err != nil {
|
||||||
|
return fmt.Errorf("failed to update tls certs: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
|
@ -890,6 +876,15 @@ func (a *App) updateServers() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) serverIndex(address string) int {
|
||||||
|
for i := range a.servers {
|
||||||
|
if a.servers[i].Address() == address {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) stopServices() {
|
func (a *App) stopServices() {
|
||||||
ctx, cancel := shutdownContext()
|
ctx, cancel := shutdownContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -964,31 +959,6 @@ func (a *App) initHandler() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) getServer(address string) Server {
|
|
||||||
for i := range a.servers {
|
|
||||||
if a.servers[i].Address() == address {
|
|
||||||
return a.servers[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) updateUnbindServerInfo(info ServerInfo) bool {
|
|
||||||
for i := range a.unbindServers {
|
|
||||||
if a.unbindServers[i].Address == info.Address {
|
|
||||||
a.unbindServers[i] = info
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) getServers() []Server {
|
|
||||||
a.mu.RLock()
|
|
||||||
defer a.mu.RUnlock()
|
|
||||||
return a.servers
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) setRuntimeParameters() {
|
func (a *App) setRuntimeParameters() {
|
||||||
if len(os.Getenv("GOMEMLIMIT")) != 0 {
|
if len(os.Getenv("GOMEMLIMIT")) != 0 {
|
||||||
// default limit < yaml limit < app env limit < GOMEMLIMIT
|
// default limit < yaml limit < app env limit < GOMEMLIMIT
|
||||||
|
@ -1004,60 +974,3 @@ func (a *App) setRuntimeParameters() {
|
||||||
zap.Int64("old_value", previous))
|
zap.Int64("old_value", previous))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) scheduleReconnect(ctx context.Context, srv *http.Server) {
|
|
||||||
go func() {
|
|
||||||
t := time.NewTicker(a.settings.reconnectInterval)
|
|
||||||
defer t.Stop()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
if a.tryReconnect(ctx, srv) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.Reset(a.settings.reconnectInterval)
|
|
||||||
case <-ctx.Done():
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) tryReconnect(ctx context.Context, sr *http.Server) bool {
|
|
||||||
a.mu.Lock()
|
|
||||||
defer a.mu.Unlock()
|
|
||||||
|
|
||||||
a.log.Info(logs.ServerReconnecting)
|
|
||||||
var failedServers []ServerInfo
|
|
||||||
|
|
||||||
for _, serverInfo := range a.unbindServers {
|
|
||||||
fields := []zap.Field{
|
|
||||||
zap.String("address", serverInfo.Address), zap.Bool("tls enabled", serverInfo.TLS.Enabled),
|
|
||||||
zap.String("tls cert", serverInfo.TLS.CertFile), zap.String("tls key", serverInfo.TLS.KeyFile),
|
|
||||||
}
|
|
||||||
|
|
||||||
srv, err := newServer(ctx, serverInfo)
|
|
||||||
if err != nil {
|
|
||||||
a.log.Warn(logs.ServerReconnectFailed, zap.Error(err))
|
|
||||||
failedServers = append(failedServers, serverInfo)
|
|
||||||
a.metrics.MarkUnhealthy(serverInfo.Address)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
a.log.Info(logs.StartingServer, zap.String("address", srv.Address()))
|
|
||||||
a.metrics.MarkHealthy(serverInfo.Address)
|
|
||||||
if err = sr.Serve(srv.Listener()); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
||||||
a.log.Warn(logs.ListenAndServe, zap.Error(err))
|
|
||||||
a.metrics.MarkUnhealthy(serverInfo.Address)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
a.servers = append(a.servers, srv)
|
|
||||||
a.log.Info(logs.ServerReconnectedSuccessfully, fields...)
|
|
||||||
}
|
|
||||||
|
|
||||||
a.unbindServers = failedServers
|
|
||||||
|
|
||||||
return len(a.unbindServers) == 0
|
|
||||||
}
|
|
||||||
|
|
|
@ -59,8 +59,6 @@ const (
|
||||||
defaultConstraintName = "default"
|
defaultConstraintName = "default"
|
||||||
|
|
||||||
defaultNamespace = ""
|
defaultNamespace = ""
|
||||||
|
|
||||||
defaultReconnectInterval = time.Minute
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -224,9 +222,6 @@ const ( // Settings.
|
||||||
// Proxy.
|
// Proxy.
|
||||||
cfgProxyContract = "proxy.contract"
|
cfgProxyContract = "proxy.contract"
|
||||||
|
|
||||||
// Server.
|
|
||||||
cfgReconnectInterval = "reconnect_interval"
|
|
||||||
|
|
||||||
// envPrefix is an environment variables prefix used for configuration.
|
// envPrefix is an environment variables prefix used for configuration.
|
||||||
envPrefix = "S3_GW"
|
envPrefix = "S3_GW"
|
||||||
)
|
)
|
||||||
|
@ -249,15 +244,6 @@ func fetchConnectTimeout(cfg *viper.Viper) time.Duration {
|
||||||
return connTimeout
|
return connTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchReconnectInterval(cfg *viper.Viper) time.Duration {
|
|
||||||
reconnect := cfg.GetDuration(cfgReconnectInterval)
|
|
||||||
if reconnect <= 0 {
|
|
||||||
reconnect = defaultReconnectInterval
|
|
||||||
}
|
|
||||||
|
|
||||||
return reconnect
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchStreamTimeout(cfg *viper.Viper) time.Duration {
|
func fetchStreamTimeout(cfg *viper.Viper) time.Duration {
|
||||||
streamTimeout := cfg.GetDuration(cfgStreamTimeout)
|
streamTimeout := cfg.GetDuration(cfgStreamTimeout)
|
||||||
if streamTimeout <= 0 {
|
if streamTimeout <= 0 {
|
||||||
|
@ -625,9 +611,8 @@ func fetchPeers(l *zap.Logger, v *viper.Viper) []pool.NodeParam {
|
||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchServers(v *viper.Viper, log *zap.Logger) []ServerInfo {
|
func fetchServers(v *viper.Viper) []ServerInfo {
|
||||||
var servers []ServerInfo
|
var servers []ServerInfo
|
||||||
seen := make(map[string]struct{})
|
|
||||||
|
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
key := cfgServer + "." + strconv.Itoa(i) + "."
|
key := cfgServer + "." + strconv.Itoa(i) + "."
|
||||||
|
@ -642,11 +627,6 @@ func fetchServers(v *viper.Viper, log *zap.Logger) []ServerInfo {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := seen[serverInfo.Address]; ok {
|
|
||||||
log.Warn(logs.WarnDuplicateAddress, zap.String("address", serverInfo.Address))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seen[serverInfo.Address] = struct{}{}
|
|
||||||
servers = append(servers, serverInfo)
|
servers = append(servers, serverInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,6 @@ func newServer(ctx context.Context, serverInfo ServerInfo) (*server, error) {
|
||||||
|
|
||||||
ln = tls.NewListener(ln, &tls.Config{
|
ln = tls.NewListener(ln, &tls.Config{
|
||||||
GetCertificate: tlsProvider.GetCertificate,
|
GetCertificate: tlsProvider.GetCertificate,
|
||||||
NextProtos: []string{"h2"}, // required to enable HTTP/2 requests in `http.Serve`
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/pem"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"golang.org/x/net/http2"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
expHeaderKey = "Foo"
|
|
||||||
expHeaderValue = "Bar"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestHTTP2TLS(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
certPath, keyPath := prepareTestCerts(t)
|
|
||||||
|
|
||||||
srv := &http.Server{
|
|
||||||
Handler: http.HandlerFunc(testHandler),
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsListener, err := newServer(ctx, ServerInfo{
|
|
||||||
Address: ":0",
|
|
||||||
TLS: ServerTLSInfo{
|
|
||||||
Enabled: true,
|
|
||||||
CertFile: certPath,
|
|
||||||
KeyFile: keyPath,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
port := tlsListener.Listener().Addr().(*net.TCPAddr).Port
|
|
||||||
addr := fmt.Sprintf("https://localhost:%d", port)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
_ = srv.Serve(tlsListener.Listener())
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Server is running, now send HTTP/2 request
|
|
||||||
|
|
||||||
tlsClientConfig := &tls.Config{
|
|
||||||
InsecureSkipVerify: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
cliHTTP1 := http.Client{Transport: &http.Transport{TLSClientConfig: tlsClientConfig}}
|
|
||||||
cliHTTP2 := http.Client{Transport: &http2.Transport{TLSClientConfig: tlsClientConfig}}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", addr, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
req.Header[expHeaderKey] = []string{expHeaderValue}
|
|
||||||
|
|
||||||
resp, err := cliHTTP1.Do(req)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
|
||||||
|
|
||||||
resp, err = cliHTTP2.Do(req)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testHandler(resp http.ResponseWriter, req *http.Request) {
|
|
||||||
hdr, ok := req.Header[expHeaderKey]
|
|
||||||
if !ok || len(hdr) != 1 || hdr[0] != expHeaderValue {
|
|
||||||
resp.WriteHeader(http.StatusBadRequest)
|
|
||||||
} else {
|
|
||||||
resp.WriteHeader(http.StatusOK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func prepareTestCerts(t *testing.T) (certPath, keyPath string) {
|
|
||||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
template := x509.Certificate{
|
|
||||||
SerialNumber: big.NewInt(1),
|
|
||||||
Subject: pkix.Name{CommonName: "localhost"},
|
|
||||||
NotBefore: time.Now(),
|
|
||||||
NotAfter: time.Now().Add(time.Hour * 24 * 365),
|
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
dir := t.TempDir()
|
|
||||||
certPath = path.Join(dir, "cert.pem")
|
|
||||||
keyPath = path.Join(dir, "key.pem")
|
|
||||||
|
|
||||||
certFile, err := os.Create(certPath)
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer certFile.Close()
|
|
||||||
|
|
||||||
keyFile, err := os.Create(keyPath)
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer keyFile.Close()
|
|
||||||
|
|
||||||
err = pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = pem.Encode(keyFile, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return certPath, keyPath
|
|
||||||
}
|
|
|
@ -33,9 +33,6 @@ S3_GW_SERVER_1_TLS_ENABLED=true
|
||||||
S3_GW_SERVER_1_TLS_CERT_FILE=/path/to/tls/cert
|
S3_GW_SERVER_1_TLS_CERT_FILE=/path/to/tls/cert
|
||||||
S3_GW_SERVER_1_TLS_KEY_FILE=/path/to/tls/key
|
S3_GW_SERVER_1_TLS_KEY_FILE=/path/to/tls/key
|
||||||
|
|
||||||
# How often to reconnect to the servers
|
|
||||||
S3_GW_RECONNECT_INTERVAL: 1m
|
|
||||||
|
|
||||||
# Control API
|
# Control API
|
||||||
# List of hex-encoded public keys that have rights to use the Control Service
|
# List of hex-encoded public keys that have rights to use the Control Service
|
||||||
S3_GW_CONTROL_AUTHORIZED_KEYS=035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11 028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6
|
S3_GW_CONTROL_AUTHORIZED_KEYS=035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11 028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6
|
||||||
|
|
|
@ -25,8 +25,6 @@ peers:
|
||||||
priority: 2
|
priority: 2
|
||||||
weight: 0.9
|
weight: 0.9
|
||||||
|
|
||||||
reconnect_interval: 1m
|
|
||||||
|
|
||||||
server:
|
server:
|
||||||
- address: 0.0.0.0:8080
|
- address: 0.0.0.0:8080
|
||||||
tls:
|
tls:
|
||||||
|
|
|
@ -1,313 +0,0 @@
|
||||||
# Authentication and authorization scheme
|
|
||||||
|
|
||||||
This document describes s3-gw authentication and authorization mechanism.
|
|
||||||
|
|
||||||
## General overview
|
|
||||||
|
|
||||||
Basic provisions:
|
|
||||||
|
|
||||||
* A request to s3-gw can be signed or not (request that isn't signed we will cal anonymous or just anon)
|
|
||||||
* To manage resources (buckets/objects) using s3-gw you must have appropriate access rights
|
|
||||||
|
|
||||||
Each request must be authenticated (at least as anonymous) and authorized. The following scheme shows components that
|
|
||||||
are involved to this
|
|
||||||
process.
|
|
||||||
|
|
||||||
<a>
|
|
||||||
<img src="images/authentication/auth-overview.svg" alt="Auth general overview"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
There are several participants of this process:
|
|
||||||
|
|
||||||
1. User that make a request
|
|
||||||
2. S3-GW that accepts a request
|
|
||||||
3. FrostFS Storage that stores AccessObjects (objects are needed for authentication)
|
|
||||||
4. Blockchain smart contracts (`frostfsid`, `policy`) that stores user info and access rules.
|
|
||||||
|
|
||||||
## Data auth process
|
|
||||||
|
|
||||||
Let's look at the process in more detail:
|
|
||||||
|
|
||||||
<a>
|
|
||||||
<img src="images/authentication/auth-sequence.svg" alt="Auth sequence diagram"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
* First of all, someone make a request. If request is signed we will check its signature (`Authentication`) after that
|
|
||||||
we will check access rights using policies (`Auhorization`). For anonymous requests only authorization be performed.
|
|
||||||
|
|
||||||
* **Authentication steps**:
|
|
||||||
* Each signed request is provided with `AccessKeyId` and signature. So if request is signed we must check its
|
|
||||||
signature. To do this we must know the `AccessKeyId`/`SecretAccessKey` pair (How the signature is calculated
|
|
||||||
using this pair see [signing](#aws-signing). Client and server (s3-gw) use the same credentials and algorithm to
|
|
||||||
compute signature). The `AccessKeyId` is a public part of credentials, and it's passed to gate in request. The
|
|
||||||
private part of credentials is `SecretAccessKey` and it's encrypted and stored in [AccessBox](#accessbox). So on
|
|
||||||
this step we must find appropriate `AccessBox` in FrostFS storage node (How to find appropriate `AccessBox`
|
|
||||||
knowing `AccessKeyId` see [search algorithm](#search-algorithm)). On this stage we can get `AccessDenied` from
|
|
||||||
FrostFS storage node if the s3-gw doesn't have permission to read this `AccessBox` object.
|
|
||||||
|
|
||||||
* After successful retrieving object we must extract `SecretAccessKey` from it. Since it's encrypted the s3-gw must
|
|
||||||
decrypt (see [encryption](#encryption)) this object using own private key and `SeedKey` from `AccessBox`
|
|
||||||
(see [AccessBox inner structure](#accessbox)). After s3-gw have got the `AccessKeyId`/`SecretAccessKey` pair it
|
|
||||||
[calculate signature](#aws-signing) and compare got signature with provided withing request. If signature doesn't
|
|
||||||
match the `AccessDenied` is returned.
|
|
||||||
|
|
||||||
* `AccessBox` also contains `OwnerID` that is related to `AccessKeyId` that was provided. So we have to check if
|
|
||||||
such `OwnerID` exists in `frsotfsid` contract (that stores all registered valid users). If user doesn't exist in
|
|
||||||
contract the `AccessDenied` is returned.
|
|
||||||
|
|
||||||
* **Authorization steps**:
|
|
||||||
* To know if user has access right to do what he wants to do we must find appropriate access policies. Such policies
|
|
||||||
are stored in `policy` contract and locally (can be manged using [control api](#control-auth-process)). So we need
|
|
||||||
to get policies from contract and [check them](#policies) along with local to decide if user has access right. If
|
|
||||||
he doesn't have such right the `AccessDenied` is returned.
|
|
||||||
|
|
||||||
* After successful authentication and authorization the request will be processed by s3-gw business logic and finally be
|
|
||||||
propagated to FrostFS storage node which also performs some auth checks and can return `AccessDenied`. If this happens
|
|
||||||
s3-gw also returns `AccessDenied` as response.
|
|
||||||
|
|
||||||
### AWS Signing
|
|
||||||
|
|
||||||
Every interaction with FrostFS S3 gateway is either authenticated or anonymous. This section explains request
|
|
||||||
authentication with the AWS Signature Version 4 algorithm. More info in AWS documentation:
|
|
||||||
|
|
||||||
* [Authenticating Requests (AWS Signature Version 4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)
|
|
||||||
* [Signing AWS API requests](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html)
|
|
||||||
|
|
||||||
#### Authentication Methods
|
|
||||||
|
|
||||||
You can express authentication information by using one of the following methods:
|
|
||||||
|
|
||||||
* **HTTP Authorization header** - Using the HTTP Authorization header is the most common method of authenticating an
|
|
||||||
FrostFS S3 request. All the FrostFS S3 REST operations (except for browser-based uploads using POST requests) require
|
|
||||||
this header. For more information about the Authorization header value, and how to calculate signature and related
|
|
||||||
options,
|
|
||||||
see [Authenticating Requests: Using the Authorization Header (AWS Signature Version 4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html).
|
|
||||||
* **Query string parameters** - You can use a query string to express a request entirely in a URL. In this case, you use
|
|
||||||
query parameters to provide request information, including the authentication information. Because the request
|
|
||||||
signature is part of the URL, this type of URL is often referred to as a presigned URL. You can use presigned URLs to
|
|
||||||
embed clickable links, which can be valid for up to seven days, in HTML. For more information,
|
|
||||||
see [Authenticating Requests: Using Query Parameters (AWS Signature Version 4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html).
|
|
||||||
|
|
||||||
FrostFS S3 also supports browser-based uploads that use HTTP POST requests. With an HTTP POST request, you can upload
|
|
||||||
content to FrostFS S3 directly from the browser. For information about authenticating POST requests,
|
|
||||||
see [Browser-Based Uploads Using POST (AWS Signature Version 4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html).
|
|
||||||
|
|
||||||
#### Introduction to Signing Requests
|
|
||||||
|
|
||||||
Authentication information that you send in a request must include a signature. To calculate a signature, you first
|
|
||||||
concatenate select request elements to form a string, referred to as the string to sign. You then use a signing key to
|
|
||||||
calculate the hash-based message authentication code (HMAC) of the string to sign.
|
|
||||||
|
|
||||||
In AWS Signature Version 4, you don't use your secret access key to sign the request. Instead, you first use your secret
|
|
||||||
access key to derive a signing key. The derived signing key is specific to the date, service, and Region. For more
|
|
||||||
information about how to derive a signing key in different programming languages, see Examples of how to derive a
|
|
||||||
signing key for Signature Version 4.
|
|
||||||
|
|
||||||
The following diagram illustrates the general process of computing a signature.
|
|
||||||
|
|
||||||
<a>
|
|
||||||
<img src="images/authentication/aws-signing.png" alt="AWS Signing"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
The string to sign depends on the request type. For example, when you use the HTTP Authorization header or the query
|
|
||||||
parameters for authentication, you use a varying combination of request elements to create the string to sign. For an
|
|
||||||
HTTP POST request, the POST policy in the request is the string you sign. For more information about computing string to
|
|
||||||
sign, follow links provided at the end of this section.
|
|
||||||
|
|
||||||
For signing key, the diagram shows series of calculations, where result of each step you feed into the next step. The
|
|
||||||
final step is the signing key.
|
|
||||||
|
|
||||||
Upon receiving an authenticated request, FrostFS S3 servers re-create the signature by using the authentication
|
|
||||||
information that is contained in the request. If the signatures match, FrostFS S3 processes your request; otherwise, the
|
|
||||||
request is rejected.
|
|
||||||
|
|
||||||
##### Signature Calculations for the Authorization Header
|
|
||||||
|
|
||||||
To calculate a signature, you first need a string to sign. You then calculate a HMAC-SHA256 hash of the string to sign
|
|
||||||
by using a signing key. The following diagram illustrates the process, including the various components of the string
|
|
||||||
that you create for signing.
|
|
||||||
|
|
||||||
When FrostFS S3 receives an authenticated request, it computes the signature and then compares it with the signature
|
|
||||||
that you provided in the request. For that reason, you must compute the signature by using the same method that is used
|
|
||||||
by FrostFS S3. The process of putting a request in an agreed-upon form for signing is called canonicalization.
|
|
||||||
|
|
||||||
<a>
|
|
||||||
<img src="images/authentication/auth-header-signing.png" alt="Signature Calculations for the Authorization Header"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
See detains in [AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html).
|
|
||||||
|
|
||||||
#### s3-gw
|
|
||||||
|
|
||||||
s3-gw support the following ways to provide the singed request:
|
|
||||||
|
|
||||||
* [HTTP Authorization header](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html)
|
|
||||||
* [Query string parameters](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)
|
|
||||||
* [Browser-Based Uploads Using POST](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html)
|
|
||||||
|
|
||||||
All these methods provide `AccessKeyId` and signature. Using `AccessKeyId` s3-gw can get `SecretAccessKey`
|
|
||||||
(see [data auth](#data-auth-process)) to compute signature using exactly the same mechanics
|
|
||||||
as [client does](#introduction-to-signing-requests). After signature calculation the s3-gw just compares signatures and
|
|
||||||
if they don't match the access denied is returned.
|
|
||||||
|
|
||||||
### AccessBox
|
|
||||||
|
|
||||||
`AccessBox` is an ordinary object in FrostFS storage. It contains all information that can be used by s3-gw to
|
|
||||||
successfully authenticate request. Also, it contains data that is required to successful authentication in FrostFS
|
|
||||||
storage node.
|
|
||||||
|
|
||||||
Based on this object s3 credentials are formed:
|
|
||||||
|
|
||||||
* `AccessKeyId` - is concatenated container id and object id (`<cid>0<oid>`) of `AccessBox` (
|
|
||||||
e.g. `2XGRML5EW3LMHdf64W2DkBy1Nkuu4y4wGhUj44QjbXBi05ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3Snxf`)
|
|
||||||
* `SecretAccessKey` - hex-encoded random generated 32 bytes (that is encrypted and stored in object payload)
|
|
||||||
|
|
||||||
> **Note**: sensitive info in `AccessBox` is [encrypted](#encryption), so only someone who posses specific private key
|
|
||||||
> can decrypt such info.
|
|
||||||
|
|
||||||
`AccessBox` has the following structure:
|
|
||||||
|
|
||||||
<a>
|
|
||||||
<img src="images/authentication/accessbox-object.svg" alt="AccessBox object structure"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
**Headers:**
|
|
||||||
|
|
||||||
`AccessBox` object has the following attributes (at least them, it also can contain custom one):
|
|
||||||
|
|
||||||
* `Timestamp` - unix timestamp when object was created
|
|
||||||
* `__SYSTEM__EXPIRATION_EPOCH` - epoch after which the object isn't available anymore
|
|
||||||
* `S3-CRDT-Versions-Add` - comma separated list of previous versions of `AccessBox` (
|
|
||||||
see [AccessBox versions](#accessbox-versions))
|
|
||||||
* `S3-Access-Box-CRDT-Name` - `AccessKeyId` of credentials to which current `AccessBox` is related (
|
|
||||||
see [AccessBox versions](#accessbox-versions))
|
|
||||||
* `FilePath` - just object name
|
|
||||||
|
|
||||||
**Payload:**
|
|
||||||
|
|
||||||
The `AccessBox` payload is an encoded [AccessBox protobuf type](../creds/accessbox/accessbox.proto) .
|
|
||||||
It contains:
|
|
||||||
|
|
||||||
* Seed key - hex-encoded public seed key to compute shared secret using ECDH (see [encryption](#encryption))
|
|
||||||
* List of gate data:
|
|
||||||
* Gate public key (so that gate (when it will decrypt data later) know which one item from list it should process)
|
|
||||||
* Encrypted tokens:
|
|
||||||
* `SecretAccessKey` - hex-encoded random generated 32 bytes
|
|
||||||
* Marshaled bearer token - more detail
|
|
||||||
in [spec](https://git.frostfs.info/TrueCloudLab/frostfs-api/src/commit/4c68d92468503b10282c8a92af83a56f170c8a3a/acl/types.proto#L189)
|
|
||||||
* Marshaled session token - more detail
|
|
||||||
in [spec](https://git.frostfs.info/TrueCloudLab/frostfs-api/src/commit/4c68d92468503b10282c8a92af83a56f170c8a3a/session/types.proto#L89)
|
|
||||||
* Container placement policies:
|
|
||||||
* `LocationsConstraint` - name of location constraint that can be used to create bucket/container using s3
|
|
||||||
credentials related to this `AccessBox`
|
|
||||||
* Marshaled placement policy - more detail
|
|
||||||
in [spec](https://git.frostfs.info/TrueCloudLab/frostfs-api/src/commit/4c68d92468503b10282c8a92af83a56f170c8a3a/netmap/types.proto#L111)
|
|
||||||
|
|
||||||
#### AccessBox versions
|
|
||||||
|
|
||||||
Imagine the following scenario:
|
|
||||||
|
|
||||||
* There is a system where only one s3-gw exist
|
|
||||||
* There is a `AccessBox` that can be used by this s3-gw
|
|
||||||
* User has s3 credentials (`AccessKeyId`/`SecretAccessKey`) related to corresponded `AccessBox` and can successfully
|
|
||||||
make request to s3-gw
|
|
||||||
* The system is expanded and new one s3-gw is added
|
|
||||||
* User must be able to use the credentials (that he has already had) to make request to new one s3-gw
|
|
||||||
|
|
||||||
Since `AccessBox` object is immutable and `SecretAccessKey` is encrypted only for restricted list of keys (can be used
|
|
||||||
(decrypted) only by limited number of s3-gw) we have to create new `AccessBox` that has encrypted secrets for new list
|
|
||||||
of s3-gw and be related to initial s3 credentials (`AccessKeyId`/`SecretAccessKey`). Such relationship is done
|
|
||||||
by `S3-Access-Box-CRDT-Name`.
|
|
||||||
|
|
||||||
##### Search algorithm
|
|
||||||
|
|
||||||
To support scenario from previous section and find appropriate version of `AccessBox` (that contains more recent and
|
|
||||||
relevant data) the following sequence is used:
|
|
||||||
|
|
||||||
<a>
|
|
||||||
<img src="images/authentication/accessbox-search.svg" alt="AccessBox search process"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
* Search all object whose attribute `S3-Access-Box-CRDT-Name` is equal to `AccessKeyId` (extract container id
|
|
||||||
from `AccessKeyId` that has format: `<cid>0<oid>`).
|
|
||||||
* Get metadata for these object using `HEAD` requests (not `Get` to reduce network traffic)
|
|
||||||
* Sort all these objects by creation epoch and object id
|
|
||||||
* Pick last object id (If no object is found then extract object id from `AccessKeyId` that has format: `<cid>0<oid>`.
|
|
||||||
We need to do this because versions of `AccessBox` can miss the `S3-Access-Box-CRDT-Name` attribute.)
|
|
||||||
* Get appropriate object from FrostFS storage
|
|
||||||
* Decrypt `AccessBox` (see [encryption](#encryption))
|
|
||||||
|
|
||||||
#### Encryption
|
|
||||||
|
|
||||||
Each `AccessBox` contains sensitive information (`AccessSecretKey`, bearer/session tokens etc.) that must be protected
|
|
||||||
and available only to trusted parties (in our case it's a s3-gw).
|
|
||||||
|
|
||||||
To encrypt/decrypt data the authenticated encryption with associated
|
|
||||||
data ([AEAD](https://en.wikipedia.org/wiki/Authenticated_encryption)) is used. The encryption algorithm
|
|
||||||
is [ChaCha20-Poly1305](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) ([RFC](https://datatracker.ietf.org/doc/html/rfc7905)).
|
|
||||||
|
|
||||||
Is the following algorithm the ECDSA keys (with curve implements NIST P-256 (FIPS 186-3, section D.2.3) also known as
|
|
||||||
secp256r1 or prime256v1) is used (unless otherwise stated).
|
|
||||||
|
|
||||||
**Encryption:**
|
|
||||||
|
|
||||||
* Create ephemeral key (`SeedKey`), it's need to generate shared secret
|
|
||||||
* Generate random 32-byte (that after hex-encoded be `SecretAccessKey`) or use existing secret access key
|
|
||||||
(if `AccessBox` is being updated rather than creating brand new)
|
|
||||||
* Generate shared secret as [ECDH](https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman)
|
|
||||||
* Derive 32-byte key using shared secret from previous step with key derivation function based on
|
|
||||||
HMAC with SHA256 [HKDF](https://en.wikipedia.org/wiki/HKDF)
|
|
||||||
* Encrypt marshaled [Tokens](../creds/accessbox) using derived key
|
|
||||||
with [ChaCha20-Poly1305](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) algorithm without additional data.
|
|
||||||
|
|
||||||
**Decryption:**
|
|
||||||
|
|
||||||
* Get public part of `SeedKey` from `AccessBox`
|
|
||||||
* Generate shared secret as follows:
|
|
||||||
* Make scalar curve multiplication of public part of `SeedKey` and private part of s3-gw key
|
|
||||||
* Use `X` part of multiplication (with zero padding at the beginning to fit 32-byte)
|
|
||||||
* Derive 32-byte key using shared secret from previous step with key derivation function based on
|
|
||||||
HMAC with SHA256 [HKDF](https://en.wikipedia.org/wiki/HKDF)
|
|
||||||
* Decrypt encrypted marshaled [Tokens](../creds/accessbox) using derived key
|
|
||||||
with [ChaCha20-Poly1305](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) algorithm without additional data.
|
|
||||||
|
|
||||||
### Policies
|
|
||||||
|
|
||||||
The main repository that contains policy implementation is https://git.frostfs.info/TrueCloudLab/policy-engine.
|
|
||||||
|
|
||||||
Policies can be stored locally (using [control api](#control-auth-process)) or in `policy` contract. When policies check
|
|
||||||
is performed the following algorithm is applied:
|
|
||||||
|
|
||||||
* Check local policies:
|
|
||||||
* If any rule was matched return checking result.
|
|
||||||
* Check contract policies:
|
|
||||||
* If any rule was matched return checking result.
|
|
||||||
* If no rules were matched return `deny` status.
|
|
||||||
|
|
||||||
To local and contract policies `deny first` scheme is applied. This means that if several rules were matched for
|
|
||||||
reqeust (with both statuses `allow` and `deny`) the resulting status be `deny`.
|
|
||||||
|
|
||||||
Policy rules validate if specified request can be performed on the specific resource. Request and resource can contain
|
|
||||||
some properties and rules can contain conditions on some such properties.
|
|
||||||
|
|
||||||
In s3-gw resource is `/bucket/object`, `/bucket` or just `/` (if request is trying to list buckets).
|
|
||||||
Currently, request that is checked contains the following properties (so policy rule can contain conditions on them):
|
|
||||||
|
|
||||||
* `Owner` - address of owner that is performing request (this is taken from bearer token from `AccessBox`)
|
|
||||||
* `frostfsid:groupID` - groups to which the owner belongs (this is taken from `frostfsid` contract)
|
|
||||||
|
|
||||||
## Control auth process
|
|
||||||
|
|
||||||
There are control path [grpc api](../pkg/service/control/service.proto) in s3-gw that also has their own authentication
|
|
||||||
and authorization process.
|
|
||||||
|
|
||||||
But this process is quite straight forward:
|
|
||||||
|
|
||||||
* Get grpc request
|
|
||||||
* Check if signing key belongs to [allowed key list](configuration.md#control-section) (that is located in config file)
|
|
||||||
* Validate signature
|
|
||||||
|
|
||||||
For signing process the asymmetric encryption based on elliptic curves (`ECDSA_SHA512`) is used.
|
|
||||||
For more details see the appropriate code
|
|
||||||
in [frostfs-api](https://git.frostfs.info/TrueCloudLab/frostfs-api/src/commit/4c68d92468503b10282c8a92af83a56f170c8a3a/refs/types.proto#L94)
|
|
||||||
and [frostfs-api-go](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/src/commit/a85146250b312fcdd6da9a71285527fed544234f/refs/types.go#L38).
|
|
|
@ -192,51 +192,17 @@ See also `GetObject` and other method parameters.
|
||||||
|
|
||||||
## Policy and replication
|
## Policy and replication
|
||||||
|
|
||||||
Bucket policy has the following limitations
|
| | Method | Comments |
|
||||||
|
|-----|-------------------------|------------------------------|
|
||||||
* Supports only AWS principals in format `arn:aws:iam::<namespace>:user/<user>` or wildcard `*`.
|
| 🟢 | DeleteBucketPolicy | |
|
||||||
* No complex conditions (only conditions for groups now supported)
|
| 🔵 | DeleteBucketReplication | |
|
||||||
|
| 🔵 | DeletePublicAccessBlock | |
|
||||||
Simple valid policy example:
|
| 🟢 | GetBucketPolicy | |
|
||||||
|
| 🔵 | GetBucketPolicyStatus | |
|
||||||
```json
|
| 🔵 | GetBucketReplication | |
|
||||||
{
|
| 🟢 | PostPolicyBucket | Upload file using POST form |
|
||||||
"Version": "2012-10-17",
|
| 🟡 | PutBucketPolicy | Conditions are not supported |
|
||||||
"Statement": [
|
| 🔵 | PutBucketReplication | |
|
||||||
{
|
|
||||||
"Principal": {
|
|
||||||
"AWS": [
|
|
||||||
"arn:aws:iam::111122223333:role/JohnDoe"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Action": [
|
|
||||||
"s3:GetObject",
|
|
||||||
"s3:GetObjectVersion"
|
|
||||||
],
|
|
||||||
"Resource": [
|
|
||||||
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Bucket policy status determines using the following scheme:
|
|
||||||
|
|
||||||
* If policy has statement with principal that is wildcard (`*`) then policy is considered as public
|
|
||||||
|
|
||||||
| | Method | Comments |
|
|
||||||
|-----|-------------------------|---------------------------------------------------|
|
|
||||||
| 🟢 | DeleteBucketPolicy | See Policy limitations |
|
|
||||||
| 🔵 | DeleteBucketReplication | |
|
|
||||||
| 🔵 | DeletePublicAccessBlock | |
|
|
||||||
| 🟢 | GetBucketPolicy | See Policy limitations |
|
|
||||||
| 🟢 | GetBucketPolicyStatus | See rule determining status in Policy limitations |
|
|
||||||
| 🔵 | GetBucketReplication | |
|
|
||||||
| 🟢 | PostPolicyBucket | Upload file using POST form |
|
|
||||||
| 🟡 | PutBucketPolicy | See Policy limitations |
|
|
||||||
| 🔵 | PutBucketReplication | |
|
|
||||||
|
|
||||||
## Request payment
|
## Request payment
|
||||||
|
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
# Bucket policy
|
|
||||||
|
|
||||||
A bucket policy is a resource-based policy that you can use to grant access permissions to your S3 bucket and the
|
|
||||||
objects in it https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-policies.html.
|
|
||||||
|
|
||||||
## Conditions
|
|
||||||
|
|
||||||
In AWS there are a lot of condition
|
|
||||||
keys https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.htm
|
|
||||||
but s3-gw currently supports only the following conditions in bucket policy:
|
|
||||||
|
|
||||||
> Note: all condition keys and values must be string formatted in json policy (even if they are numbers).
|
|
||||||
|
|
||||||
| Condition key | Description |
|
|
||||||
|-------------------------------|---------------------------------------------------------------------------|
|
|
||||||
| [s3:max-keys](#s3-max-keys) | Filters access by maximum number of keys returned in a ListBucket request |
|
|
||||||
| [s3:delimiter](#s3-delimiter) | Filters access by delimiter parameter |
|
|
||||||
| [s3:prefix](#s3-prefix) | Filters access by key name prefix |
|
|
||||||
| [s3:VersionId](#s3-versionid) | Filters access by a specific object version |
|
|
||||||
|
|
||||||
Each key can be used only with specific set of
|
|
||||||
operators https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html
|
|
||||||
(it depends on type of key).
|
|
||||||
|
|
||||||
### s3 max-keys
|
|
||||||
|
|
||||||
**Key:** `s3:max-keys`
|
|
||||||
|
|
||||||
**Type:** `Numeric`
|
|
||||||
|
|
||||||
**Description:** Filters access by maximum number of keys returned in a ListBucket request
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": {
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Principal": "*",
|
|
||||||
"Action": "s3:ListBucket",
|
|
||||||
"Resource": "arn:aws:s3:::example_bucket",
|
|
||||||
"Condition": {
|
|
||||||
"NumericLessThanEquals": {
|
|
||||||
"s3:max-keys": "10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### s3 delimiter
|
|
||||||
|
|
||||||
**Key:** `s3:delimiter`
|
|
||||||
|
|
||||||
**Type:** `String`
|
|
||||||
|
|
||||||
**Description:** Filters access by delimiter parameter
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": {
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Principal": "*",
|
|
||||||
"Action": "s3:ListBucket",
|
|
||||||
"Resource": "arn:aws:s3:::example_bucket",
|
|
||||||
"Condition": {
|
|
||||||
"StringEquals": {
|
|
||||||
"s3:delimiter": "/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### s3 prefix
|
|
||||||
|
|
||||||
**Key:** `s3:prefix`
|
|
||||||
|
|
||||||
**Type:** `String`
|
|
||||||
|
|
||||||
**Description:** Filters access by key name prefix
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": {
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Principal": {
|
|
||||||
"AWS": [
|
|
||||||
"arn:aws:iam::111122223333:user/JohnDoe"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Action": "s3:ListBucket",
|
|
||||||
"Resource": "arn:aws:s3:::example_bucket",
|
|
||||||
"Condition": {
|
|
||||||
"StringEquals": {
|
|
||||||
"s3:prefix": "home/JohnDoe"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### s3 VersionId
|
|
||||||
|
|
||||||
**Key:** `s3:VersionId`
|
|
||||||
|
|
||||||
**Type:** `String`
|
|
||||||
|
|
||||||
**Description:** Filters access by a specific object version
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": {
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Principal": {
|
|
||||||
"AWS": [
|
|
||||||
"arn:aws:iam::111122223333:user/JohnDoe"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Action": "s3:GetObjectVersion",
|
|
||||||
"Resource": "arn:aws:s3:::example_bucket/some-file.txt",
|
|
||||||
"Condition": {
|
|
||||||
"StringEquals": {
|
|
||||||
"s3:VersionId": "AT2L3qER7CHGk4TDooocEzkz2RyqTm4Zh2b1QLzAhLbH"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -218,8 +218,6 @@ max_clients_deadline: 30s
|
||||||
allowed_access_key_id_prefixes:
|
allowed_access_key_id_prefixes:
|
||||||
- Ck9BHsgKcnwfCTUSFm6pxhoNS4cBqgN2NQ8zVgPjqZDX
|
- Ck9BHsgKcnwfCTUSFm6pxhoNS4cBqgN2NQ8zVgPjqZDX
|
||||||
- 3stjWenX15YwYzczMr88gy3CQr4NYFBQ8P7keGzH5QFn
|
- 3stjWenX15YwYzczMr88gy3CQr4NYFBQ8P7keGzH5QFn
|
||||||
|
|
||||||
reconnect_interval: 1m
|
|
||||||
```
|
```
|
||||||
|
|
||||||
| Parameter | Type | SIGHUP reload | Default value | Description |
|
| Parameter | Type | SIGHUP reload | Default value | Description |
|
||||||
|
@ -235,7 +233,6 @@ reconnect_interval: 1m
|
||||||
| `max_clients_count` | `int` | no | `100` | Limits for processing of clients' requests. |
|
| `max_clients_count` | `int` | no | `100` | Limits for processing of clients' requests. |
|
||||||
| `max_clients_deadline` | `duration` | no | `30s` | Deadline after which the gate sends error `RequestTimeout` to a client. |
|
| `max_clients_deadline` | `duration` | no | `30s` | Deadline after which the gate sends error `RequestTimeout` to a client. |
|
||||||
| `allowed_access_key_id_prefixes` | `[]string` | no | | List of allowed `AccessKeyID` prefixes which S3 GW serve. If the parameter is omitted, all `AccessKeyID` will be accepted. |
|
| `allowed_access_key_id_prefixes` | `[]string` | no | | List of allowed `AccessKeyID` prefixes which S3 GW serve. If the parameter is omitted, all `AccessKeyID` will be accepted. |
|
||||||
| `reconnect_interval` | `duration` | no | `1m` | Listeners reconnection interval. |
|
|
||||||
|
|
||||||
### `wallet` section
|
### `wallet` section
|
||||||
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
@startuml
|
|
||||||
|
|
||||||
package AccessBox {
|
|
||||||
map Tokens {
|
|
||||||
SecretKey => Private key
|
|
||||||
BearerToken => Encoded bearer token
|
|
||||||
SessionTokens => List of encoded session tokens
|
|
||||||
}
|
|
||||||
|
|
||||||
map Gate {
|
|
||||||
GateKey => Encoded public gate key
|
|
||||||
Encrypted tokens *--> Tokens
|
|
||||||
}
|
|
||||||
|
|
||||||
map ContainerPolicy {
|
|
||||||
LocationConstraint => Policy name
|
|
||||||
PlacementPolicy => Encoded placement policy
|
|
||||||
}
|
|
||||||
|
|
||||||
map Box {
|
|
||||||
SeedKey => Encoded public seed key
|
|
||||||
List of Gates *--> Gate
|
|
||||||
List of container policies *--> ContainerPolicy
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
map ObjectAttributes {
|
|
||||||
Timestamp => 1710418478
|
|
||||||
_~_SYSTEM_~_EXPIRATION_EPOCH => 10801
|
|
||||||
S3-CRDT-Versions-Add => 5ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3Snxf,9bLtL1EsUpuSiqmHnqFf6RuT6x5QMLMNBqx7vCcCcNhy
|
|
||||||
S3-Access-Box-CRDT-Name => 2XGRML5EW3LMHdf64W2DkBy1Nkuu4y4wGhUj44QjbXBi05ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3Snxf
|
|
||||||
FilePath => 1710418478_access.box
|
|
||||||
}
|
|
||||||
|
|
||||||
map FrostFSObject {
|
|
||||||
Header *-> ObjectAttributes
|
|
||||||
Payload *--> Box
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@enduml
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 13 KiB |
|
@ -1,29 +0,0 @@
|
||||||
@startuml
|
|
||||||
|
|
||||||
User -> "S3-GW": AccessKey
|
|
||||||
"S3-GW" -> "FrostFS Node": Search objects
|
|
||||||
|
|
||||||
note right
|
|
||||||
Search by exact attribute matching:
|
|
||||||
**S3-Access-Box-CRDT-Name:** //AccessKey//
|
|
||||||
end note
|
|
||||||
|
|
||||||
"FrostFS Node" --> "S3-GW": AccessBox objects ids
|
|
||||||
|
|
||||||
"S3-GW" -> "FrostFS Node" : Head AccessBox objects
|
|
||||||
"FrostFS Node" --> "S3-GW": AccessBox object headers
|
|
||||||
|
|
||||||
"S3-GW" -> "S3-GW": Choose latest AccessBox
|
|
||||||
|
|
||||||
note left
|
|
||||||
Sort AccessBox headers by creation epoch
|
|
||||||
and then by ObjectID
|
|
||||||
Pick last
|
|
||||||
end note
|
|
||||||
|
|
||||||
"S3-GW" -> "FrostFS Node" : Get AccessBox object
|
|
||||||
"FrostFS Node" --> "S3-GW": AccessBox object
|
|
||||||
|
|
||||||
"S3-GW" -> "S3-GW": Decrypt and validate AccessBox
|
|
||||||
|
|
||||||
@enduml
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 8.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 133 KiB |
|
@ -1,25 +0,0 @@
|
||||||
@startuml
|
|
||||||
!include <c4/C4_Container.puml>
|
|
||||||
AddElementTag("smart-contract", $bgColor=#0abab5)
|
|
||||||
|
|
||||||
Person(user, "User", "User with or without credentials")
|
|
||||||
|
|
||||||
System_Boundary(c1, "FrostFS") {
|
|
||||||
Container(s3, "S3 Gateway", $descr="AWS S3 compatible gate")
|
|
||||||
Container(stor, "FrostFS Storage", $descr="Storage service")
|
|
||||||
}
|
|
||||||
|
|
||||||
System_Boundary(c3, "Blockchain") {
|
|
||||||
Interface "NeoGo"
|
|
||||||
Container(ffsid, "FrostFS ID", $tags="smart-contract", $descr="Stores namespaces and users")
|
|
||||||
Container(policy, "Policy", $tags="smart-contract", $descr="Stores APE rules")
|
|
||||||
}
|
|
||||||
|
|
||||||
Rel_R(user, s3, "Requests", "HTTP")
|
|
||||||
Rel_R(s3, stor, "Get data to validate request, store objects")
|
|
||||||
Rel_D(s3, NeoGo, "Get data to validate request")
|
|
||||||
Rel("NeoGo", ffsid, "Fetch users")
|
|
||||||
Rel("NeoGo", policy, "Fetch policies")
|
|
||||||
|
|
||||||
SHOW_LEGEND(true)
|
|
||||||
@enduml
|
|
|
@ -1,611 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="660px" preserveAspectRatio="none" style="width:851px;height:660px;background:#FFFFFF;" version="1.1" viewBox="0 0 851 660" width="851px" zoomAndPan="magnify"><defs/><g><!--MD5=[84dda40acb3410cad7262261daba2aaf]
|
|
||||||
cluster c1--><g id="cluster_c1"><rect fill="none" height="152" rx="2.5" ry="2.5" style="stroke:#444444;stroke-width:1.0;stroke-dasharray:7.0,7.0;" width="587" x="258" y="7"/><text fill="#444444" font-family="sans-serif" font-size="16" font-weight="bold" lengthAdjust="spacing" textLength="71" x="516" y="23.8516">FrostFS</text><text fill="#444444" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="61" x="521" y="38.7637">[System]</text></g><!--MD5=[fb252dd5a834d4be8567d0df3f6bbec4]
|
|
||||||
cluster c3--><g id="cluster_c3"><rect fill="none" height="301" rx="2.5" ry="2.5" style="stroke:#444444;stroke-width:1.0;stroke-dasharray:7.0,7.0;" width="405" x="259" y="243.5"/><text fill="#444444" font-family="sans-serif" font-size="16" font-weight="bold" lengthAdjust="spacing" textLength="95" x="414" y="260.3516">Blockchain</text><text fill="#444444" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="61" x="431" y="275.2637">[System]</text></g><!--MD5=[b165ca7cce796f881c879adda4a6bef9]
|
|
||||||
entity s3--><g id="elem_s3"><rect fill="#438DD5" height="85.1875" rx="2.5" ry="2.5" style="stroke:#3C7FC0;stroke-width:0.5;" width="199" x="274.5" y="58"/><text fill="#FFFFFF" font-family="sans-serif" font-size="16" font-weight="bold" lengthAdjust="spacing" textLength="108" x="320" y="82.8516">S3 Gateway</text><text fill="#FFFFFF" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="10" x="369" y="97.7637">[]</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="372" y="113.5889"> </text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="175" x="288.5" y="129.8857">AWS S3 compatible gate</text></g><!--MD5=[b631bc93683c8d3c6bcd86869bd62c2d]
|
|
||||||
entity stor--><g id="elem_stor"><rect fill="#438DD5" height="85.1875" rx="2.5" ry="2.5" style="stroke:#3C7FC0;stroke-width:0.5;" width="169" x="660.5" y="58"/><text fill="#FFFFFF" font-family="sans-serif" font-size="16" font-weight="bold" lengthAdjust="spacing" textLength="149" x="670.5" y="82.8516">FrostFS Storage</text><text fill="#FFFFFF" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="10" x="740" y="97.7637">[]</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="743" y="113.5889"> </text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="111" x="691.5" y="129.8857">Storage service</text></g><!--MD5=[d75780de534459f9083ff96c63e26824]
|
|
||||||
entity NeoGo--><g id="elem_NeoGo"><ellipse cx="374" cy="323.5" fill="#F1F1F1" rx="8" ry="8" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="48" x="350" y="353.4951">NeoGo</text></g><!--MD5=[a1c7fbed12783ec305c3357d72c64f9e]
|
|
||||||
entity ffsid--><g id="elem_ffsid"><rect fill="#0ABAB5" height="101.4844" rx="2.5" ry="2.5" style="stroke:#3C7FC0;stroke-width:0.5;" width="198" x="275" y="427.5"/><text fill="#FFFFFF" font-family="sans-serif" font-size="16" font-weight="bold" lengthAdjust="spacing" textLength="96" x="326" y="452.3516">FrostFS ID</text><text fill="#FFFFFF" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="10" x="369" y="467.2637">[]</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="372" y="483.0889"> </text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="170" x="289" y="499.3857">Stores namespaces and</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="38" x="355" y="515.6826">users</text></g><!--MD5=[4361443624774238dacd0e01c3165ecf]
|
|
||||||
entity policy--><g id="elem_policy"><rect fill="#0ABAB5" height="85.1875" rx="2.5" ry="2.5" style="stroke:#3C7FC0;stroke-width:0.5;" width="139" x="508.5" y="435.5"/><text fill="#FFFFFF" font-family="sans-serif" font-size="16" font-weight="bold" lengthAdjust="spacing" textLength="52" x="552" y="460.3516">Policy</text><text fill="#FFFFFF" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="10" x="573" y="475.2637">[]</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="576" y="491.0889"> </text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="115" x="522.5" y="507.3857">Stores APE rules</text></g><!--MD5=[8fc3522a43f8c7199df5e09e5bb0188e]
|
|
||||||
entity user--><g id="elem_user"><rect fill="#08427B" height="135.5156" rx="2.5" ry="2.5" style="stroke:#073B6F;stroke-width:0.5;" width="168" x="7" y="32.5"/><image height="48" width="48" x="67" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=" y="42.5"/><text fill="#FFFFFF" font-family="sans-serif" font-size="16" font-weight="bold" lengthAdjust="spacing" textLength="42" x="70" y="105.3516">User</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="89" y="122.1201"> </text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="140" x="21" y="138.417">User with or without</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="79" x="51.5" y="154.7139">credentials</text></g><!--MD5=[52d0c115c7d06b979b7f69659773ccc0]
|
|
||||||
link user to s3--><g id="link_user_s3"><path d="M175.14,100.5 C203.78,100.5 236.2,100.5 266.42,100.5 " fill="none" id="user-to-s3" style="stroke:#666666;stroke-width:1.0;"/><polygon fill="#666666" points="274.47,100.5,266.47,97.5,266.47,103.5,274.47,100.5" style="stroke:#666666;stroke-width:1.0;"/><text fill="#666666" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="63" x="193.25" y="80.6387">Requests</text><text fill="#666666" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="40" x="204.75" y="94.6074">[HTTP]</text></g><!--MD5=[22d466a8c2458259cbad703a0636b8fb]
|
|
||||||
link s3 to stor--><g id="link_s3_stor"><path d="M473.91,100.5 C529.33,100.5 597.81,100.5 652.08,100.5 " fill="none" id="s3-to-stor" style="stroke:#666666;stroke-width:1.0;"/><polygon fill="#666666" points="660.32,100.5,652.32,97.5,652.32,103.5,660.32,100.5" style="stroke:#666666;stroke-width:1.0;"/><text fill="#666666" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="136" x="497" y="80.6387">Get data to validate</text><text fill="#666666" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="150" x="492" y="94.6074">request, store objects</text></g><!--MD5=[8c98dd26c815ae7a8024bcc2d9dd4f66]
|
|
||||||
link s3 to NeoGo--><g id="link_s3_NeoGo"><path d="M374,143.07 C374,192.21 374,271.65 374,305.9 " fill="none" id="s3-to-NeoGo" style="stroke:#666666;stroke-width:1.0;"/><polygon fill="#666666" points="374,314.3,377,306.3,371,306.3,374,314.3" style="stroke:#666666;stroke-width:1.0;"/><text fill="#666666" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="136" x="375" y="210.6387">Get data to validate</text><text fill="#666666" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="53" x="418.5" y="224.6074">request</text></g><!--MD5=[67f0c0ebd6d2a23c30e202ac0cd81435]
|
|
||||||
link NeoGo to ffsid--><g id="link_NeoGo_ffsid"><path d="M374,332.7 C374,348.95 374,386.52 374,419.25 " fill="none" id="NeoGo-to-ffsid" style="stroke:#666666;stroke-width:1.0;"/><polygon fill="#666666" points="374,427.45,377,419.45,371,419.45,374,427.45" style="stroke:#666666;stroke-width:1.0;"/><text fill="#666666" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="79" x="375" y="394.6387">Fetch users</text></g><!--MD5=[d37da9b99a3aca6bfa9447725e2e6374]
|
|
||||||
link NeoGo to policy--><g id="link_NeoGo_policy"><path d="M383.06,329.95 C399.4,339.87 434.74,361.78 463,382.5 C483.22,397.33 504.63,414.49 523.43,430.09 " fill="none" id="NeoGo-to-policy" style="stroke:#666666;stroke-width:1.0;"/><polygon fill="#666666" points="529.7,435.31,525.4816,427.88,521.6363,432.4858,529.7,435.31" style="stroke:#666666;stroke-width:1.0;"/><text fill="#666666" font-family="sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="93" x="483" y="394.6387">Fetch policies</text></g><rect fill="none" height="16.2969" style="stroke:none;stroke-width:1.0;" width="236" x="584" y="568.5"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="59" x="584" y="581.4951">Legend</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="643" y="581.4951"> </text><rect fill="#08427B" height="16.2969" style="stroke:none;stroke-width:1.0;" width="236" x="584" y="584.7969"/><text fill="#073B6F" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="8" x="588" y="597.792">▯</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="596" y="597.792"> </text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="49" x="604" y="597.792">person</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="657" y="597.792"> </text><rect fill="#438DD5" height="16.2969" style="stroke:none;stroke-width:1.0;" width="236" x="584" y="601.0938"/><text fill="#3C7FC0" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="8" x="588" y="614.0889">▯</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="596" y="614.0889"> </text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="68" x="604" y="614.0889">container</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="676" y="614.0889"> </text><rect fill="#0ABAB5" height="16.2969" style="stroke:none;stroke-width:1.0;" width="236" x="584" y="617.3906"/><text fill="#0ABAB5" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="8" x="588" y="630.3857">▯</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="596" y="630.3857"> </text><text fill="#66622E" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="208" x="604" y="630.3857">smart-contract (no text color)</text><text fill="#FFFFFF" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="4" x="816" y="630.3857"> </text><line style="stroke:none;stroke-width:1.0;" x1="584" x2="820" y1="568.5" y2="568.5"/><line style="stroke:none;stroke-width:1.0;" x1="584" x2="820" y1="584.7969" y2="584.7969"/><line style="stroke:none;stroke-width:1.0;" x1="584" x2="820" y1="601.0938" y2="601.0938"/><line style="stroke:none;stroke-width:1.0;" x1="584" x2="820" y1="617.3906" y2="617.3906"/><line style="stroke:none;stroke-width:1.0;" x1="584" x2="820" y1="633.6875" y2="633.6875"/><line style="stroke:none;stroke-width:1.0;" x1="584" x2="584" y1="568.5" y2="633.6875"/><line style="stroke:none;stroke-width:1.0;" x1="820" x2="820" y1="568.5" y2="633.6875"/><!--MD5=[c02d88aa5b998c40021c1d715125d393]
|
|
||||||
@startuml
|
|
||||||
!include <c4/C4_Container.puml>
|
|
||||||
AddElementTag("smart-contract", $bgColor=#0abab5)
|
|
||||||
|
|
||||||
Person(user, "User", "User with or without credentials")
|
|
||||||
|
|
||||||
System_Boundary(c1, "FrostFS") {
|
|
||||||
Container(s3, "S3 Gateway", $descr="AWS S3 compatible gate")
|
|
||||||
Container(stor, "FrostFS Storage", $descr="Storage service")
|
|
||||||
}
|
|
||||||
|
|
||||||
System_Boundary(c3, "Blockchain") {
|
|
||||||
Interface "NeoGo"
|
|
||||||
Container(ffsid, "FrostFS ID", $tags="smart-contract", $descr="Stores namespaces and users")
|
|
||||||
Container(policy, "Policy", $tags="smart-contract", $descr="Stores APE rules")
|
|
||||||
}
|
|
||||||
|
|
||||||
Rel_R(user, s3, "Requests", "HTTP")
|
|
||||||
Rel_R(s3, stor, "Get data to validate request, store objects")
|
|
||||||
Rel_D(s3, NeoGo, "Get data to validate request")
|
|
||||||
Rel("NeoGo", ffsid, "Fetch users")
|
|
||||||
Rel("NeoGo", policy, "Fetch policies")
|
|
||||||
|
|
||||||
SHOW_LEGEND(true)
|
|
||||||
@enduml
|
|
||||||
|
|
||||||
@startuml
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
skinparam defaultTextAlignment center
|
|
||||||
|
|
||||||
skinparam wrapWidth 200
|
|
||||||
skinparam maxMessageSize 150
|
|
||||||
|
|
||||||
skinparam LegendBorderColor transparent
|
|
||||||
skinparam LegendBackgroundColor transparent
|
|
||||||
skinparam LegendFontColor #FFFFFF
|
|
||||||
|
|
||||||
skinparam shadowing<<legendArea>> false
|
|
||||||
skinparam rectangle<<legendArea>> {
|
|
||||||
backgroundcolor #00000000
|
|
||||||
bordercolor #00000000
|
|
||||||
}
|
|
||||||
|
|
||||||
skinparam rectangle {
|
|
||||||
StereotypeFontSize 12
|
|
||||||
shadowing false
|
|
||||||
}
|
|
||||||
|
|
||||||
skinparam database {
|
|
||||||
StereotypeFontSize 12
|
|
||||||
shadowing false
|
|
||||||
}
|
|
||||||
|
|
||||||
skinparam queue {
|
|
||||||
StereotypeFontSize 12
|
|
||||||
shadowing false
|
|
||||||
}
|
|
||||||
|
|
||||||
skinparam arrow {
|
|
||||||
Color #666666
|
|
||||||
FontColor #666666
|
|
||||||
FontSize 12
|
|
||||||
}
|
|
||||||
|
|
||||||
skinparam actor {
|
|
||||||
StereotypeFontSize 12
|
|
||||||
shadowing false
|
|
||||||
style awesome
|
|
||||||
}
|
|
||||||
|
|
||||||
skinparam person {
|
|
||||||
StereotypeFontSize 12
|
|
||||||
shadowing false
|
|
||||||
}
|
|
||||||
|
|
||||||
skinparam package {
|
|
||||||
StereotypeFontSize 6
|
|
||||||
StereotypeFontColor transparent
|
|
||||||
FontStyle plain
|
|
||||||
BackgroundColor transparent
|
|
||||||
}
|
|
||||||
|
|
||||||
skinparam rectangle<<boundary>> {
|
|
||||||
Shadowing false
|
|
||||||
StereotypeFontSize 6
|
|
||||||
StereotypeFontColor transparent
|
|
||||||
FontColor #444444
|
|
||||||
BorderColor #444444
|
|
||||||
BackgroundColor transparent
|
|
||||||
BorderStyle dashed
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
skinparam rectangle<<person>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #08427B
|
|
||||||
BorderColor #073B6F
|
|
||||||
}
|
|
||||||
skinparam database<<person>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #08427B
|
|
||||||
BorderColor #073B6F
|
|
||||||
}
|
|
||||||
skinparam queue<<person>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #08427B
|
|
||||||
BorderColor #073B6F
|
|
||||||
}
|
|
||||||
skinparam actor<<person>> {
|
|
||||||
StereotypeFontColor #08427B
|
|
||||||
FontColor #08427B
|
|
||||||
BackgroundColor #08427B
|
|
||||||
BorderColor #073B6F
|
|
||||||
}
|
|
||||||
skinparam person<<person>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #08427B
|
|
||||||
BorderColor #073B6F
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
skinparam rectangle<<external_person>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #686868
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
skinparam database<<external_person>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #686868
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
skinparam queue<<external_person>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #686868
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
skinparam actor<<external_person>> {
|
|
||||||
StereotypeFontColor #686868
|
|
||||||
FontColor #686868
|
|
||||||
BackgroundColor #686868
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
skinparam person<<external_person>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #686868
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
skinparam rectangle<<system>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #1168BD
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
skinparam database<<system>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #1168BD
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
skinparam queue<<system>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #1168BD
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
skinparam actor<<system>> {
|
|
||||||
StereotypeFontColor #1168BD
|
|
||||||
FontColor #1168BD
|
|
||||||
BackgroundColor #1168BD
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
skinparam person<<system>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #1168BD
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
skinparam rectangle<<external_system>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #999999
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
skinparam database<<external_system>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #999999
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
skinparam queue<<external_system>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #999999
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
skinparam actor<<external_system>> {
|
|
||||||
StereotypeFontColor #999999
|
|
||||||
FontColor #999999
|
|
||||||
BackgroundColor #999999
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
skinparam person<<external_system>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #999999
|
|
||||||
BorderColor #8A8A8A
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sprite $person [48x48/16] {
|
|
||||||
000000000000000000000000000000000000000000000000
|
|
||||||
000000000000000000000000000000000000000000000000
|
|
||||||
0000000000000000000049BCCA7200000000000000000000
|
|
||||||
0000000000000000006EFFFFFFFFB3000000000000000000
|
|
||||||
00000000000000001CFFFFFFFFFFFF700000000000000000
|
|
||||||
0000000000000001EFFFFFFFFFFFFFF80000000000000000
|
|
||||||
000000000000000CFFFFFFFFFFFFFFFF6000000000000000
|
|
||||||
000000000000007FFFFFFFFFFFFFFFFFF100000000000000
|
|
||||||
00000000000001FFFFFFFFFFFFFFFFFFF900000000000000
|
|
||||||
00000000000006FFFFFFFFFFFFFFFFFFFF00000000000000
|
|
||||||
0000000000000BFFFFFFFFFFFFFFFFFFFF40000000000000
|
|
||||||
0000000000000EFFFFFFFFFFFFFFFFFFFF70000000000000
|
|
||||||
0000000000000FFFFFFFFFFFFFFFFFFFFF80000000000000
|
|
||||||
0000000000000FFFFFFFFFFFFFFFFFFFFF80000000000000
|
|
||||||
0000000000000DFFFFFFFFFFFFFFFFFFFF60000000000000
|
|
||||||
0000000000000AFFFFFFFFFFFFFFFFFFFF40000000000000
|
|
||||||
00000000000006FFFFFFFFFFFFFFFFFFFE00000000000000
|
|
||||||
00000000000000EFFFFFFFFFFFFFFFFFF800000000000000
|
|
||||||
000000000000007FFFFFFFFFFFFFFFFFF100000000000000
|
|
||||||
000000000000000BFFFFFFFFFFFFFFFF5000000000000000
|
|
||||||
0000000000000001DFFFFFFFFFFFFFF70000000000000000
|
|
||||||
00000000000000000BFFFFFFFFFFFF500000000000000000
|
|
||||||
0000000000000000005DFFFFFFFFA1000000000000000000
|
|
||||||
0000000000000000000037ABB96100000000000000000000
|
|
||||||
000000000000000000000000000000000000000000000000
|
|
||||||
000000000000000000000000000000000000000000000000
|
|
||||||
000000000000025788300000000005886410000000000000
|
|
||||||
000000000007DFFFFFFD9643347BFFFFFFFB400000000000
|
|
||||||
0000000004EFFFFFFFFFFFFFFFFFFFFFFFFFFB1000000000
|
|
||||||
000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFD200000000
|
|
||||||
00000006FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE10000000
|
|
||||||
0000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0000000
|
|
||||||
000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5000000
|
|
||||||
000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD000000
|
|
||||||
000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF200000
|
|
||||||
00000DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF600000
|
|
||||||
00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF800000
|
|
||||||
00001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA00000
|
|
||||||
00001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB00000
|
|
||||||
00001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB00000
|
|
||||||
00001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB00000
|
|
||||||
00001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA00000
|
|
||||||
00000EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF700000
|
|
||||||
000006FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE100000
|
|
||||||
0000008FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3000000
|
|
||||||
000000014555555555555555555555555555555300000000
|
|
||||||
000000000000000000000000000000000000000000000000
|
|
||||||
000000000000000000000000000000000000000000000000
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite $person2 [48x48/16] {
|
|
||||||
0000000000000000000049BCCA7200000000000000000000
|
|
||||||
0000000000000000006EFFFFFFFFB3000000000000000000
|
|
||||||
00000000000000001CFFFFFFFFFFFF700000000000000000
|
|
||||||
0000000000000001EFFFFFFFFFFFFFF80000000000000000
|
|
||||||
000000000000000CFFFFFFFFFFFFFFFF6000000000000000
|
|
||||||
000000000000007FFFFFFFFFFFFFFFFFF100000000000000
|
|
||||||
00000000000001FFFFFFFFFFFFFFFFFFF900000000000000
|
|
||||||
00000000000006FFFFFFFFFFFFFFFFFFFF00000000000000
|
|
||||||
0000000000000BFFFFFFFFFFFFFFFFFFFF40000000000000
|
|
||||||
0000000000000EFFFFFFFFFFFFFFFFFFFF70000000000000
|
|
||||||
0000000000000FFFFFFFFFFFFFFFFFFFFF80000000000000
|
|
||||||
0000000000000FFFFFFFFFFFFFFFFFFFFF80000000000000
|
|
||||||
0000000000000DFFFFFFFFFFFFFFFFFFFF60000000000000
|
|
||||||
0000000000000AFFFFFFFFFFFFFFFFFFFF40000000000000
|
|
||||||
00000000000006FFFFFFFFFFFFFFFFFFFE00000000000000
|
|
||||||
00000000000000EFFFFFFFFFFFFFFFFFF800000000000000
|
|
||||||
000000000000007FFFFFFFFFFFFFFFFFF100000000000000
|
|
||||||
000000000000000BFFFFFFFFFFFFFFFF5000000000000000
|
|
||||||
0000000000000001DFFFFFFFFFFFFFF70000000000000000
|
|
||||||
00000000000000000BFFFFFFFFFFFF500000000000000000
|
|
||||||
0000000000000000005DFFFFFFFFA1000000000000000000
|
|
||||||
0000000000000000000037ABB96100000000000000000000
|
|
||||||
000000000002578888300000000005888864100000000000
|
|
||||||
0000000007DFFFFFFFFD9643347BFFFFFFFFFB4000000000
|
|
||||||
00000004EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB10000000
|
|
||||||
0000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2000000
|
|
||||||
000006FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE100000
|
|
||||||
00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB00000
|
|
||||||
0000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50000
|
|
||||||
0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0000
|
|
||||||
0009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2000
|
|
||||||
000DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6000
|
|
||||||
000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000
|
|
||||||
001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB000
|
|
||||||
001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB000
|
|
||||||
001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB000
|
|
||||||
001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA000
|
|
||||||
000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000
|
|
||||||
000DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6000
|
|
||||||
0009FFFFFFFF8FFFFFFFFFFFFFFFFFFFFFF8FFFFFFFF2000
|
|
||||||
0003FFFFFFFF8FFFFFFFFFFFFFFFFFFFFFF8FFFFFFFD0000
|
|
||||||
0000BFFFFFFF8FFFFFFFFFFFFFFFFFFFFFF8FFFFFFF50000
|
|
||||||
00003FFFFFFF8FFFFFFFFFFFFFFFFFFFFFF8FFFFFFB00000
|
|
||||||
000006FFFFFF8FFFFFFFFFFFFFFFFFFFFFF8FFFFFE100000
|
|
||||||
0000007FFFFF8FFFFFFFFFFFFFFFFFFFFFF8FFFFD2000000
|
|
||||||
00000004EFFF8FFFFFFFFFFFFFFFFFFFFFF8FFFB10000000
|
|
||||||
0000000007DF8FFFFFFFFFFFFFFFFFFFFFF8FB4000000000
|
|
||||||
000000000002578888888888888888888864100000000000
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
skinparam rectangle<<container>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #438DD5
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
skinparam database<<container>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #438DD5
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
skinparam queue<<container>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #438DD5
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
skinparam actor<<container>> {
|
|
||||||
StereotypeFontColor #438DD5
|
|
||||||
FontColor #438DD5
|
|
||||||
BackgroundColor #438DD5
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
skinparam person<<container>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #438DD5
|
|
||||||
BorderColor #3C7FC0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
skinparam rectangle<<external_container>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #B3B3B3
|
|
||||||
BorderColor #A6A6A6
|
|
||||||
}
|
|
||||||
skinparam database<<external_container>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #B3B3B3
|
|
||||||
BorderColor #A6A6A6
|
|
||||||
}
|
|
||||||
skinparam queue<<external_container>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #B3B3B3
|
|
||||||
BorderColor #A6A6A6
|
|
||||||
}
|
|
||||||
skinparam actor<<external_container>> {
|
|
||||||
StereotypeFontColor #B3B3B3
|
|
||||||
FontColor #B3B3B3
|
|
||||||
BackgroundColor #B3B3B3
|
|
||||||
BorderColor #A6A6A6
|
|
||||||
}
|
|
||||||
skinparam person<<external_container>> {
|
|
||||||
StereotypeFontColor #FFFFFF
|
|
||||||
FontColor #FFFFFF
|
|
||||||
BackgroundColor #B3B3B3
|
|
||||||
BorderColor #A6A6A6
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
skinparam rectangle<<smart-contract>> {
|
|
||||||
BackgroundColor #0abab5
|
|
||||||
}
|
|
||||||
skinparam database<<smart-contract>> {
|
|
||||||
BackgroundColor #0abab5
|
|
||||||
}
|
|
||||||
skinparam queue<<smart-contract>> {
|
|
||||||
BackgroundColor #0abab5
|
|
||||||
}
|
|
||||||
skinparam actor<<smart-contract>> {
|
|
||||||
StereotypeFontColor #0abab5
|
|
||||||
FontColor #0abab5
|
|
||||||
BackgroundColor #0abab5
|
|
||||||
}
|
|
||||||
skinparam person<<smart-contract>> {
|
|
||||||
BackgroundColor #0abab5
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rectangle "<$person>\n==User\n\n User with or without credentials" <<person>> as user
|
|
||||||
|
|
||||||
rectangle "==FrostFS\n<size:12>[System]</size>" <<boundary>> as c1 {
|
|
||||||
rectangle "==S3 Gateway\n//<size:12>[]</size>//\n\n AWS S3 compatible gate" <<container>> as s3
|
|
||||||
rectangle "==FrostFS Storage\n//<size:12>[]</size>//\n\n Storage service" <<container>> as stor
|
|
||||||
}
|
|
||||||
|
|
||||||
rectangle "==Blockchain\n<size:12>[System]</size>" <<boundary>> as c3 {
|
|
||||||
Interface "NeoGo"
|
|
||||||
rectangle "==FrostFS ID\n//<size:12>[]</size>//\n\n Stores namespaces and users" <<smart-contract>><<container>> as ffsid
|
|
||||||
rectangle "==Policy\n//<size:12>[]</size>//\n\n Stores APE rules" <<smart-contract>><<container>> as policy
|
|
||||||
}
|
|
||||||
|
|
||||||
user -RIGHT->> s3 : **Requests**\n//<size:12>[HTTP]</size>//
|
|
||||||
s3 -RIGHT->> stor : **Get data to validate request, store objects**
|
|
||||||
s3 -DOWN->> NeoGo : **Get data to validate request**
|
|
||||||
NeoGo - ->> ffsid : **Fetch users**
|
|
||||||
NeoGo - ->> policy : **Fetch policies**
|
|
||||||
|
|
||||||
hide stereotype
|
|
||||||
legend right
|
|
||||||
<#00000000,#00000000>|<color:#000000>**Legend**</color> |
|
|
||||||
|<#08427B><color:#073B6F> <U+25AF></color> <color:#FFFFFF> person </color> |
|
|
||||||
|<#438DD5><color:#3C7FC0> <U+25AF></color> <color:#FFFFFF> container </color> |
|
|
||||||
|<#0abab5><color:#0abab5> <U+25AF></color> <color:#66622E> smart-contract (no text color) </color> |
|
|
||||||
endlegend
|
|
||||||
@enduml
|
|
||||||
|
|
||||||
PlantUML version 1.2022.13(Sat Nov 19 16:22:17 MSK 2022)
|
|
||||||
(GPL source distribution)
|
|
||||||
Java Runtime: OpenJDK Runtime Environment
|
|
||||||
JVM: OpenJDK 64-Bit Server VM
|
|
||||||
Default Encoding: UTF-8
|
|
||||||
Language: en
|
|
||||||
Country: US
|
|
||||||
--></g></svg>
|
|
Before Width: | Height: | Size: 25 KiB |
|
@ -1,60 +0,0 @@
|
||||||
@startuml
|
|
||||||
|
|
||||||
participant User
|
|
||||||
participant "S3-GW"
|
|
||||||
collections "FrostFS Storage"
|
|
||||||
|
|
||||||
User -> "S3-GW": Request
|
|
||||||
|
|
||||||
group signed request
|
|
||||||
|
|
||||||
"S3-GW" -> "FrostFS Storage": Find Access Box
|
|
||||||
"FrostFS Storage" -> "FrostFS Storage": Check request
|
|
||||||
|
|
||||||
alt #pink Check failure
|
|
||||||
"FrostFS Storage" -->> "S3-GW": Access Denied
|
|
||||||
"S3-GW" -->> User: Access Denied
|
|
||||||
end
|
|
||||||
|
|
||||||
"FrostFS Storage" -->> "S3-GW": Access Box
|
|
||||||
"S3-GW" -> "S3-GW": Check sign
|
|
||||||
|
|
||||||
alt #pink Check failure
|
|
||||||
"S3-GW" -->> User: Access Denied
|
|
||||||
end
|
|
||||||
|
|
||||||
"S3-GW" -> "frostfsid contract": Find user
|
|
||||||
"frostfsid contract" -->> "S3-GW": User info
|
|
||||||
"S3-GW" -> "S3-GW": Check user info
|
|
||||||
|
|
||||||
alt #pink Check failure
|
|
||||||
"S3-GW" -->> User: Access Denied
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
"S3-GW" -> "policy contract": Get policies
|
|
||||||
"policy contract" -->> "S3-GW": Policies
|
|
||||||
"S3-GW" -> "S3-GW": Check policy
|
|
||||||
|
|
||||||
alt #pink Check failure
|
|
||||||
"S3-GW" -->> User: Access Denied
|
|
||||||
end
|
|
||||||
|
|
||||||
"S3-GW" -> "FrostFS Storage": User Request
|
|
||||||
"FrostFS Storage" -> "FrostFS Storage": Check request
|
|
||||||
|
|
||||||
alt #pink Check failure
|
|
||||||
"FrostFS Storage" -->> "S3-GW": Access Denied
|
|
||||||
"S3-GW" -->> User: Access Denied
|
|
||||||
end
|
|
||||||
|
|
||||||
"FrostFS Storage" -->> "S3-GW": Response
|
|
||||||
"S3-GW" -->> User: Response
|
|
||||||
|
|
||||||
box "Neo Go"
|
|
||||||
participant "frostfsid contract"
|
|
||||||
participant "policy contract"
|
|
||||||
end box
|
|
||||||
|
|
||||||
@enduml
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 19 KiB |
Binary file not shown.
Before Width: | Height: | Size: 35 KiB |
8
go.mod
8
go.mod
|
@ -3,11 +3,11 @@ module git.frostfs.info/TrueCloudLab/frostfs-s3-gw
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240327095603-491a47e7fe24
|
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240306101814-c1c7b344b9c0
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409115729-6eb492025bdd
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409115729-6eb492025bdd
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6
|
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141549-3790142b10c7
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141532-e5040d35e99d
|
||||||
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412102212-530248de754c
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412130734-0e69e485115a
|
||||||
git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02
|
git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02
|
||||||
github.com/aws/aws-sdk-go v1.44.6
|
github.com/aws/aws-sdk-go v1.44.6
|
||||||
github.com/bluele/gcache v0.0.2
|
github.com/bluele/gcache v0.0.2
|
||||||
|
@ -30,7 +30,6 @@ require (
|
||||||
go.uber.org/zap v1.26.0
|
go.uber.org/zap v1.26.0
|
||||||
golang.org/x/crypto v0.17.0
|
golang.org/x/crypto v0.17.0
|
||||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
|
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
|
||||||
golang.org/x/net v0.17.0
|
|
||||||
google.golang.org/grpc v1.59.0
|
google.golang.org/grpc v1.59.0
|
||||||
google.golang.org/protobuf v1.33.0
|
google.golang.org/protobuf v1.33.0
|
||||||
)
|
)
|
||||||
|
@ -92,6 +91,7 @@ require (
|
||||||
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
|
golang.org/x/net v0.17.0 // indirect
|
||||||
golang.org/x/sync v0.3.0 // indirect
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
golang.org/x/sys v0.15.0 // indirect
|
golang.org/x/sys v0.15.0 // indirect
|
||||||
golang.org/x/term v0.15.0 // indirect
|
golang.org/x/term v0.15.0 // indirect
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -36,20 +36,20 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240327095603-491a47e7fe24 h1:uIkl0mKWwDICUZTbNWZ38HLYDBI9rMgdAhYQWZ0C9iQ=
|
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240306101814-c1c7b344b9c0 h1:4iyAj9k7W29YpyzUTwMuMBbL3G3M96kMbX62OwGNGfE=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240327095603-491a47e7fe24/go.mod h1:OBDSr+DqV1z4VDouoX3YMleNc4DPBVBWTG3WDT2PK1o=
|
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240306101814-c1c7b344b9c0/go.mod h1:OBDSr+DqV1z4VDouoX3YMleNc4DPBVBWTG3WDT2PK1o=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409115729-6eb492025bdd h1:fujTUMMn0wnpEKNDWLejFL916EPuaYD1MdZpk1ZokU8=
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409115729-6eb492025bdd h1:fujTUMMn0wnpEKNDWLejFL916EPuaYD1MdZpk1ZokU8=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409115729-6eb492025bdd/go.mod h1:F/fe1OoIDKr5Bz99q4sriuHDuf3aZefZy9ZsCqEtgxc=
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409115729-6eb492025bdd/go.mod h1:F/fe1OoIDKr5Bz99q4sriuHDuf3aZefZy9ZsCqEtgxc=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 h1:FxqFDhQYYgpe41qsIHVOcdzSVCB8JNSfPG7Uk4r2oSk=
|
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 h1:FxqFDhQYYgpe41qsIHVOcdzSVCB8JNSfPG7Uk4r2oSk=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0/go.mod h1:RUIKZATQLJ+TaYQa60X2fTDwfuhMfm8Ar60bQ5fr+vU=
|
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0/go.mod h1:RUIKZATQLJ+TaYQa60X2fTDwfuhMfm8Ar60bQ5fr+vU=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6 h1:aGQ6QaAnTerQ5Dq5b2/f9DUQtSqPkZZ/bkMx/HKuLCo=
|
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6 h1:aGQ6QaAnTerQ5Dq5b2/f9DUQtSqPkZZ/bkMx/HKuLCo=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6/go.mod h1:W8Nn08/l6aQ7UlIbpF7FsQou7TVpcRD1ZT1KG4TrFhE=
|
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6/go.mod h1:W8Nn08/l6aQ7UlIbpF7FsQou7TVpcRD1ZT1KG4TrFhE=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141549-3790142b10c7 h1:sjvYXV0WJAF4iNF3l0uhcN8zhXmpY1gYI0WyJpeFe6s=
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141532-e5040d35e99d h1:MYlPcYV/8j3PP0Yv0t6kJwPwOnhHNTybHi05g+ofyw0=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141549-3790142b10c7/go.mod h1:i0RKqiF4z3UOxLSNwhHw+cUz/JyYWuTRpnn9ere4Y3w=
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141532-e5040d35e99d/go.mod h1:s2ISRBm7AjfTdfZ3aF6gQt9VXz+n8cwSZcRiaVUMVI0=
|
||||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8lNIRudVc=
|
git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8lNIRudVc=
|
||||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM=
|
git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM=
|
||||||
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412102212-530248de754c h1:Ei15WKKLDXoFqEIe292szb3RfsyLqRZfeJX2FjFvz6k=
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412130734-0e69e485115a h1:wbndKvHbwDQiSMQWL75RxiTZCeUyCi7NUj1lsfdAGkc=
|
||||||
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412102212-530248de754c/go.mod h1:H/AW85RtYxVTbcgwHW76DqXeKlsiCIOeNXHPqyDBrfQ=
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412130734-0e69e485115a/go.mod h1:H/AW85RtYxVTbcgwHW76DqXeKlsiCIOeNXHPqyDBrfQ=
|
||||||
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 h1:M2KR3iBj7WpY3hP10IevfIB9MURr4O9mwVfJ+SjT3HA=
|
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 h1:M2KR3iBj7WpY3hP10IevfIB9MURr4O9mwVfJ+SjT3HA=
|
||||||
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0/go.mod h1:okpbKfVYf/BpejtfFTfhZqFP+sZ8rsHrP8Rr/jYPNRc=
|
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0/go.mod h1:okpbKfVYf/BpejtfFTfhZqFP+sZ8rsHrP8Rr/jYPNRc=
|
||||||
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 h1:UFMnUIk0Zh17m8rjGHJMqku2hCgaXDqjqZzS4gsb4UA=
|
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 h1:UFMnUIk0Zh17m8rjGHJMqku2hCgaXDqjqZzS4gsb4UA=
|
||||||
|
|
|
@ -117,12 +117,16 @@ func (c *MorphRuleChainStorage) SaveACLChains(cid string, chains []*chain.Chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getKind(target engine.Target) policycontract.Kind {
|
func getKind(target engine.Target) policycontract.Kind {
|
||||||
var kind policycontract.Kind = policycontract.Container
|
switch target.Type {
|
||||||
if target.Type != engine.Container {
|
case engine.Container:
|
||||||
kind = policycontract.Namespace
|
return policycontract.Container
|
||||||
|
case engine.User:
|
||||||
|
return 'u'
|
||||||
|
case engine.Group:
|
||||||
|
return 'g'
|
||||||
|
default:
|
||||||
|
return policycontract.Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
return kind
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBucketPolicyName(cnrID cid.ID) []byte {
|
func getBucketPolicyName(cnrID cid.ID) []byte {
|
||||||
|
|
|
@ -135,9 +135,6 @@ const (
|
||||||
ControlAPIGetPolicy = "get policy request"
|
ControlAPIGetPolicy = "get policy request"
|
||||||
ControlAPIListPolicies = "list policies request"
|
ControlAPIListPolicies = "list policies request"
|
||||||
PolicyValidationFailed = "policy validation failed"
|
PolicyValidationFailed = "policy validation failed"
|
||||||
ServerReconnecting = "reconnecting server..."
|
|
||||||
ServerReconnectedSuccessfully = "server reconnected successfully"
|
|
||||||
ServerReconnectFailed = "failed to reconnect server"
|
|
||||||
ParseTreeNode = "parse tree node"
|
ParseTreeNode = "parse tree node"
|
||||||
FailedToGetRealObjectSize = "failed to get real object size"
|
FailedToGetRealObjectSize = "failed to get real object size"
|
||||||
CouldntDeleteObjectFromStorageContinueDeleting = "couldn't delete object from storage, continue deleting from tree"
|
CouldntDeleteObjectFromStorageContinueDeleting = "couldn't delete object from storage, continue deleting from tree"
|
||||||
|
@ -152,6 +149,5 @@ const (
|
||||||
InvalidBucketObjectLockEnabledHeader = "invalid X-Amz-Bucket-Object-Lock-Enabled header"
|
InvalidBucketObjectLockEnabledHeader = "invalid X-Amz-Bucket-Object-Lock-Enabled header"
|
||||||
InvalidTreeKV = "invalid tree service meta KV"
|
InvalidTreeKV = "invalid tree service meta KV"
|
||||||
FailedToWriteResponse = "failed to write response"
|
FailedToWriteResponse = "failed to write response"
|
||||||
WarnDuplicateAddress = "duplicate address"
|
|
||||||
PolicyCouldntBeConvertedToNativeRules = "policy couldn't be converted to native rules, only s3 rules be applied"
|
PolicyCouldntBeConvertedToNativeRules = "policy couldn't be converted to native rules, only s3 rules be applied"
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
policycontract "git.frostfs.info/TrueCloudLab/frostfs-contract/policy"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/control"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/control"
|
||||||
controlSvc "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/control/server"
|
controlSvc "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/control/server"
|
||||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||||
|
@ -23,13 +24,30 @@ type Config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PolicyData struct {
|
type PolicyData struct {
|
||||||
Namespace string
|
Kind policycontract.Kind
|
||||||
Chain *chain.Chain
|
Name string
|
||||||
|
Chain *chain.Chain
|
||||||
}
|
}
|
||||||
|
|
||||||
type PolicyInfo struct {
|
type PolicyInfo struct {
|
||||||
Namespace string
|
Kind policycontract.Kind
|
||||||
ChainID chain.ID
|
Name string
|
||||||
|
ChainID chain.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func kindToTarget(k policycontract.Kind) control.PolicyTarget {
|
||||||
|
switch k {
|
||||||
|
case policycontract.Container:
|
||||||
|
return control.PolicyTarget_CONTAINER
|
||||||
|
case policycontract.Namespace:
|
||||||
|
return control.PolicyTarget_NAMESPACE
|
||||||
|
case 'u':
|
||||||
|
return control.PolicyTarget_USER
|
||||||
|
case 'g':
|
||||||
|
return control.PolicyTarget_GROUP
|
||||||
|
default:
|
||||||
|
return control.PolicyTarget_TARGET_UNDEFINED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx context.Context, addr string, key *keys.PrivateKey) (*Client, error) {
|
func New(ctx context.Context, addr string, key *keys.PrivateKey) (*Client, error) {
|
||||||
|
@ -70,8 +88,9 @@ func (c *Client) PutPolicies(ctx context.Context, policies []PolicyData) error {
|
||||||
chainDatas := make([]*control.PutPoliciesRequest_ChainData, len(policies))
|
chainDatas := make([]*control.PutPoliciesRequest_ChainData, len(policies))
|
||||||
for i := range policies {
|
for i := range policies {
|
||||||
chainDatas[i] = &control.PutPoliciesRequest_ChainData{
|
chainDatas[i] = &control.PutPoliciesRequest_ChainData{
|
||||||
Namespace: policies[i].Namespace,
|
Target: kindToTarget(policies[i].Kind),
|
||||||
Chain: policies[i].Chain.Bytes(),
|
Name: policies[i].Name,
|
||||||
|
Chain: policies[i].Chain.Bytes(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +112,9 @@ func (c *Client) RemovePolicies(ctx context.Context, policies []PolicyInfo) erro
|
||||||
chainInfos := make([]*control.RemovePoliciesRequest_ChainInfo, len(policies))
|
chainInfos := make([]*control.RemovePoliciesRequest_ChainInfo, len(policies))
|
||||||
for i := range policies {
|
for i := range policies {
|
||||||
chainInfos[i] = &control.RemovePoliciesRequest_ChainInfo{
|
chainInfos[i] = &control.RemovePoliciesRequest_ChainInfo{
|
||||||
Namespace: policies[i].Namespace,
|
Target: kindToTarget(policies[i].Kind),
|
||||||
ChainID: []byte(policies[i].ChainID),
|
Name: policies[i].Name,
|
||||||
|
ChainID: []byte(policies[i].ChainID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,11 +132,12 @@ func (c *Client) RemovePolicies(ctx context.Context, policies []PolicyInfo) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) GetPolicy(ctx context.Context, namespace string, chainID chain.ID) (*chain.Chain, error) {
|
func (c *Client) GetPolicy(ctx context.Context, kind policycontract.Kind, name string, chainID chain.ID) (*chain.Chain, error) {
|
||||||
req := &control.GetPolicyRequest{
|
req := &control.GetPolicyRequest{
|
||||||
Body: &control.GetPolicyRequest_Body{
|
Body: &control.GetPolicyRequest_Body{
|
||||||
Namespace: namespace,
|
Target: kindToTarget(kind),
|
||||||
ChainID: []byte(chainID),
|
Name: name,
|
||||||
|
ChainID: []byte(chainID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +158,11 @@ func (c *Client) GetPolicy(ctx context.Context, namespace string, chainID chain.
|
||||||
return &policyChain, nil
|
return &policyChain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ListPolicies(ctx context.Context, namespace string) ([]chain.ID, error) {
|
func (c *Client) ListPolicies(ctx context.Context, kind policycontract.Kind, name string) ([]chain.ID, error) {
|
||||||
req := &control.ListPoliciesRequest{
|
req := &control.ListPoliciesRequest{
|
||||||
Body: &control.ListPoliciesRequest_Body{
|
Body: &control.ListPoliciesRequest_Body{
|
||||||
Namespace: namespace,
|
Target: kindToTarget(kind),
|
||||||
|
Name: name,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,14 +140,39 @@ func (s *Server) putPolicy(data *control.PutPoliciesRequest_ChainData) error {
|
||||||
return status.Error(codes.InvalidArgument, "missing chain id")
|
return status.Error(codes.InvalidArgument, "missing chain id")
|
||||||
}
|
}
|
||||||
|
|
||||||
ns := s.settings.ResolveNamespaceAlias(data.GetNamespace())
|
t, err := s.parseTarget(data.Target, data.Name)
|
||||||
if _, err := s.chainStorage.AddOverride(chain.S3, engine.NamespaceTarget(ns), &overrideChain); err != nil {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := s.chainStorage.AddOverride(chain.S3, t, &overrideChain); err != nil {
|
||||||
return status.Error(codes.Internal, err.Error())
|
return status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) parseTarget(target control.PolicyTarget, name string) (engine.Target, error) {
|
||||||
|
var (
|
||||||
|
t engine.Target
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
switch target {
|
||||||
|
case control.PolicyTarget_NAMESPACE:
|
||||||
|
ns := s.settings.ResolveNamespaceAlias(name)
|
||||||
|
t = engine.NamespaceTarget(ns)
|
||||||
|
case control.PolicyTarget_CONTAINER:
|
||||||
|
t = engine.ContainerTarget(name)
|
||||||
|
case control.PolicyTarget_USER:
|
||||||
|
t = engine.UserTarget(name)
|
||||||
|
case control.PolicyTarget_GROUP:
|
||||||
|
t = engine.GroupTarget(name)
|
||||||
|
default:
|
||||||
|
err = status.Error(codes.InvalidArgument, fmt.Sprintf("invalid target: %s", target.String()))
|
||||||
|
}
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
|
||||||
// RemovePolicies removes existing policies.
|
// RemovePolicies removes existing policies.
|
||||||
//
|
//
|
||||||
// If request is unsigned or signed by disallowed key, permission error returns.
|
// If request is unsigned or signed by disallowed key, permission error returns.
|
||||||
|
@ -169,8 +194,11 @@ func (s *Server) RemovePolicies(_ context.Context, req *control.RemovePoliciesRe
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) removePolicy(info *control.RemovePoliciesRequest_ChainInfo) error {
|
func (s *Server) removePolicy(info *control.RemovePoliciesRequest_ChainInfo) error {
|
||||||
ns := s.settings.ResolveNamespaceAlias(info.GetNamespace())
|
t, err := s.parseTarget(info.Target, info.Name)
|
||||||
err := s.chainStorage.RemoveOverride(chain.S3, engine.NamespaceTarget(ns), chain.ID(info.GetChainID()))
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = s.chainStorage.RemoveOverride(chain.S3, t, chain.ID(info.GetChainID()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isNotFoundError(err) {
|
if isNotFoundError(err) {
|
||||||
return status.Error(codes.NotFound, err.Error())
|
return status.Error(codes.NotFound, err.Error())
|
||||||
|
@ -184,16 +212,20 @@ func (s *Server) removePolicy(info *control.RemovePoliciesRequest_ChainInfo) err
|
||||||
//
|
//
|
||||||
// If request is unsigned or signed by disallowed key, permission error returns.
|
// If request is unsigned or signed by disallowed key, permission error returns.
|
||||||
func (s *Server) GetPolicy(_ context.Context, req *control.GetPolicyRequest) (*control.GetPolicyResponse, error) {
|
func (s *Server) GetPolicy(_ context.Context, req *control.GetPolicyRequest) (*control.GetPolicyResponse, error) {
|
||||||
s.log.Info(logs.ControlAPIGetPolicy, zap.String("namespace", req.GetBody().GetNamespace()),
|
s.log.Info(logs.ControlAPIGetPolicy, zap.Stringer("target", req.GetBody().GetTarget()), zap.String("name", req.GetBody().GetName()),
|
||||||
zap.Binary("chainId", req.GetBody().GetChainID()), zap.String("key", hex.EncodeToString(req.Signature.Key)))
|
zap.Binary("chainId", req.GetBody().GetChainID()), zap.String("key", hex.EncodeToString(req.Signature.Key)))
|
||||||
|
|
||||||
|
t, err := s.parseTarget(req.GetBody().GetTarget(), req.GetBody().GetName())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// verify request
|
// verify request
|
||||||
if err := s.isValidRequest(req); err != nil {
|
if err := s.isValidRequest(req); err != nil {
|
||||||
return nil, status.Error(codes.PermissionDenied, err.Error())
|
return nil, status.Error(codes.PermissionDenied, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
ns := s.settings.ResolveNamespaceAlias(req.GetBody().GetNamespace())
|
overrideChain, err := s.chainStorage.GetOverride(chain.S3, t, chain.ID(req.GetBody().GetChainID()))
|
||||||
overrideChain, err := s.chainStorage.GetOverride(chain.S3, engine.NamespaceTarget(ns), chain.ID(req.GetBody().GetChainID()))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -205,16 +237,20 @@ func (s *Server) GetPolicy(_ context.Context, req *control.GetPolicyRequest) (*c
|
||||||
//
|
//
|
||||||
// If request is unsigned or signed by disallowed key, permission error returns.
|
// If request is unsigned or signed by disallowed key, permission error returns.
|
||||||
func (s *Server) ListPolicies(_ context.Context, req *control.ListPoliciesRequest) (*control.ListPoliciesResponse, error) {
|
func (s *Server) ListPolicies(_ context.Context, req *control.ListPoliciesRequest) (*control.ListPoliciesResponse, error) {
|
||||||
s.log.Info(logs.ControlAPIListPolicies, zap.String("namespace", req.GetBody().GetNamespace()),
|
s.log.Info(logs.ControlAPIListPolicies, zap.Stringer("target", req.GetBody().GetTarget()), zap.String("name", req.GetBody().GetName()),
|
||||||
zap.String("key", hex.EncodeToString(req.Signature.Key)))
|
zap.String("key", hex.EncodeToString(req.Signature.Key)))
|
||||||
|
|
||||||
|
t, err := s.parseTarget(req.GetBody().GetTarget(), req.GetBody().GetName())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// verify request
|
// verify request
|
||||||
if err := s.isValidRequest(req); err != nil {
|
if err := s.isValidRequest(req); err != nil {
|
||||||
return nil, status.Error(codes.PermissionDenied, err.Error())
|
return nil, status.Error(codes.PermissionDenied, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
ns := s.settings.ResolveNamespaceAlias(req.GetBody().GetNamespace())
|
chains, err := s.chainStorage.ListOverrides(chain.S3, t)
|
||||||
chains, err := s.chainStorage.ListOverrides(chain.S3, engine.NamespaceTarget(ns))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.28.1
|
// protoc-gen-go v1.30.0
|
||||||
// protoc v3.21.9
|
// protoc v3.21.12
|
||||||
// source: pkg/service/control/service.proto
|
// source: pkg/service/control/service.proto
|
||||||
|
|
||||||
package control
|
package control
|
||||||
|
@ -77,6 +77,67 @@ func (HealthStatus) EnumDescriptor() ([]byte, []int) {
|
||||||
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{0}
|
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Policy target to store chains.
|
||||||
|
type PolicyTarget int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Undefined target, invalid to use.
|
||||||
|
PolicyTarget_TARGET_UNDEFINED PolicyTarget = 0
|
||||||
|
// Container target for bucket policies.
|
||||||
|
PolicyTarget_CONTAINER PolicyTarget = 1
|
||||||
|
// Namespace target for namespace policies.
|
||||||
|
PolicyTarget_NAMESPACE PolicyTarget = 2
|
||||||
|
// User target for namespace user policies.
|
||||||
|
PolicyTarget_USER PolicyTarget = 3
|
||||||
|
// Group target for namespace target policies.
|
||||||
|
PolicyTarget_GROUP PolicyTarget = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for PolicyTarget.
|
||||||
|
var (
|
||||||
|
PolicyTarget_name = map[int32]string{
|
||||||
|
0: "TARGET_UNDEFINED",
|
||||||
|
1: "CONTAINER",
|
||||||
|
2: "NAMESPACE",
|
||||||
|
3: "USER",
|
||||||
|
4: "GROUP",
|
||||||
|
}
|
||||||
|
PolicyTarget_value = map[string]int32{
|
||||||
|
"TARGET_UNDEFINED": 0,
|
||||||
|
"CONTAINER": 1,
|
||||||
|
"NAMESPACE": 2,
|
||||||
|
"USER": 3,
|
||||||
|
"GROUP": 4,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x PolicyTarget) Enum() *PolicyTarget {
|
||||||
|
p := new(PolicyTarget)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x PolicyTarget) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (PolicyTarget) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_pkg_service_control_service_proto_enumTypes[1].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (PolicyTarget) Type() protoreflect.EnumType {
|
||||||
|
return &file_pkg_service_control_service_proto_enumTypes[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x PolicyTarget) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use PolicyTarget.Descriptor instead.
|
||||||
|
func (PolicyTarget) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
// Signature of some message.
|
// Signature of some message.
|
||||||
type Signature struct {
|
type Signature struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
|
@ -794,10 +855,12 @@ type PutPoliciesRequest_ChainData struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
// Namespace.
|
// Policy entity type.
|
||||||
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
|
Target PolicyTarget `protobuf:"varint,1,opt,name=target,proto3,enum=s3gw.control.PolicyTarget" json:"target,omitempty"`
|
||||||
|
// Policy name.
|
||||||
|
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
// Chain rules.
|
// Chain rules.
|
||||||
Chain []byte `protobuf:"bytes,2,opt,name=chain,proto3" json:"chain,omitempty"`
|
Chain []byte `protobuf:"bytes,3,opt,name=chain,proto3" json:"chain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *PutPoliciesRequest_ChainData) Reset() {
|
func (x *PutPoliciesRequest_ChainData) Reset() {
|
||||||
|
@ -832,9 +895,16 @@ func (*PutPoliciesRequest_ChainData) Descriptor() ([]byte, []int) {
|
||||||
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{3, 0}
|
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{3, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *PutPoliciesRequest_ChainData) GetNamespace() string {
|
func (x *PutPoliciesRequest_ChainData) GetTarget() PolicyTarget {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Namespace
|
return x.Target
|
||||||
|
}
|
||||||
|
return PolicyTarget_TARGET_UNDEFINED
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *PutPoliciesRequest_ChainData) GetName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Name
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -936,10 +1006,12 @@ type RemovePoliciesRequest_ChainInfo struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
// Namespace.
|
// Policy entity type.
|
||||||
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
|
Target PolicyTarget `protobuf:"varint,1,opt,name=target,proto3,enum=s3gw.control.PolicyTarget" json:"target,omitempty"`
|
||||||
|
// Policy name.
|
||||||
|
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
// Chain id to remove.
|
// Chain id to remove.
|
||||||
ChainID []byte `protobuf:"bytes,2,opt,name=chainID,proto3" json:"chainID,omitempty"`
|
ChainID []byte `protobuf:"bytes,3,opt,name=chainID,proto3" json:"chainID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RemovePoliciesRequest_ChainInfo) Reset() {
|
func (x *RemovePoliciesRequest_ChainInfo) Reset() {
|
||||||
|
@ -974,9 +1046,16 @@ func (*RemovePoliciesRequest_ChainInfo) Descriptor() ([]byte, []int) {
|
||||||
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{5, 0}
|
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{5, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RemovePoliciesRequest_ChainInfo) GetNamespace() string {
|
func (x *RemovePoliciesRequest_ChainInfo) GetTarget() PolicyTarget {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Namespace
|
return x.Target
|
||||||
|
}
|
||||||
|
return PolicyTarget_TARGET_UNDEFINED
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RemovePoliciesRequest_ChainInfo) GetName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Name
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -1078,10 +1157,12 @@ type GetPolicyRequest_Body struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
// Namespace.
|
// Policy entity type.
|
||||||
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
|
Target PolicyTarget `protobuf:"varint,1,opt,name=target,proto3,enum=s3gw.control.PolicyTarget" json:"target,omitempty"`
|
||||||
// Chain id to remove.
|
// Policy name.
|
||||||
ChainID []byte `protobuf:"bytes,2,opt,name=chainID,proto3" json:"chainID,omitempty"`
|
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
|
// Chain id to get.
|
||||||
|
ChainID []byte `protobuf:"bytes,3,opt,name=chainID,proto3" json:"chainID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetPolicyRequest_Body) Reset() {
|
func (x *GetPolicyRequest_Body) Reset() {
|
||||||
|
@ -1116,9 +1197,16 @@ func (*GetPolicyRequest_Body) Descriptor() ([]byte, []int) {
|
||||||
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{7, 0}
|
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{7, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetPolicyRequest_Body) GetNamespace() string {
|
func (x *GetPolicyRequest_Body) GetTarget() PolicyTarget {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Namespace
|
return x.Target
|
||||||
|
}
|
||||||
|
return PolicyTarget_TARGET_UNDEFINED
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetPolicyRequest_Body) GetName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Name
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -1183,8 +1271,10 @@ type ListPoliciesRequest_Body struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
// Namespace.
|
// Policy entity type.
|
||||||
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
|
Target PolicyTarget `protobuf:"varint,1,opt,name=target,proto3,enum=s3gw.control.PolicyTarget" json:"target,omitempty"`
|
||||||
|
// Policy name.
|
||||||
|
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ListPoliciesRequest_Body) Reset() {
|
func (x *ListPoliciesRequest_Body) Reset() {
|
||||||
|
@ -1219,9 +1309,16 @@ func (*ListPoliciesRequest_Body) Descriptor() ([]byte, []int) {
|
||||||
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{9, 0}
|
return file_pkg_service_control_service_proto_rawDescGZIP(), []int{9, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ListPoliciesRequest_Body) GetNamespace() string {
|
func (x *ListPoliciesRequest_Body) GetTarget() PolicyTarget {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Namespace
|
return x.Target
|
||||||
|
}
|
||||||
|
return PolicyTarget_TARGET_UNDEFINED
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ListPoliciesRequest_Body) GetName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Name
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -1305,7 +1402,7 @@ var file_pkg_service_control_service_proto_rawDesc = []byte{
|
||||||
0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01,
|
0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01,
|
||||||
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||||
0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||||
0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x9b,
|
0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xc5,
|
||||||
0x02, 0x0a, 0x12, 0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65,
|
0x02, 0x0a, 0x12, 0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65,
|
||||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20,
|
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20,
|
||||||
0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||||
|
@ -1314,136 +1411,153 @@ var file_pkg_service_control_service_proto_rawDesc = []byte{
|
||||||
0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20,
|
0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20,
|
||||||
0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||||
0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69,
|
0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69,
|
||||||
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x3f, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e,
|
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x69, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e,
|
||||||
0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
|
0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01,
|
||||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
|
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||||
0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
0x72, 0x6f, 0x6c, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||||
0x0c, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x1a, 0x52, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79,
|
0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||||
0x12, 0x4a, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x73, 0x18, 0x01,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05,
|
||||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x68, 0x61,
|
||||||
0x72, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52,
|
0x69, 0x6e, 0x1a, 0x52, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x4a, 0x0a, 0x0a, 0x63, 0x68,
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61,
|
0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a,
|
||||||
0x52, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x73, 0x22, 0x90, 0x01, 0x0a,
|
0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x50, 0x75,
|
||||||
0x13, 0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01,
|
0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x69,
|
||||||
0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
0x6e, 0x44, 0x61, 0x74, 0x61, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x13, 0x50, 0x75, 0x74, 0x50, 0x6f,
|
||||||
0x6c, 0x2e, 0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73,
|
0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a,
|
||||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79,
|
0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73,
|
||||||
0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20,
|
0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x74, 0x50,
|
||||||
0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e,
|
||||||
0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69,
|
0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69,
|
||||||
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x22,
|
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
|
||||||
0xa8, 0x02, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69,
|
0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67,
|
||||||
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x04, 0x62, 0x6f, 0x64,
|
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
|
||||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63,
|
0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x22, 0xd2, 0x02, 0x0a, 0x15, 0x52, 0x65,
|
||||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c,
|
0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||||
0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64,
|
0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61,
|
0x0b, 0x32, 0x28, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||||
0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67,
|
0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52,
|
||||||
0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
|
||||||
0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x43,
|
|
||||||
0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e,
|
|
||||||
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
|
||||||
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61,
|
|
||||||
0x69, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69,
|
|
||||||
0x6e, 0x49, 0x44, 0x1a, 0x55, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x4d, 0x0a, 0x0a, 0x63,
|
|
||||||
0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
|
||||||
0x2d, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52,
|
|
||||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71,
|
|
||||||
0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a,
|
|
||||||
0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x16, 0x52,
|
|
||||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73,
|
|
||||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20,
|
|
||||||
0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
|
||||||
0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
|
|
||||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04,
|
|
||||||
0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
|
|
||||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63,
|
|
||||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
|
||||||
0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42,
|
|
||||||
0x6f, 0x64, 0x79, 0x22, 0xc2, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63,
|
|
||||||
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79,
|
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f,
|
|
||||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52,
|
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64,
|
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64,
|
||||||
0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
|
0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
|
||||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||||
0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73,
|
0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73,
|
||||||
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x3e, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79,
|
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x6d, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69,
|
||||||
0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20,
|
0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18,
|
||||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18,
|
0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e,
|
||||||
0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65,
|
||||||
0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x22, 0xa2, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74,
|
0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
|
||||||
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38,
|
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a,
|
||||||
0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73,
|
0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07,
|
||||||
0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x50,
|
0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x1a, 0x55, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12,
|
||||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f,
|
0x4d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x01, 0x20,
|
||||||
|
0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||||
|
0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
|
||||||
|
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e,
|
||||||
|
0x66, 0x6f, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x22, 0x96,
|
||||||
|
0x01, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
|
||||||
|
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x62, 0x6f, 0x64,
|
||||||
|
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63,
|
||||||
|
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c,
|
||||||
|
0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f,
|
||||||
0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
|
0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
|
||||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33,
|
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33,
|
||||||
0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61,
|
0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61,
|
||||||
0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a,
|
0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a,
|
||||||
0x1c, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e,
|
0x06, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x22, 0xec, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50,
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x22, 0xae, 0x01,
|
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x04,
|
||||||
0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65,
|
0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x33, 0x67,
|
||||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20,
|
0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c,
|
||||||
0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52,
|
||||||
0x6f, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52,
|
0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64,
|
0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e,
|
||||||
0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
|
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
|
||||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x68, 0x0a, 0x04,
|
||||||
0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73,
|
0x42, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01,
|
||||||
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x24, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79,
|
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||||
0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20,
|
0x72, 0x6f, 0x6c, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xae,
|
0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||||
0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07,
|
||||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18,
|
0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63,
|
||||||
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e,
|
0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x22, 0xa2, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x6f,
|
||||||
0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
|
0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x04,
|
||||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04,
|
0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x33, 0x67,
|
||||||
0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
|
0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c,
|
||||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63,
|
0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79,
|
||||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||||
0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x22, 0x0a, 0x04, 0x42,
|
0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77,
|
||||||
0x6f, 0x64, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x73, 0x18,
|
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
|
||||||
0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x73, 0x2a,
|
0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x1c, 0x0a,
|
||||||
0x57, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
|
0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01,
|
||||||
0x1b, 0x0a, 0x17, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
|
0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x22, 0xd8, 0x01, 0x0a, 0x13,
|
||||||
0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08,
|
0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||||
0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45,
|
0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x41, 0x44, 0x59, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e,
|
0x0b, 0x32, 0x26, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||||
0x47, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x32, 0xba, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6e,
|
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71,
|
||||||
0x74, 0x72, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x0b, 0x48,
|
0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12,
|
||||||
0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x20, 0x2e, 0x73, 0x33, 0x67,
|
0x35, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||||
0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68,
|
0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||||
0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73,
|
0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67,
|
||||||
0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c,
|
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x4e, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x32,
|
||||||
0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a,
|
||||||
0x52, 0x0a, 0x0b, 0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x20,
|
0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x50, 0x6f,
|
||||||
0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x50, 0x75,
|
0x6c, 0x69, 0x63, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67,
|
||||||
0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||||
0x1a, 0x21, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e,
|
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xae, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50,
|
||||||
0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||||
0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c,
|
0x3b, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e,
|
||||||
0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e,
|
0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x4c, 0x69, 0x73,
|
||||||
0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63,
|
0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x33, 0x67,
|
0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09,
|
||||||
0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
|
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||||
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
0x17, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53,
|
||||||
0x12, 0x4c, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1e, 0x2e,
|
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||||
0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x47, 0x65, 0x74,
|
0x75, 0x72, 0x65, 0x1a, 0x22, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x63,
|
||||||
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e,
|
0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x63,
|
||||||
0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x47, 0x65, 0x74,
|
0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x73, 0x2a, 0x57, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74,
|
||||||
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55,
|
0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x17, 0x48, 0x45, 0x41, 0x4c, 0x54,
|
||||||
0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x21,
|
0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e,
|
||||||
0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x4c, 0x69,
|
0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47,
|
||||||
0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x02, 0x12, 0x11, 0x0a,
|
||||||
0x74, 0x1a, 0x22, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03,
|
||||||
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73,
|
0x2a, 0x57, 0x0a, 0x0c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, 0x6f,
|
0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46,
|
||||||
0x73, 0x74, 0x66, 0x73, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c,
|
0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49,
|
||||||
0x6f, 0x75, 0x64, 0x4c, 0x61, 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, 0x73,
|
0x4e, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x41, 0x4d, 0x45, 0x53, 0x50, 0x41,
|
||||||
0x33, 0x2d, 0x67, 0x77, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
0x43, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x03, 0x12, 0x09,
|
||||||
0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x0a, 0x05, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x04, 0x32, 0xba, 0x03, 0x0a, 0x0e, 0x43, 0x6f,
|
||||||
|
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x0b,
|
||||||
|
0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x20, 0x2e, 0x73, 0x33,
|
||||||
|
0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74,
|
||||||
|
0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e,
|
||||||
|
0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61,
|
||||||
|
0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||||
|
0x12, 0x52, 0x0a, 0x0b, 0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12,
|
||||||
|
0x20, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x50,
|
||||||
|
0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||||
|
0x74, 0x1a, 0x21, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||||
|
0x2e, 0x50, 0x75, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||||
|
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f,
|
||||||
|
0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f,
|
||||||
|
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x6c, 0x69,
|
||||||
|
0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x33,
|
||||||
|
0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
|
||||||
|
0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
|
0x65, 0x12, 0x4c, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1e,
|
||||||
|
0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x47, 0x65,
|
||||||
|
0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f,
|
||||||
|
0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x47, 0x65,
|
||||||
|
0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||||
|
0x55, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12,
|
||||||
|
0x21, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x4c,
|
||||||
|
0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
|
0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x33, 0x67, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||||
|
0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65,
|
||||||
|
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72,
|
||||||
|
0x6f, 0x73, 0x74, 0x66, 0x73, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43,
|
||||||
|
0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x61, 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d,
|
||||||
|
0x73, 0x33, 0x2d, 0x67, 0x77, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||||
|
0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
|
0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -1458,73 +1572,78 @@ func file_pkg_service_control_service_proto_rawDescGZIP() []byte {
|
||||||
return file_pkg_service_control_service_proto_rawDescData
|
return file_pkg_service_control_service_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_pkg_service_control_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
var file_pkg_service_control_service_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||||
var file_pkg_service_control_service_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
|
var file_pkg_service_control_service_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
|
||||||
var file_pkg_service_control_service_proto_goTypes = []interface{}{
|
var file_pkg_service_control_service_proto_goTypes = []interface{}{
|
||||||
(HealthStatus)(0), // 0: s3gw.control.HealthStatus
|
(HealthStatus)(0), // 0: s3gw.control.HealthStatus
|
||||||
(*Signature)(nil), // 1: s3gw.control.Signature
|
(PolicyTarget)(0), // 1: s3gw.control.PolicyTarget
|
||||||
(*HealthCheckRequest)(nil), // 2: s3gw.control.HealthCheckRequest
|
(*Signature)(nil), // 2: s3gw.control.Signature
|
||||||
(*HealthCheckResponse)(nil), // 3: s3gw.control.HealthCheckResponse
|
(*HealthCheckRequest)(nil), // 3: s3gw.control.HealthCheckRequest
|
||||||
(*PutPoliciesRequest)(nil), // 4: s3gw.control.PutPoliciesRequest
|
(*HealthCheckResponse)(nil), // 4: s3gw.control.HealthCheckResponse
|
||||||
(*PutPoliciesResponse)(nil), // 5: s3gw.control.PutPoliciesResponse
|
(*PutPoliciesRequest)(nil), // 5: s3gw.control.PutPoliciesRequest
|
||||||
(*RemovePoliciesRequest)(nil), // 6: s3gw.control.RemovePoliciesRequest
|
(*PutPoliciesResponse)(nil), // 6: s3gw.control.PutPoliciesResponse
|
||||||
(*RemovePoliciesResponse)(nil), // 7: s3gw.control.RemovePoliciesResponse
|
(*RemovePoliciesRequest)(nil), // 7: s3gw.control.RemovePoliciesRequest
|
||||||
(*GetPolicyRequest)(nil), // 8: s3gw.control.GetPolicyRequest
|
(*RemovePoliciesResponse)(nil), // 8: s3gw.control.RemovePoliciesResponse
|
||||||
(*GetPolicyResponse)(nil), // 9: s3gw.control.GetPolicyResponse
|
(*GetPolicyRequest)(nil), // 9: s3gw.control.GetPolicyRequest
|
||||||
(*ListPoliciesRequest)(nil), // 10: s3gw.control.ListPoliciesRequest
|
(*GetPolicyResponse)(nil), // 10: s3gw.control.GetPolicyResponse
|
||||||
(*ListPoliciesResponse)(nil), // 11: s3gw.control.ListPoliciesResponse
|
(*ListPoliciesRequest)(nil), // 11: s3gw.control.ListPoliciesRequest
|
||||||
(*HealthCheckRequest_Body)(nil), // 12: s3gw.control.HealthCheckRequest.Body
|
(*ListPoliciesResponse)(nil), // 12: s3gw.control.ListPoliciesResponse
|
||||||
(*HealthCheckResponse_Body)(nil), // 13: s3gw.control.HealthCheckResponse.Body
|
(*HealthCheckRequest_Body)(nil), // 13: s3gw.control.HealthCheckRequest.Body
|
||||||
(*PutPoliciesRequest_ChainData)(nil), // 14: s3gw.control.PutPoliciesRequest.ChainData
|
(*HealthCheckResponse_Body)(nil), // 14: s3gw.control.HealthCheckResponse.Body
|
||||||
(*PutPoliciesRequest_Body)(nil), // 15: s3gw.control.PutPoliciesRequest.Body
|
(*PutPoliciesRequest_ChainData)(nil), // 15: s3gw.control.PutPoliciesRequest.ChainData
|
||||||
(*PutPoliciesResponse_Body)(nil), // 16: s3gw.control.PutPoliciesResponse.Body
|
(*PutPoliciesRequest_Body)(nil), // 16: s3gw.control.PutPoliciesRequest.Body
|
||||||
(*RemovePoliciesRequest_ChainInfo)(nil), // 17: s3gw.control.RemovePoliciesRequest.ChainInfo
|
(*PutPoliciesResponse_Body)(nil), // 17: s3gw.control.PutPoliciesResponse.Body
|
||||||
(*RemovePoliciesRequest_Body)(nil), // 18: s3gw.control.RemovePoliciesRequest.Body
|
(*RemovePoliciesRequest_ChainInfo)(nil), // 18: s3gw.control.RemovePoliciesRequest.ChainInfo
|
||||||
(*RemovePoliciesResponse_Body)(nil), // 19: s3gw.control.RemovePoliciesResponse.Body
|
(*RemovePoliciesRequest_Body)(nil), // 19: s3gw.control.RemovePoliciesRequest.Body
|
||||||
(*GetPolicyRequest_Body)(nil), // 20: s3gw.control.GetPolicyRequest.Body
|
(*RemovePoliciesResponse_Body)(nil), // 20: s3gw.control.RemovePoliciesResponse.Body
|
||||||
(*GetPolicyResponse_Body)(nil), // 21: s3gw.control.GetPolicyResponse.Body
|
(*GetPolicyRequest_Body)(nil), // 21: s3gw.control.GetPolicyRequest.Body
|
||||||
(*ListPoliciesRequest_Body)(nil), // 22: s3gw.control.ListPoliciesRequest.Body
|
(*GetPolicyResponse_Body)(nil), // 22: s3gw.control.GetPolicyResponse.Body
|
||||||
(*ListPoliciesResponse_Body)(nil), // 23: s3gw.control.ListPoliciesResponse.Body
|
(*ListPoliciesRequest_Body)(nil), // 23: s3gw.control.ListPoliciesRequest.Body
|
||||||
|
(*ListPoliciesResponse_Body)(nil), // 24: s3gw.control.ListPoliciesResponse.Body
|
||||||
}
|
}
|
||||||
var file_pkg_service_control_service_proto_depIdxs = []int32{
|
var file_pkg_service_control_service_proto_depIdxs = []int32{
|
||||||
12, // 0: s3gw.control.HealthCheckRequest.body:type_name -> s3gw.control.HealthCheckRequest.Body
|
13, // 0: s3gw.control.HealthCheckRequest.body:type_name -> s3gw.control.HealthCheckRequest.Body
|
||||||
1, // 1: s3gw.control.HealthCheckRequest.signature:type_name -> s3gw.control.Signature
|
2, // 1: s3gw.control.HealthCheckRequest.signature:type_name -> s3gw.control.Signature
|
||||||
13, // 2: s3gw.control.HealthCheckResponse.body:type_name -> s3gw.control.HealthCheckResponse.Body
|
14, // 2: s3gw.control.HealthCheckResponse.body:type_name -> s3gw.control.HealthCheckResponse.Body
|
||||||
1, // 3: s3gw.control.HealthCheckResponse.signature:type_name -> s3gw.control.Signature
|
2, // 3: s3gw.control.HealthCheckResponse.signature:type_name -> s3gw.control.Signature
|
||||||
15, // 4: s3gw.control.PutPoliciesRequest.body:type_name -> s3gw.control.PutPoliciesRequest.Body
|
16, // 4: s3gw.control.PutPoliciesRequest.body:type_name -> s3gw.control.PutPoliciesRequest.Body
|
||||||
1, // 5: s3gw.control.PutPoliciesRequest.signature:type_name -> s3gw.control.Signature
|
2, // 5: s3gw.control.PutPoliciesRequest.signature:type_name -> s3gw.control.Signature
|
||||||
16, // 6: s3gw.control.PutPoliciesResponse.body:type_name -> s3gw.control.PutPoliciesResponse.Body
|
17, // 6: s3gw.control.PutPoliciesResponse.body:type_name -> s3gw.control.PutPoliciesResponse.Body
|
||||||
1, // 7: s3gw.control.PutPoliciesResponse.signature:type_name -> s3gw.control.Signature
|
2, // 7: s3gw.control.PutPoliciesResponse.signature:type_name -> s3gw.control.Signature
|
||||||
18, // 8: s3gw.control.RemovePoliciesRequest.body:type_name -> s3gw.control.RemovePoliciesRequest.Body
|
19, // 8: s3gw.control.RemovePoliciesRequest.body:type_name -> s3gw.control.RemovePoliciesRequest.Body
|
||||||
1, // 9: s3gw.control.RemovePoliciesRequest.signature:type_name -> s3gw.control.Signature
|
2, // 9: s3gw.control.RemovePoliciesRequest.signature:type_name -> s3gw.control.Signature
|
||||||
19, // 10: s3gw.control.RemovePoliciesResponse.body:type_name -> s3gw.control.RemovePoliciesResponse.Body
|
20, // 10: s3gw.control.RemovePoliciesResponse.body:type_name -> s3gw.control.RemovePoliciesResponse.Body
|
||||||
1, // 11: s3gw.control.RemovePoliciesResponse.signature:type_name -> s3gw.control.Signature
|
2, // 11: s3gw.control.RemovePoliciesResponse.signature:type_name -> s3gw.control.Signature
|
||||||
20, // 12: s3gw.control.GetPolicyRequest.body:type_name -> s3gw.control.GetPolicyRequest.Body
|
21, // 12: s3gw.control.GetPolicyRequest.body:type_name -> s3gw.control.GetPolicyRequest.Body
|
||||||
1, // 13: s3gw.control.GetPolicyRequest.signature:type_name -> s3gw.control.Signature
|
2, // 13: s3gw.control.GetPolicyRequest.signature:type_name -> s3gw.control.Signature
|
||||||
21, // 14: s3gw.control.GetPolicyResponse.body:type_name -> s3gw.control.GetPolicyResponse.Body
|
22, // 14: s3gw.control.GetPolicyResponse.body:type_name -> s3gw.control.GetPolicyResponse.Body
|
||||||
1, // 15: s3gw.control.GetPolicyResponse.signature:type_name -> s3gw.control.Signature
|
2, // 15: s3gw.control.GetPolicyResponse.signature:type_name -> s3gw.control.Signature
|
||||||
22, // 16: s3gw.control.ListPoliciesRequest.body:type_name -> s3gw.control.ListPoliciesRequest.Body
|
23, // 16: s3gw.control.ListPoliciesRequest.body:type_name -> s3gw.control.ListPoliciesRequest.Body
|
||||||
1, // 17: s3gw.control.ListPoliciesRequest.signature:type_name -> s3gw.control.Signature
|
2, // 17: s3gw.control.ListPoliciesRequest.signature:type_name -> s3gw.control.Signature
|
||||||
23, // 18: s3gw.control.ListPoliciesResponse.body:type_name -> s3gw.control.ListPoliciesResponse.Body
|
24, // 18: s3gw.control.ListPoliciesResponse.body:type_name -> s3gw.control.ListPoliciesResponse.Body
|
||||||
1, // 19: s3gw.control.ListPoliciesResponse.signature:type_name -> s3gw.control.Signature
|
2, // 19: s3gw.control.ListPoliciesResponse.signature:type_name -> s3gw.control.Signature
|
||||||
0, // 20: s3gw.control.HealthCheckResponse.Body.health_status:type_name -> s3gw.control.HealthStatus
|
0, // 20: s3gw.control.HealthCheckResponse.Body.health_status:type_name -> s3gw.control.HealthStatus
|
||||||
14, // 21: s3gw.control.PutPoliciesRequest.Body.chainDatas:type_name -> s3gw.control.PutPoliciesRequest.ChainData
|
1, // 21: s3gw.control.PutPoliciesRequest.ChainData.target:type_name -> s3gw.control.PolicyTarget
|
||||||
17, // 22: s3gw.control.RemovePoliciesRequest.Body.chainInfos:type_name -> s3gw.control.RemovePoliciesRequest.ChainInfo
|
15, // 22: s3gw.control.PutPoliciesRequest.Body.chainDatas:type_name -> s3gw.control.PutPoliciesRequest.ChainData
|
||||||
2, // 23: s3gw.control.ControlService.HealthCheck:input_type -> s3gw.control.HealthCheckRequest
|
1, // 23: s3gw.control.RemovePoliciesRequest.ChainInfo.target:type_name -> s3gw.control.PolicyTarget
|
||||||
4, // 24: s3gw.control.ControlService.PutPolicies:input_type -> s3gw.control.PutPoliciesRequest
|
18, // 24: s3gw.control.RemovePoliciesRequest.Body.chainInfos:type_name -> s3gw.control.RemovePoliciesRequest.ChainInfo
|
||||||
6, // 25: s3gw.control.ControlService.RemovePolicies:input_type -> s3gw.control.RemovePoliciesRequest
|
1, // 25: s3gw.control.GetPolicyRequest.Body.target:type_name -> s3gw.control.PolicyTarget
|
||||||
8, // 26: s3gw.control.ControlService.GetPolicy:input_type -> s3gw.control.GetPolicyRequest
|
1, // 26: s3gw.control.ListPoliciesRequest.Body.target:type_name -> s3gw.control.PolicyTarget
|
||||||
10, // 27: s3gw.control.ControlService.ListPolicies:input_type -> s3gw.control.ListPoliciesRequest
|
3, // 27: s3gw.control.ControlService.HealthCheck:input_type -> s3gw.control.HealthCheckRequest
|
||||||
3, // 28: s3gw.control.ControlService.HealthCheck:output_type -> s3gw.control.HealthCheckResponse
|
5, // 28: s3gw.control.ControlService.PutPolicies:input_type -> s3gw.control.PutPoliciesRequest
|
||||||
5, // 29: s3gw.control.ControlService.PutPolicies:output_type -> s3gw.control.PutPoliciesResponse
|
7, // 29: s3gw.control.ControlService.RemovePolicies:input_type -> s3gw.control.RemovePoliciesRequest
|
||||||
7, // 30: s3gw.control.ControlService.RemovePolicies:output_type -> s3gw.control.RemovePoliciesResponse
|
9, // 30: s3gw.control.ControlService.GetPolicy:input_type -> s3gw.control.GetPolicyRequest
|
||||||
9, // 31: s3gw.control.ControlService.GetPolicy:output_type -> s3gw.control.GetPolicyResponse
|
11, // 31: s3gw.control.ControlService.ListPolicies:input_type -> s3gw.control.ListPoliciesRequest
|
||||||
11, // 32: s3gw.control.ControlService.ListPolicies:output_type -> s3gw.control.ListPoliciesResponse
|
4, // 32: s3gw.control.ControlService.HealthCheck:output_type -> s3gw.control.HealthCheckResponse
|
||||||
28, // [28:33] is the sub-list for method output_type
|
6, // 33: s3gw.control.ControlService.PutPolicies:output_type -> s3gw.control.PutPoliciesResponse
|
||||||
23, // [23:28] is the sub-list for method input_type
|
8, // 34: s3gw.control.ControlService.RemovePolicies:output_type -> s3gw.control.RemovePoliciesResponse
|
||||||
23, // [23:23] is the sub-list for extension type_name
|
10, // 35: s3gw.control.ControlService.GetPolicy:output_type -> s3gw.control.GetPolicyResponse
|
||||||
23, // [23:23] is the sub-list for extension extendee
|
12, // 36: s3gw.control.ControlService.ListPolicies:output_type -> s3gw.control.ListPoliciesResponse
|
||||||
0, // [0:23] is the sub-list for field type_name
|
32, // [32:37] is the sub-list for method output_type
|
||||||
|
27, // [27:32] is the sub-list for method input_type
|
||||||
|
27, // [27:27] is the sub-list for extension type_name
|
||||||
|
27, // [27:27] is the sub-list for extension extendee
|
||||||
|
0, // [0:27] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_pkg_service_control_service_proto_init() }
|
func init() { file_pkg_service_control_service_proto_init() }
|
||||||
|
@ -1815,7 +1934,7 @@ func file_pkg_service_control_service_proto_init() {
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_pkg_service_control_service_proto_rawDesc,
|
RawDescriptor: file_pkg_service_control_service_proto_rawDesc,
|
||||||
NumEnums: 1,
|
NumEnums: 2,
|
||||||
NumMessages: 23,
|
NumMessages: 23,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
|
|
|
@ -69,13 +69,33 @@ enum HealthStatus {
|
||||||
SHUTTING_DOWN = 3;
|
SHUTTING_DOWN = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Policy target to store chains.
|
||||||
|
enum PolicyTarget {
|
||||||
|
// Undefined target, invalid to use.
|
||||||
|
TARGET_UNDEFINED = 0;
|
||||||
|
|
||||||
|
// Container target for bucket policies.
|
||||||
|
CONTAINER = 1;
|
||||||
|
|
||||||
|
// Namespace target for namespace policies.
|
||||||
|
NAMESPACE = 2;
|
||||||
|
|
||||||
|
// User target for namespace user policies.
|
||||||
|
USER = 3;
|
||||||
|
|
||||||
|
// Group target for namespace target policies.
|
||||||
|
GROUP = 4;
|
||||||
|
}
|
||||||
|
|
||||||
// Put policies request.
|
// Put policies request.
|
||||||
message PutPoliciesRequest {
|
message PutPoliciesRequest {
|
||||||
message ChainData {
|
message ChainData {
|
||||||
// Namespace.
|
// Policy entity type.
|
||||||
string namespace = 1;
|
PolicyTarget target = 1;
|
||||||
|
// Policy name.
|
||||||
|
string name = 2;
|
||||||
// Chain rules.
|
// Chain rules.
|
||||||
bytes chain = 2;
|
bytes chain = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Body {
|
message Body {
|
||||||
|
@ -101,10 +121,12 @@ message PutPoliciesResponse {
|
||||||
// Remove policies request.
|
// Remove policies request.
|
||||||
message RemovePoliciesRequest {
|
message RemovePoliciesRequest {
|
||||||
message ChainInfo {
|
message ChainInfo {
|
||||||
// Namespace.
|
// Policy entity type.
|
||||||
string namespace = 1;
|
PolicyTarget target = 1;
|
||||||
|
// Policy name.
|
||||||
|
string name = 2;
|
||||||
// Chain id to remove.
|
// Chain id to remove.
|
||||||
bytes chainID = 2;
|
bytes chainID = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Body {
|
message Body {
|
||||||
|
@ -130,10 +152,12 @@ message RemovePoliciesResponse {
|
||||||
// Get policy request.
|
// Get policy request.
|
||||||
message GetPolicyRequest {
|
message GetPolicyRequest {
|
||||||
message Body {
|
message Body {
|
||||||
// Namespace.
|
// Policy entity type.
|
||||||
string namespace = 1;
|
PolicyTarget target = 1;
|
||||||
// Chain id to remove.
|
// Policy name.
|
||||||
bytes chainID = 2;
|
string name = 2;
|
||||||
|
// Chain id to get.
|
||||||
|
bytes chainID = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
Body body = 1;
|
Body body = 1;
|
||||||
|
@ -157,8 +181,10 @@ message GetPolicyResponse {
|
||||||
// List policies request.
|
// List policies request.
|
||||||
message ListPoliciesRequest {
|
message ListPoliciesRequest {
|
||||||
message Body {
|
message Body {
|
||||||
// Namespace.
|
// Policy entity type.
|
||||||
string namespace = 1;
|
PolicyTarget target = 1;
|
||||||
|
// Policy name.
|
||||||
|
string name = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Body body = 1;
|
Body body = 1;
|
||||||
|
|
|
@ -207,8 +207,9 @@ func (x *PutPoliciesRequest_ChainData) StableSize() (size int) {
|
||||||
if x == nil {
|
if x == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
size += proto.StringSize(1, x.Namespace)
|
size += proto.EnumSize(1, int32(x.Target))
|
||||||
size += proto.BytesSize(2, x.Chain)
|
size += proto.StringSize(2, x.Name)
|
||||||
|
size += proto.BytesSize(3, x.Chain)
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,8 +229,9 @@ func (x *PutPoliciesRequest_ChainData) StableMarshal(buf []byte) []byte {
|
||||||
buf = make([]byte, x.StableSize())
|
buf = make([]byte, x.StableSize())
|
||||||
}
|
}
|
||||||
var offset int
|
var offset int
|
||||||
offset += proto.StringMarshal(1, buf[offset:], x.Namespace)
|
offset += proto.EnumMarshal(1, buf[offset:], int32(x.Target))
|
||||||
offset += proto.BytesMarshal(2, buf[offset:], x.Chain)
|
offset += proto.StringMarshal(2, buf[offset:], x.Name)
|
||||||
|
offset += proto.BytesMarshal(3, buf[offset:], x.Chain)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,8 +409,9 @@ func (x *RemovePoliciesRequest_ChainInfo) StableSize() (size int) {
|
||||||
if x == nil {
|
if x == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
size += proto.StringSize(1, x.Namespace)
|
size += proto.EnumSize(1, int32(x.Target))
|
||||||
size += proto.BytesSize(2, x.ChainID)
|
size += proto.StringSize(2, x.Name)
|
||||||
|
size += proto.BytesSize(3, x.ChainID)
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,8 +431,9 @@ func (x *RemovePoliciesRequest_ChainInfo) StableMarshal(buf []byte) []byte {
|
||||||
buf = make([]byte, x.StableSize())
|
buf = make([]byte, x.StableSize())
|
||||||
}
|
}
|
||||||
var offset int
|
var offset int
|
||||||
offset += proto.StringMarshal(1, buf[offset:], x.Namespace)
|
offset += proto.EnumMarshal(1, buf[offset:], int32(x.Target))
|
||||||
offset += proto.BytesMarshal(2, buf[offset:], x.ChainID)
|
offset += proto.StringMarshal(2, buf[offset:], x.Name)
|
||||||
|
offset += proto.BytesMarshal(3, buf[offset:], x.ChainID)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,8 +611,9 @@ func (x *GetPolicyRequest_Body) StableSize() (size int) {
|
||||||
if x == nil {
|
if x == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
size += proto.StringSize(1, x.Namespace)
|
size += proto.EnumSize(1, int32(x.Target))
|
||||||
size += proto.BytesSize(2, x.ChainID)
|
size += proto.StringSize(2, x.Name)
|
||||||
|
size += proto.BytesSize(3, x.ChainID)
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,8 +633,9 @@ func (x *GetPolicyRequest_Body) StableMarshal(buf []byte) []byte {
|
||||||
buf = make([]byte, x.StableSize())
|
buf = make([]byte, x.StableSize())
|
||||||
}
|
}
|
||||||
var offset int
|
var offset int
|
||||||
offset += proto.StringMarshal(1, buf[offset:], x.Namespace)
|
offset += proto.EnumMarshal(1, buf[offset:], int32(x.Target))
|
||||||
offset += proto.BytesMarshal(2, buf[offset:], x.ChainID)
|
offset += proto.StringMarshal(2, buf[offset:], x.Name)
|
||||||
|
offset += proto.BytesMarshal(3, buf[offset:], x.ChainID)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +787,8 @@ func (x *ListPoliciesRequest_Body) StableSize() (size int) {
|
||||||
if x == nil {
|
if x == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
size += proto.StringSize(1, x.Namespace)
|
size += proto.EnumSize(1, int32(x.Target))
|
||||||
|
size += proto.StringSize(2, x.Name)
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,7 +808,8 @@ func (x *ListPoliciesRequest_Body) StableMarshal(buf []byte) []byte {
|
||||||
buf = make([]byte, x.StableSize())
|
buf = make([]byte, x.StableSize())
|
||||||
}
|
}
|
||||||
var offset int
|
var offset int
|
||||||
offset += proto.StringMarshal(1, buf[offset:], x.Namespace)
|
offset += proto.EnumMarshal(1, buf[offset:], int32(x.Target))
|
||||||
|
offset += proto.StringMarshal(2, buf[offset:], x.Name)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.2.0
|
// - protoc-gen-go-grpc v1.2.0
|
||||||
// - protoc v3.21.9
|
// - protoc v3.21.12
|
||||||
// source: pkg/service/control/service.proto
|
// source: pkg/service/control/service.proto
|
||||||
|
|
||||||
package control
|
package control
|
||||||
|
|
Loading…
Reference in a new issue