[#301] Support GetBucketPolicyStatus #332
12 changed files with 205 additions and 24 deletions
|
@ -27,6 +27,7 @@ This document outlines major changes between releases.
|
||||||
- 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)
|
- 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,6 +91,7 @@ const (
|
||||||
ErrBucketNotEmpty
|
ErrBucketNotEmpty
|
||||||
ErrAllAccessDisabled
|
ErrAllAccessDisabled
|
||||||
ErrMalformedPolicy
|
ErrMalformedPolicy
|
||||||
|
ErrMalformedPolicyNotPrincipal
|
||||||
ErrMissingFields
|
ErrMissingFields
|
||||||
ErrMissingCredTag
|
ErrMissingCredTag
|
||||||
ErrCredMalformed
|
ErrCredMalformed
|
||||||
|
@ -665,6 +666,12 @@ 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,6 +650,48 @@ 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())
|
||||||
|
|
||||||
|
@ -731,6 +773,11 @@ 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))
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -1467,6 +1468,41 @@ 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{
|
||||||
|
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 TestBucketPolicyUnmarshal(t *testing.T) {
|
func TestBucketPolicyUnmarshal(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -1557,6 +1593,22 @@ 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,8 +4,10 @@ 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"
|
||||||
|
@ -181,6 +183,7 @@ func prepareHandlerContextBase(t *testing.T, cacheCfg *layer.CachesConfig) *hand
|
||||||
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{
|
||||||
|
@ -301,6 +304,32 @@ func (a *apeMock) SaveACLChains(ns 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,6 +55,19 @@ 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,6 +9,7 @@ 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"
|
||||||
|
@ -77,6 +78,7 @@ 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"
|
||||||
|
|
|
@ -37,6 +37,7 @@ 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)
|
||||||
|
@ -230,6 +231,9 @@ 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,6 +186,11 @@ 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")
|
||||||
|
|
|
@ -207,16 +207,37 @@ See also `GetObject` and other method parameters.
|
||||||
|
|
||||||
## Policy and replication
|
## Policy and replication
|
||||||
|
|
||||||
|
Bucket policy has the following limitations
|
||||||
|
* Supports only AWS principals in format `arn:aws:iam::<namespace>:user/<user>` or wildcard `*`.
|
||||||
|
* No complex conditions (only conditions for groups now supported)
|
||||||
|
|
||||||
|
Simple valid policy example:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [{
|
||||||
|
"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 |
|
| | Method | Comments |
|
||||||
|----|-------------------------|-----------------------------|
|
|-----|-------------------------|-----------------------------|
|
||||||
| 🔵 | DeleteBucketPolicy | |
|
| 🟡 | DeleteBucketPolicy | See Policy limitations |
|
||||||
| 🔵 | DeleteBucketReplication | |
|
| 🔵 | DeleteBucketReplication | |
|
||||||
| 🔵 | DeletePublicAccessBlock | |
|
| 🔵 | DeletePublicAccessBlock | |
|
||||||
| 🟡 | GetBucketPolicy | See ACL limitations |
|
| 🟡 | GetBucketPolicy | See Policy limitations |
|
||||||
| 🔵 | GetBucketPolicyStatus | |
|
| 🟡 | GetBucketPolicyStatus | |
|
||||||
| 🔵 | GetBucketReplication | |
|
| 🔵 | GetBucketReplication | |
|
||||||
| 🟢 | PostPolicyBucket | Upload file using POST form |
|
| 🟢 | PostPolicyBucket | Upload file using POST form |
|
||||||
| 🟡 | PutBucketPolicy | See ACL limitations |
|
| 🟡 | PutBucketPolicy | See Policy limitations |
|
||||||
| 🔵 | PutBucketReplication | |
|
| 🔵 | PutBucketReplication | |
|
||||||
|
|
||||||
## Request payment
|
## Request payment
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -3,10 +3,10 @@ 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.20240215114728-2a124b95bc02
|
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240306101814-c1c7b344b9c0
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.18.1-0.20231218084346-bce7ef18c83b
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.18.1-0.20231218084346-bce7ef18c83b
|
||||||
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-20240301150205-6fe4e2541d0b
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240306103404-8081445ff2f3
|
||||||
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240226094215-c960b1b08831
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240226094215-c960b1b08831
|
||||||
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
|
||||||
|
@ -31,7 +31,7 @@ require (
|
||||||
golang.org/x/crypto v0.14.0
|
golang.org/x/crypto v0.14.0
|
||||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
|
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
|
||||||
google.golang.org/grpc v1.59.0
|
google.golang.org/grpc v1.59.0
|
||||||
google.golang.org/protobuf v1.31.0
|
google.golang.org/protobuf v1.33.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -36,16 +36,16 @@ 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.20240215114728-2a124b95bc02 h1:SAoUNpK1KBcY9NwP3ZZwDMXB5bvGCQiHxpXCw6wdpAI=
|
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.20240215114728-2a124b95bc02/go.mod h1:uY0AYmCznjZdghDnAk7THFIe1Vlg531IxUcus7ZfUJI=
|
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.18.1-0.20231218084346-bce7ef18c83b h1:zdbOxyqkxRyOLc7/2oNFu5tBwwg0Q6+0tJM3RkAxHlE=
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.18.1-0.20231218084346-bce7ef18c83b h1:zdbOxyqkxRyOLc7/2oNFu5tBwwg0Q6+0tJM3RkAxHlE=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.18.1-0.20231218084346-bce7ef18c83b/go.mod h1:YMFtNZy2MgeiSwt0t8lqk8dYBGzlbhmV1cbbstJJ6oY=
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.18.1-0.20231218084346-bce7ef18c83b/go.mod h1:YMFtNZy2MgeiSwt0t8lqk8dYBGzlbhmV1cbbstJJ6oY=
|
||||||
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-20240301150205-6fe4e2541d0b h1:nLIWYXe4e1fWgpKeMfVke/CNBn388egh4fArFdvhfHw=
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240306103404-8081445ff2f3 h1:mdP5eLtDgyj5hFgwGEMfA3Tz9+8GHTxymrtvjSWm3Eo=
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240301150205-6fe4e2541d0b/go.mod h1:XcgrbZ88XfvhAMxmZCQJ0dv6FyRSq6Mg2J7nN8uuO0k=
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240306103404-8081445ff2f3/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-20240226094215-c960b1b08831 h1:yK2iGQlg5kMmU47ZHor/g52mVS1xEgJSRQ4Olp76Cg8=
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240226094215-c960b1b08831 h1:yK2iGQlg5kMmU47ZHor/g52mVS1xEgJSRQ4Olp76Cg8=
|
||||||
|
@ -663,8 +663,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
|
Loading…
Reference in a new issue
Can we separate this lines?