forked from TrueCloudLab/frostfs-api-go
Add v2
version to go module name
Replace all elements from `v2` to root directory. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
2d70391e31
commit
25da5d2e13
267 changed files with 116 additions and 17991 deletions
|
@ -1,11 +1,11 @@
|
||||||
package accounting
|
package accounting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
|
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *BalanceRequestBody) ToGRPCMessage() grpc.Message {
|
func (b *BalanceRequestBody) ToGRPCMessage() grpc.Message {
|
|
@ -1,8 +1,8 @@
|
||||||
package accounting
|
package accounting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
|
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *Decimal) MarshalJSON() ([]byte, error) {
|
func (d *Decimal) MarshalJSON() ([]byte, error) {
|
|
@ -1,9 +1,9 @@
|
||||||
package accounting
|
package accounting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
|
|
||||||
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
|
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
|
@ -3,9 +3,9 @@ package accounting_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
|
|
||||||
accountingtest "github.com/nspcc-dev/neofs-api-go/v2/accounting/test"
|
accountingtest "github.com/nspcc-dev/neofs-api-go/v2/accounting/test"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMessage(t *testing.T) {
|
func TestMessage(t *testing.T) {
|
|
@ -1,11 +1,11 @@
|
||||||
package acl
|
package acl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
|
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RoleToGRPCField converts unified role enum into grpc enum.
|
// RoleToGRPCField converts unified role enum into grpc enum.
|
0
v2/acl/grpc/types.pb.go → acl/grpc/types.pb.go
generated
0
v2/acl/grpc/types.pb.go → acl/grpc/types.pb.go
generated
|
@ -1,8 +1,8 @@
|
||||||
package acl
|
package acl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
|
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f *HeaderFilter) MarshalJSON() ([]byte, error) {
|
func (f *HeaderFilter) MarshalJSON() ([]byte, error) {
|
|
@ -1,9 +1,9 @@
|
||||||
package acl
|
package acl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
|
|
||||||
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
|
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
|
@ -3,9 +3,9 @@ package acl_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
|
|
||||||
acltest "github.com/nspcc-dev/neofs-api-go/v2/acl/test"
|
acltest "github.com/nspcc-dev/neofs-api-go/v2/acl/test"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMessageConvert(t *testing.T) {
|
func TestMessageConvert(t *testing.T) {
|
|
@ -1,11 +1,11 @@
|
||||||
package audit
|
package audit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
|
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *DataAuditResult) ToGRPCMessage() grpc.Message {
|
func (a *DataAuditResult) ToGRPCMessage() grpc.Message {
|
|
@ -1,8 +1,8 @@
|
||||||
package audit
|
package audit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
|
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *DataAuditResult) MarshalJSON() ([]byte, error) {
|
func (a *DataAuditResult) MarshalJSON() ([]byte, error) {
|
|
@ -1,10 +1,10 @@
|
||||||
package audit
|
package audit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/util/proto"
|
|
||||||
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
|
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/util/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
|
@ -3,9 +3,9 @@ package audit_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
|
|
||||||
audittest "github.com/nspcc-dev/neofs-api-go/v2/audit/test"
|
audittest "github.com/nspcc-dev/neofs-api-go/v2/audit/test"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMessageConvert(t *testing.T) {
|
func TestMessageConvert(t *testing.T) {
|
|
@ -1,8 +1,6 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
aclGRPC "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
|
aclGRPC "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
|
||||||
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
|
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
|
||||||
|
@ -10,6 +8,8 @@ import (
|
||||||
netmapGRPC "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
|
netmapGRPC "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||||
sessionGRPC "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
|
sessionGRPC "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
|
||||||
)
|
)
|
|
@ -1,8 +1,8 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
|
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *Attribute) MarshalJSON() ([]byte, error) {
|
func (a *Attribute) MarshalJSON() ([]byte, error) {
|
|
@ -1,9 +1,9 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
|
|
||||||
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
|
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
|
@ -3,9 +3,9 @@ package container_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
|
|
||||||
containertest "github.com/nspcc-dev/neofs-api-go/v2/container/test"
|
containertest "github.com/nspcc-dev/neofs-api-go/v2/container/test"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMessageConvert(t *testing.T) {
|
func TestMessageConvert(t *testing.T) {
|
10
go.mod
10
go.mod
|
@ -1,18 +1,10 @@
|
||||||
module github.com/nspcc-dev/neofs-api-go
|
module github.com/nspcc-dev/neofs-api-go/v2
|
||||||
|
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.1.2
|
|
||||||
github.com/mr-tron/base58 v1.1.2
|
|
||||||
github.com/nspcc-dev/hrw v1.0.9
|
|
||||||
github.com/nspcc-dev/neo-go v0.95.3
|
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0
|
github.com/nspcc-dev/neofs-crypto v0.3.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
|
|
||||||
golang.org/x/text v0.3.7 // indirect
|
|
||||||
google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9 // indirect
|
|
||||||
google.golang.org/grpc v1.41.0
|
google.golang.org/grpc v1.41.0
|
||||||
google.golang.org/protobuf v1.27.1
|
google.golang.org/protobuf v1.27.1
|
||||||
)
|
)
|
||||||
|
|
230
go.sum
230
go.sum
|
@ -1,85 +1,25 @@
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/CityOfZion/neo-go v0.62.1-pre.0.20191114145240-e740fbe708f8/go.mod h1:MJCkWUBhi9pn/CrYO1Q3P687y2KeahrOPS9BD9LDGb0=
|
|
||||||
github.com/CityOfZion/neo-go v0.70.1-pre.0.20191209120015-fccb0085941e/go.mod h1:0enZl0az8xA6PVkwzEOwPWVJGqlt/GO4hA4kmQ5Xzig=
|
|
||||||
github.com/CityOfZion/neo-go v0.70.1-pre.0.20191212173117-32ac01130d4c/go.mod h1:JtlHfeqLywZLswKIKFnAp+yzezY4Dji9qlfQKB2OD/I=
|
|
||||||
github.com/CityOfZion/neo-go v0.71.1-pre.0.20200129171427-f773ec69fb84/go.mod h1:FLI526IrRWHmcsO+mHsCbj64pJZhwQFTLJZu+A4PGOA=
|
|
||||||
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
|
||||||
github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
|
|
||||||
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
|
|
||||||
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530=
|
|
||||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
|
||||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
|
||||||
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
|
|
||||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
|
||||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
|
||||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
|
||||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
|
||||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
|
||||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
|
||||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
|
||||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
|
||||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
|
||||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
|
||||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM=
|
|
||||||
github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
|
||||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
|
||||||
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M=
|
|
||||||
github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-redis/redis v6.10.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
|
@ -90,12 +30,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
|
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
|
||||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
@ -103,135 +39,27 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
|
||||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
|
||||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
|
||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
|
||||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
|
||||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=
|
github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=
|
||||||
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20191205084618-dacb1a30c254/go.mod h1:w1Ln2aT+dBlPhLnuZhBV+DfPEdS2CHWWLp5JTScY3bw=
|
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20191209120240-0d6b7568d9ae/go.mod h1:3FjXOoHmA51EGfb5GS/HOv7VdmngNRTssSeQ729dvGY=
|
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a/go.mod h1:/YFK+XOxxg0Bfm6P92lY5eDSLYfp06XOdL8KAVgXjVk=
|
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1/go.mod h1:O0qtn62prQSqizzoagHmuuKoz8QMkU3SzBoKdEvm3aQ=
|
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20200711144034-c526ccc6f570/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E=
|
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20210302103605-cc75991b7cfb/go.mod h1:U8MSnEShH+o5hexfWJdze6uMFJteP0ko7J2frO7Yu1Y=
|
|
||||||
github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
|
|
||||||
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
|
|
||||||
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
|
|
||||||
github.com/nspcc-dev/neo-go v0.91.0/go.mod h1:G6HdOWvzQ6tlvFdvFSN/PgCzLPN/X/X4d5hTjFRUDcc=
|
|
||||||
github.com/nspcc-dev/neo-go v0.95.1/go.mod h1:bW07ge1WFXsBgqrcPpLUr6OcyQxHqM26MZNesWMdH0c=
|
|
||||||
github.com/nspcc-dev/neo-go v0.95.3 h1:RxBKcmmatbSM2cETGhv3ritmrkU0gUnWItNZvtrBtI0=
|
|
||||||
github.com/nspcc-dev/neo-go v0.95.3/go.mod h1:t15xRFDVhz5o/pstptdoW9N9JJBNn1hZ6APMNiC6MrY=
|
|
||||||
github.com/nspcc-dev/neofs-api-go v1.24.0/go.mod h1:G7dqincfdjBrAbL5nxVp82emF05fSVEqe59ICsoRDI8=
|
|
||||||
github.com/nspcc-dev/neofs-api-go v1.27.1/go.mod h1:i0Cwgvcu9A4M4e58pydbXFisUhSxpfljmuWFPIp2btE=
|
|
||||||
github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=
|
|
||||||
github.com/nspcc-dev/neofs-crypto v0.2.3/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM=
|
github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM=
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
||||||
github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
|
||||||
github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
|
||||||
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
|
||||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
|
||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
|
||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/syndtr/goleveldb v0.0.0-20180307113352-169b1b37be73/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
|
||||||
github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c=
|
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
|
||||||
github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
|
||||||
github.com/yuin/gopher-lua v0.0.0-20191128022950-c6266f4fe8d7/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
|
||||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
|
||||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
@ -239,18 +67,12 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
|
||||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b h1:eB48h3HiRycXNy8E0Gf5e0hv7YT6Kt14L/D73G1fuwo=
|
|
||||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -258,37 +80,12 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
|
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180318012157-96caea41033d/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
@ -301,17 +98,14 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9 h1:XTH066D35LyHehRwlYhoK3qA+Hcgvg5xREG4kFQEW1Y=
|
|
||||||
google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
|
||||||
google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E=
|
google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E=
|
||||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
|
@ -324,20 +118,12 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
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.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
gopkg.in/abiosoft/ishell.v2 v2.0.0/go.mod h1:sFp+cGtH6o4s1FtpVPTMcHq2yue+c4DGOVohJCPUzwY=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
|
||||||
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-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package netmap
|
package netmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
|
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f *Filter) ToGRPCMessage() grpc.Message {
|
func (f *Filter) ToGRPCMessage() grpc.Message {
|
|
@ -1,8 +1,8 @@
|
||||||
package netmap
|
package netmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
|
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *PlacementPolicy) MarshalJSON() ([]byte, error) {
|
func (p *PlacementPolicy) MarshalJSON() ([]byte, error) {
|
|
@ -1,9 +1,9 @@
|
||||||
package netmap
|
package netmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
|
|
||||||
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
|
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
protoutil "github.com/nspcc-dev/neofs-api-go/v2/util/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
|
@ -3,9 +3,9 @@ package netmap_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
|
|
||||||
netmaptest "github.com/nspcc-dev/neofs-api-go/v2/netmap/test"
|
netmaptest "github.com/nspcc-dev/neofs-api-go/v2/netmap/test"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMessageConvert(t *testing.T) {
|
func TestMessageConvert(t *testing.T) {
|
|
@ -3,11 +3,11 @@ package object
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
|
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||||
sessionGRPC "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
|
sessionGRPC "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
|
||||||
)
|
)
|
|
@ -1,8 +1,8 @@
|
||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
|
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *ShortHeader) MarshalJSON() ([]byte, error) {
|
func (h *ShortHeader) MarshalJSON() ([]byte, error) {
|
|
@ -1,10 +1,10 @@
|
||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/util/proto"
|
|
||||||
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
|
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/util/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
|
@ -3,9 +3,9 @@ package object_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/message"
|
|
||||||
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
|
|
||||||
objecttest "github.com/nspcc-dev/neofs-api-go/v2/object/test"
|
objecttest "github.com/nspcc-dev/neofs-api-go/v2/object/test"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/message"
|
||||||
|
messagetest "github.com/nspcc-dev/neofs-api-go/v2/rpc/message/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMessageConvert(t *testing.T) {
|
func TestMessageConvert(t *testing.T) {
|
|
@ -1,74 +0,0 @@
|
||||||
package accounting
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/accounting"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Decimal represents v2-compatible decimal number.
|
|
||||||
type Decimal accounting.Decimal
|
|
||||||
|
|
||||||
// NewDecimal creates, initializes and returns blank Decimal instance.
|
|
||||||
func NewDecimal() *Decimal {
|
|
||||||
return NewDecimalFromV2(new(accounting.Decimal))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDecimalFromV2 converts v2 Decimal to Decimal.
|
|
||||||
func NewDecimalFromV2(d *accounting.Decimal) *Decimal {
|
|
||||||
return (*Decimal)(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns value of the decimal number.
|
|
||||||
func (d *Decimal) Value() int64 {
|
|
||||||
return (*accounting.Decimal)(d).
|
|
||||||
GetValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValue sets value of the decimal number.
|
|
||||||
func (d *Decimal) SetValue(v int64) {
|
|
||||||
(*accounting.Decimal)(d).
|
|
||||||
SetValue(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Precision returns precision of the decimal number.
|
|
||||||
func (d *Decimal) Precision() uint32 {
|
|
||||||
return (*accounting.Decimal)(d).
|
|
||||||
GetPrecision()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPrecision sets precision of the decimal number.
|
|
||||||
func (d *Decimal) SetPrecision(p uint32) {
|
|
||||||
(*accounting.Decimal)(d).
|
|
||||||
SetPrecision(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal marshals Decimal into a protobuf binary form.
|
|
||||||
//
|
|
||||||
// Buffer is allocated when the argument is empty.
|
|
||||||
// Otherwise, the first buffer is used.
|
|
||||||
func (d *Decimal) Marshal(b ...[]byte) ([]byte, error) {
|
|
||||||
var buf []byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
buf = b[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return (*accounting.Decimal)(d).
|
|
||||||
StableMarshal(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal unmarshals protobuf binary representation of Decimal.
|
|
||||||
func (d *Decimal) Unmarshal(data []byte) error {
|
|
||||||
return (*accounting.Decimal)(d).
|
|
||||||
Unmarshal(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Decimal to protobuf JSON format.
|
|
||||||
func (d *Decimal) MarshalJSON() ([]byte, error) {
|
|
||||||
return (*accounting.Decimal)(d).
|
|
||||||
MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Decimal from protobuf JSON format.
|
|
||||||
func (d *Decimal) UnmarshalJSON(data []byte) error {
|
|
||||||
return (*accounting.Decimal)(d).
|
|
||||||
UnmarshalJSON(data)
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package accounting_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/accounting"
|
|
||||||
accountingtest "github.com/nspcc-dev/neofs-api-go/pkg/accounting/test"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDecimal_Value(t *testing.T) {
|
|
||||||
d := accounting.NewDecimal()
|
|
||||||
|
|
||||||
v := int64(3)
|
|
||||||
d.SetValue(v)
|
|
||||||
|
|
||||||
require.Equal(t, v, d.Value())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecimal_Precision(t *testing.T) {
|
|
||||||
d := accounting.NewDecimal()
|
|
||||||
|
|
||||||
p := uint32(3)
|
|
||||||
d.SetPrecision(p)
|
|
||||||
|
|
||||||
require.Equal(t, p, d.Precision())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecimalEncoding(t *testing.T) {
|
|
||||||
d := accountingtest.Generate()
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data, err := d.Marshal()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
d2 := accounting.NewDecimal()
|
|
||||||
require.NoError(t, d2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, d, d2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
|
||||||
data, err := d.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
d2 := accounting.NewDecimal()
|
|
||||||
require.NoError(t, d2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, d, d2)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package accountingtest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/accounting"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Generate returns random accounting.Decimal.
|
|
||||||
func Generate() *accounting.Decimal {
|
|
||||||
d := accounting.NewDecimal()
|
|
||||||
d.SetValue(1)
|
|
||||||
d.SetPrecision(2)
|
|
||||||
|
|
||||||
return d
|
|
||||||
}
|
|
|
@ -1,396 +0,0 @@
|
||||||
package eacl
|
|
||||||
|
|
||||||
import (
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Action taken if EACL record matched request.
|
|
||||||
// Action is compatible with v2 acl.Action enum.
|
|
||||||
type Action uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ActionUnknown is an Action value used to mark action as undefined.
|
|
||||||
ActionUnknown Action = iota
|
|
||||||
|
|
||||||
// ActionAllow is an Action value that allows access to the operation from context.
|
|
||||||
ActionAllow
|
|
||||||
|
|
||||||
// ActionDeny is an Action value that denies access to the operation from context.
|
|
||||||
ActionDeny
|
|
||||||
)
|
|
||||||
|
|
||||||
// Operation is a object service method to match request.
|
|
||||||
// Operation is compatible with v2 acl.Operation enum.
|
|
||||||
type Operation uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// OperationUnknown is an Operation value used to mark operation as undefined.
|
|
||||||
OperationUnknown Operation = iota
|
|
||||||
|
|
||||||
// OperationGet is an object get Operation.
|
|
||||||
OperationGet
|
|
||||||
|
|
||||||
// OperationHead is an Operation of getting the object header.
|
|
||||||
OperationHead
|
|
||||||
|
|
||||||
// OperationPut is an object put Operation.
|
|
||||||
OperationPut
|
|
||||||
|
|
||||||
// OperationDelete is an object delete Operation.
|
|
||||||
OperationDelete
|
|
||||||
|
|
||||||
// OperationSearch is an object search Operation.
|
|
||||||
OperationSearch
|
|
||||||
|
|
||||||
// OperationRange is an object payload range retrieval Operation.
|
|
||||||
OperationRange
|
|
||||||
|
|
||||||
// OperationRangeHash is an object payload range hashing Operation.
|
|
||||||
OperationRangeHash
|
|
||||||
)
|
|
||||||
|
|
||||||
// Role is a group of request senders to match request.
|
|
||||||
// Role is compatible with v2 acl.Role enum.
|
|
||||||
type Role uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// RoleUnknown is a Role value used to mark role as undefined.
|
|
||||||
RoleUnknown Role = iota
|
|
||||||
|
|
||||||
// RoleUser is a group of senders that contains only key of container owner.
|
|
||||||
RoleUser
|
|
||||||
|
|
||||||
// RoleSystem is a group of senders that contains keys of container nodes and
|
|
||||||
// inner ring nodes.
|
|
||||||
RoleSystem
|
|
||||||
|
|
||||||
// RoleOthers is a group of senders that contains none of above keys.
|
|
||||||
RoleOthers
|
|
||||||
)
|
|
||||||
|
|
||||||
// Match is binary operation on filer name and value to check if request is matched.
|
|
||||||
// Match is compatible with v2 acl.MatchType enum.
|
|
||||||
type Match uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// MatchUnknown is a Match value used to mark matcher as undefined.
|
|
||||||
MatchUnknown Match = iota
|
|
||||||
|
|
||||||
// MatchStringEqual is a Match of string equality.
|
|
||||||
MatchStringEqual
|
|
||||||
|
|
||||||
// MatchStringNotEqual is a Match of string inequality.
|
|
||||||
MatchStringNotEqual
|
|
||||||
)
|
|
||||||
|
|
||||||
// FilterHeaderType indicates source of headers to make matches.
|
|
||||||
// FilterHeaderType is compatible with v2 acl.HeaderType enum.
|
|
||||||
type FilterHeaderType uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// HeaderTypeUnknown is a FilterHeaderType value used to mark header type as undefined.
|
|
||||||
HeaderTypeUnknown FilterHeaderType = iota
|
|
||||||
|
|
||||||
// HeaderFromRequest is a FilterHeaderType for request X-Header.
|
|
||||||
HeaderFromRequest
|
|
||||||
|
|
||||||
// HeaderFromObject is a FilterHeaderType for object header.
|
|
||||||
HeaderFromObject
|
|
||||||
|
|
||||||
// HeaderFromService is a FilterHeaderType for service header.
|
|
||||||
HeaderFromService
|
|
||||||
)
|
|
||||||
|
|
||||||
// ToV2 converts Action to v2 Action enum value.
|
|
||||||
func (a Action) ToV2() v2acl.Action {
|
|
||||||
switch a {
|
|
||||||
case ActionAllow:
|
|
||||||
return v2acl.ActionAllow
|
|
||||||
case ActionDeny:
|
|
||||||
return v2acl.ActionDeny
|
|
||||||
default:
|
|
||||||
return v2acl.ActionUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionFromV2 converts v2 Action enum value to Action.
|
|
||||||
func ActionFromV2(action v2acl.Action) (a Action) {
|
|
||||||
switch action {
|
|
||||||
case v2acl.ActionAllow:
|
|
||||||
a = ActionAllow
|
|
||||||
case v2acl.ActionDeny:
|
|
||||||
a = ActionDeny
|
|
||||||
default:
|
|
||||||
a = ActionUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns string representation of Action.
|
|
||||||
//
|
|
||||||
// String mapping:
|
|
||||||
// * ActionAllow: ALLOW;
|
|
||||||
// * ActionDeny: DENY;
|
|
||||||
// * ActionUnknown, default: ACTION_UNSPECIFIED.
|
|
||||||
func (a Action) String() string {
|
|
||||||
return a.ToV2().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromString parses Action from a string representation.
|
|
||||||
// It is a reverse action to String().
|
|
||||||
//
|
|
||||||
// Returns true if s was parsed successfully.
|
|
||||||
func (a *Action) FromString(s string) bool {
|
|
||||||
var g v2acl.Action
|
|
||||||
|
|
||||||
ok := g.FromString(s)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
*a = ActionFromV2(g)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Operation to v2 Operation enum value.
|
|
||||||
func (o Operation) ToV2() v2acl.Operation {
|
|
||||||
switch o {
|
|
||||||
case OperationGet:
|
|
||||||
return v2acl.OperationGet
|
|
||||||
case OperationHead:
|
|
||||||
return v2acl.OperationHead
|
|
||||||
case OperationPut:
|
|
||||||
return v2acl.OperationPut
|
|
||||||
case OperationDelete:
|
|
||||||
return v2acl.OperationDelete
|
|
||||||
case OperationSearch:
|
|
||||||
return v2acl.OperationSearch
|
|
||||||
case OperationRange:
|
|
||||||
return v2acl.OperationRange
|
|
||||||
case OperationRangeHash:
|
|
||||||
return v2acl.OperationRangeHash
|
|
||||||
default:
|
|
||||||
return v2acl.OperationUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// OperationFromV2 converts v2 Operation enum value to Operation.
|
|
||||||
func OperationFromV2(operation v2acl.Operation) (o Operation) {
|
|
||||||
switch operation {
|
|
||||||
case v2acl.OperationGet:
|
|
||||||
o = OperationGet
|
|
||||||
case v2acl.OperationHead:
|
|
||||||
o = OperationHead
|
|
||||||
case v2acl.OperationPut:
|
|
||||||
o = OperationPut
|
|
||||||
case v2acl.OperationDelete:
|
|
||||||
o = OperationDelete
|
|
||||||
case v2acl.OperationSearch:
|
|
||||||
o = OperationSearch
|
|
||||||
case v2acl.OperationRange:
|
|
||||||
o = OperationRange
|
|
||||||
case v2acl.OperationRangeHash:
|
|
||||||
o = OperationRangeHash
|
|
||||||
default:
|
|
||||||
o = OperationUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
return o
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns string representation of Operation.
|
|
||||||
//
|
|
||||||
// String mapping:
|
|
||||||
// * OperationGet: GET;
|
|
||||||
// * OperationHead: HEAD;
|
|
||||||
// * OperationPut: PUT;
|
|
||||||
// * OperationDelete: DELETE;
|
|
||||||
// * OperationSearch: SEARCH;
|
|
||||||
// * OperationRange: GETRANGE;
|
|
||||||
// * OperationRangeHash: GETRANGEHASH;
|
|
||||||
// * OperationUnknown, default: OPERATION_UNSPECIFIED.
|
|
||||||
func (o Operation) String() string {
|
|
||||||
return o.ToV2().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromString parses Operation from a string representation.
|
|
||||||
// It is a reverse action to String().
|
|
||||||
//
|
|
||||||
// Returns true if s was parsed successfully.
|
|
||||||
func (o *Operation) FromString(s string) bool {
|
|
||||||
var g v2acl.Operation
|
|
||||||
|
|
||||||
ok := g.FromString(s)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
*o = OperationFromV2(g)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Role to v2 Role enum value.
|
|
||||||
func (r Role) ToV2() v2acl.Role {
|
|
||||||
switch r {
|
|
||||||
case RoleUser:
|
|
||||||
return v2acl.RoleUser
|
|
||||||
case RoleSystem:
|
|
||||||
return v2acl.RoleSystem
|
|
||||||
case RoleOthers:
|
|
||||||
return v2acl.RoleOthers
|
|
||||||
default:
|
|
||||||
return v2acl.RoleUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RoleFromV2 converts v2 Role enum value to Role.
|
|
||||||
func RoleFromV2(role v2acl.Role) (r Role) {
|
|
||||||
switch role {
|
|
||||||
case v2acl.RoleUser:
|
|
||||||
r = RoleUser
|
|
||||||
case v2acl.RoleSystem:
|
|
||||||
r = RoleSystem
|
|
||||||
case v2acl.RoleOthers:
|
|
||||||
r = RoleOthers
|
|
||||||
default:
|
|
||||||
r = RoleUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns string representation of Role.
|
|
||||||
//
|
|
||||||
// String mapping:
|
|
||||||
// * RoleUser: USER;
|
|
||||||
// * RoleSystem: SYSTEM;
|
|
||||||
// * RoleOthers: OTHERS;
|
|
||||||
// * RoleUnknown, default: ROLE_UNKNOWN.
|
|
||||||
func (r Role) String() string {
|
|
||||||
return r.ToV2().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromString parses Role from a string representation.
|
|
||||||
// It is a reverse action to String().
|
|
||||||
//
|
|
||||||
// Returns true if s was parsed successfully.
|
|
||||||
func (r *Role) FromString(s string) bool {
|
|
||||||
var g v2acl.Role
|
|
||||||
|
|
||||||
ok := g.FromString(s)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
*r = RoleFromV2(g)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Match to v2 MatchType enum value.
|
|
||||||
func (m Match) ToV2() v2acl.MatchType {
|
|
||||||
switch m {
|
|
||||||
case MatchStringEqual:
|
|
||||||
return v2acl.MatchTypeStringEqual
|
|
||||||
case MatchStringNotEqual:
|
|
||||||
return v2acl.MatchTypeStringNotEqual
|
|
||||||
default:
|
|
||||||
return v2acl.MatchTypeUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MatchFromV2 converts v2 MatchType enum value to Match.
|
|
||||||
func MatchFromV2(match v2acl.MatchType) (m Match) {
|
|
||||||
switch match {
|
|
||||||
case v2acl.MatchTypeStringEqual:
|
|
||||||
m = MatchStringEqual
|
|
||||||
case v2acl.MatchTypeStringNotEqual:
|
|
||||||
m = MatchStringNotEqual
|
|
||||||
default:
|
|
||||||
m = MatchUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns string representation of Match.
|
|
||||||
//
|
|
||||||
// String mapping:
|
|
||||||
// * MatchStringEqual: STRING_EQUAL;
|
|
||||||
// * MatchStringNotEqual: STRING_NOT_EQUAL;
|
|
||||||
// * MatchUnknown, default: MATCH_TYPE_UNSPECIFIED.
|
|
||||||
func (m Match) String() string {
|
|
||||||
return m.ToV2().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromString parses Match from a string representation.
|
|
||||||
// It is a reverse action to String().
|
|
||||||
//
|
|
||||||
// Returns true if s was parsed successfully.
|
|
||||||
func (m *Match) FromString(s string) bool {
|
|
||||||
var g v2acl.MatchType
|
|
||||||
|
|
||||||
ok := g.FromString(s)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
*m = MatchFromV2(g)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts FilterHeaderType to v2 HeaderType enum value.
|
|
||||||
func (h FilterHeaderType) ToV2() v2acl.HeaderType {
|
|
||||||
switch h {
|
|
||||||
case HeaderFromRequest:
|
|
||||||
return v2acl.HeaderTypeRequest
|
|
||||||
case HeaderFromObject:
|
|
||||||
return v2acl.HeaderTypeObject
|
|
||||||
case HeaderFromService:
|
|
||||||
return v2acl.HeaderTypeService
|
|
||||||
default:
|
|
||||||
return v2acl.HeaderTypeUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FilterHeaderTypeFromV2 converts v2 HeaderType enum value to FilterHeaderType.
|
|
||||||
func FilterHeaderTypeFromV2(header v2acl.HeaderType) (h FilterHeaderType) {
|
|
||||||
switch header {
|
|
||||||
case v2acl.HeaderTypeRequest:
|
|
||||||
h = HeaderFromRequest
|
|
||||||
case v2acl.HeaderTypeObject:
|
|
||||||
h = HeaderFromObject
|
|
||||||
case v2acl.HeaderTypeService:
|
|
||||||
h = HeaderFromService
|
|
||||||
default:
|
|
||||||
h = HeaderTypeUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns string representation of FilterHeaderType.
|
|
||||||
//
|
|
||||||
// String mapping:
|
|
||||||
// * HeaderFromRequest: REQUEST;
|
|
||||||
// * HeaderFromObject: OBJECT;
|
|
||||||
// * HeaderTypeUnknown, default: HEADER_UNSPECIFIED.
|
|
||||||
func (h FilterHeaderType) String() string {
|
|
||||||
return h.ToV2().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromString parses FilterHeaderType from a string representation.
|
|
||||||
// It is a reverse action to String().
|
|
||||||
//
|
|
||||||
// Returns true if s was parsed successfully.
|
|
||||||
func (h *FilterHeaderType) FromString(s string) bool {
|
|
||||||
var g v2acl.HeaderType
|
|
||||||
|
|
||||||
ok := g.FromString(s)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
*h = FilterHeaderTypeFromV2(g)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok
|
|
||||||
}
|
|
|
@ -1,214 +0,0 @@
|
||||||
package eacl_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
eqV2Actions = map[eacl.Action]v2acl.Action{
|
|
||||||
eacl.ActionUnknown: v2acl.ActionUnknown,
|
|
||||||
eacl.ActionAllow: v2acl.ActionAllow,
|
|
||||||
eacl.ActionDeny: v2acl.ActionDeny,
|
|
||||||
}
|
|
||||||
|
|
||||||
eqV2Operations = map[eacl.Operation]v2acl.Operation{
|
|
||||||
eacl.OperationUnknown: v2acl.OperationUnknown,
|
|
||||||
eacl.OperationGet: v2acl.OperationGet,
|
|
||||||
eacl.OperationHead: v2acl.OperationHead,
|
|
||||||
eacl.OperationPut: v2acl.OperationPut,
|
|
||||||
eacl.OperationDelete: v2acl.OperationDelete,
|
|
||||||
eacl.OperationSearch: v2acl.OperationSearch,
|
|
||||||
eacl.OperationRange: v2acl.OperationRange,
|
|
||||||
eacl.OperationRangeHash: v2acl.OperationRangeHash,
|
|
||||||
}
|
|
||||||
|
|
||||||
eqV2Roles = map[eacl.Role]v2acl.Role{
|
|
||||||
eacl.RoleUnknown: v2acl.RoleUnknown,
|
|
||||||
eacl.RoleUser: v2acl.RoleUser,
|
|
||||||
eacl.RoleSystem: v2acl.RoleSystem,
|
|
||||||
eacl.RoleOthers: v2acl.RoleOthers,
|
|
||||||
}
|
|
||||||
|
|
||||||
eqV2Matches = map[eacl.Match]v2acl.MatchType{
|
|
||||||
eacl.MatchUnknown: v2acl.MatchTypeUnknown,
|
|
||||||
eacl.MatchStringEqual: v2acl.MatchTypeStringEqual,
|
|
||||||
eacl.MatchStringNotEqual: v2acl.MatchTypeStringNotEqual,
|
|
||||||
}
|
|
||||||
|
|
||||||
eqV2HeaderTypes = map[eacl.FilterHeaderType]v2acl.HeaderType{
|
|
||||||
eacl.HeaderTypeUnknown: v2acl.HeaderTypeUnknown,
|
|
||||||
eacl.HeaderFromRequest: v2acl.HeaderTypeRequest,
|
|
||||||
eacl.HeaderFromObject: v2acl.HeaderTypeObject,
|
|
||||||
eacl.HeaderFromService: v2acl.HeaderTypeService,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAction(t *testing.T) {
|
|
||||||
t.Run("known actions", func(t *testing.T) {
|
|
||||||
for i := eacl.ActionUnknown; i <= eacl.ActionDeny; i++ {
|
|
||||||
require.Equal(t, eqV2Actions[i], i.ToV2())
|
|
||||||
require.Equal(t, eacl.ActionFromV2(i.ToV2()), i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("unknown actions", func(t *testing.T) {
|
|
||||||
require.Equal(t, (eacl.ActionDeny + 1).ToV2(), v2acl.ActionUnknown)
|
|
||||||
require.Equal(t, eacl.ActionFromV2(v2acl.ActionDeny+1), eacl.ActionUnknown)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOperation(t *testing.T) {
|
|
||||||
t.Run("known operations", func(t *testing.T) {
|
|
||||||
for i := eacl.OperationUnknown; i <= eacl.OperationRangeHash; i++ {
|
|
||||||
require.Equal(t, eqV2Operations[i], i.ToV2())
|
|
||||||
require.Equal(t, eacl.OperationFromV2(i.ToV2()), i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("unknown operations", func(t *testing.T) {
|
|
||||||
require.Equal(t, (eacl.OperationRangeHash + 1).ToV2(), v2acl.OperationUnknown)
|
|
||||||
require.Equal(t, eacl.OperationFromV2(v2acl.OperationRangeHash+1), eacl.OperationUnknown)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRole(t *testing.T) {
|
|
||||||
t.Run("known roles", func(t *testing.T) {
|
|
||||||
for i := eacl.RoleUnknown; i <= eacl.RoleOthers; i++ {
|
|
||||||
require.Equal(t, eqV2Roles[i], i.ToV2())
|
|
||||||
require.Equal(t, eacl.RoleFromV2(i.ToV2()), i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("unknown roles", func(t *testing.T) {
|
|
||||||
require.Equal(t, (eacl.RoleOthers + 1).ToV2(), v2acl.RoleUnknown)
|
|
||||||
require.Equal(t, eacl.RoleFromV2(v2acl.RoleOthers+1), eacl.RoleUnknown)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMatch(t *testing.T) {
|
|
||||||
t.Run("known matches", func(t *testing.T) {
|
|
||||||
for i := eacl.MatchUnknown; i <= eacl.MatchStringNotEqual; i++ {
|
|
||||||
require.Equal(t, eqV2Matches[i], i.ToV2())
|
|
||||||
require.Equal(t, eacl.MatchFromV2(i.ToV2()), i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("unknown matches", func(t *testing.T) {
|
|
||||||
require.Equal(t, (eacl.MatchStringNotEqual + 1).ToV2(), v2acl.MatchTypeUnknown)
|
|
||||||
require.Equal(t, eacl.MatchFromV2(v2acl.MatchTypeStringNotEqual+1), eacl.MatchUnknown)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterHeaderType(t *testing.T) {
|
|
||||||
t.Run("known header types", func(t *testing.T) {
|
|
||||||
for i := eacl.HeaderTypeUnknown; i <= eacl.HeaderFromService; i++ {
|
|
||||||
require.Equal(t, eqV2HeaderTypes[i], i.ToV2())
|
|
||||||
require.Equal(t, eacl.FilterHeaderTypeFromV2(i.ToV2()), i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("unknown header types", func(t *testing.T) {
|
|
||||||
require.Equal(t, (eacl.HeaderFromService + 1).ToV2(), v2acl.HeaderTypeUnknown)
|
|
||||||
require.Equal(t, eacl.FilterHeaderTypeFromV2(v2acl.HeaderTypeService+1), eacl.HeaderTypeUnknown)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type enumIface interface {
|
|
||||||
FromString(string) bool
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type enumStringItem struct {
|
|
||||||
val enumIface
|
|
||||||
str string
|
|
||||||
}
|
|
||||||
|
|
||||||
func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) {
|
|
||||||
for _, item := range items {
|
|
||||||
require.Equal(t, item.str, item.val.String())
|
|
||||||
|
|
||||||
s := item.val.String()
|
|
||||||
|
|
||||||
require.True(t, e.FromString(s), s)
|
|
||||||
|
|
||||||
require.EqualValues(t, item.val, e, item.val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// incorrect strings
|
|
||||||
for _, str := range []string{
|
|
||||||
"some string",
|
|
||||||
"UNSPECIFIED",
|
|
||||||
} {
|
|
||||||
require.False(t, e.FromString(str))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAction_String(t *testing.T) {
|
|
||||||
toPtr := func(v eacl.Action) *eacl.Action {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
testEnumStrings(t, new(eacl.Action), []enumStringItem{
|
|
||||||
{val: toPtr(eacl.ActionAllow), str: "ALLOW"},
|
|
||||||
{val: toPtr(eacl.ActionDeny), str: "DENY"},
|
|
||||||
{val: toPtr(eacl.ActionUnknown), str: "ACTION_UNSPECIFIED"},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRole_String(t *testing.T) {
|
|
||||||
toPtr := func(v eacl.Role) *eacl.Role {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
testEnumStrings(t, new(eacl.Role), []enumStringItem{
|
|
||||||
{val: toPtr(eacl.RoleUser), str: "USER"},
|
|
||||||
{val: toPtr(eacl.RoleSystem), str: "SYSTEM"},
|
|
||||||
{val: toPtr(eacl.RoleOthers), str: "OTHERS"},
|
|
||||||
{val: toPtr(eacl.RoleUnknown), str: "ROLE_UNSPECIFIED"},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOperation_String(t *testing.T) {
|
|
||||||
toPtr := func(v eacl.Operation) *eacl.Operation {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
testEnumStrings(t, new(eacl.Operation), []enumStringItem{
|
|
||||||
{val: toPtr(eacl.OperationGet), str: "GET"},
|
|
||||||
{val: toPtr(eacl.OperationPut), str: "PUT"},
|
|
||||||
{val: toPtr(eacl.OperationHead), str: "HEAD"},
|
|
||||||
{val: toPtr(eacl.OperationDelete), str: "DELETE"},
|
|
||||||
{val: toPtr(eacl.OperationSearch), str: "SEARCH"},
|
|
||||||
{val: toPtr(eacl.OperationRange), str: "GETRANGE"},
|
|
||||||
{val: toPtr(eacl.OperationRangeHash), str: "GETRANGEHASH"},
|
|
||||||
{val: toPtr(eacl.OperationUnknown), str: "OPERATION_UNSPECIFIED"},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMatch_String(t *testing.T) {
|
|
||||||
toPtr := func(v eacl.Match) *eacl.Match {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
testEnumStrings(t, new(eacl.Match), []enumStringItem{
|
|
||||||
{val: toPtr(eacl.MatchStringEqual), str: "STRING_EQUAL"},
|
|
||||||
{val: toPtr(eacl.MatchStringNotEqual), str: "STRING_NOT_EQUAL"},
|
|
||||||
{val: toPtr(eacl.MatchUnknown), str: "MATCH_TYPE_UNSPECIFIED"},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterHeaderType_String(t *testing.T) {
|
|
||||||
toPtr := func(v eacl.FilterHeaderType) *eacl.FilterHeaderType {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
testEnumStrings(t, new(eacl.FilterHeaderType), []enumStringItem{
|
|
||||||
{val: toPtr(eacl.HeaderFromRequest), str: "REQUEST"},
|
|
||||||
{val: toPtr(eacl.HeaderFromObject), str: "OBJECT"},
|
|
||||||
{val: toPtr(eacl.HeaderTypeUnknown), str: "HEADER_UNSPECIFIED"},
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,186 +0,0 @@
|
||||||
package eacl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Filter defines check conditions if request header is matched or not. Matched
|
|
||||||
// header means that request should be processed according to EACL action.
|
|
||||||
//
|
|
||||||
// Filter is compatible with v2 acl.EACLRecord.Filter message.
|
|
||||||
type Filter struct {
|
|
||||||
from FilterHeaderType
|
|
||||||
matcher Match
|
|
||||||
key filterKey
|
|
||||||
value fmt.Stringer
|
|
||||||
}
|
|
||||||
|
|
||||||
type staticStringer string
|
|
||||||
|
|
||||||
type u64Stringer uint64
|
|
||||||
|
|
||||||
type filterKey struct {
|
|
||||||
typ filterKeyType
|
|
||||||
|
|
||||||
str string
|
|
||||||
}
|
|
||||||
|
|
||||||
// enumeration of reserved filter keys.
|
|
||||||
type filterKeyType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
_ filterKeyType = iota
|
|
||||||
fKeyObjVersion
|
|
||||||
fKeyObjID
|
|
||||||
fKeyObjContainerID
|
|
||||||
fKeyObjOwnerID
|
|
||||||
fKeyObjCreationEpoch
|
|
||||||
fKeyObjPayloadLength
|
|
||||||
fKeyObjPayloadHash
|
|
||||||
fKeyObjType
|
|
||||||
fKeyObjHomomorphicHash
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s staticStringer) String() string {
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u u64Stringer) String() string {
|
|
||||||
return strconv.FormatUint(uint64(u), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns filtered string value.
|
|
||||||
func (f Filter) Value() string {
|
|
||||||
return f.value.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Matcher returns filter Match type.
|
|
||||||
func (f Filter) Matcher() Match {
|
|
||||||
return f.matcher
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key returns key to the filtered header.
|
|
||||||
func (f Filter) Key() string {
|
|
||||||
return f.key.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// From returns FilterHeaderType that defined which header will be filtered.
|
|
||||||
func (f Filter) From() FilterHeaderType {
|
|
||||||
return f.from
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Filter to v2 acl.EACLRecord.Filter message.
|
|
||||||
//
|
|
||||||
// Nil Filter converts to nil.
|
|
||||||
func (f *Filter) ToV2() *v2acl.HeaderFilter {
|
|
||||||
if f == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := new(v2acl.HeaderFilter)
|
|
||||||
filter.SetValue(f.value.String())
|
|
||||||
filter.SetKey(f.key.String())
|
|
||||||
filter.SetMatchType(f.matcher.ToV2())
|
|
||||||
filter.SetHeaderType(f.from.ToV2())
|
|
||||||
|
|
||||||
return filter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k filterKey) String() string {
|
|
||||||
switch k.typ {
|
|
||||||
default:
|
|
||||||
return k.str
|
|
||||||
case fKeyObjVersion:
|
|
||||||
return v2acl.FilterObjectVersion
|
|
||||||
case fKeyObjID:
|
|
||||||
return v2acl.FilterObjectID
|
|
||||||
case fKeyObjContainerID:
|
|
||||||
return v2acl.FilterObjectContainerID
|
|
||||||
case fKeyObjOwnerID:
|
|
||||||
return v2acl.FilterObjectOwnerID
|
|
||||||
case fKeyObjCreationEpoch:
|
|
||||||
return v2acl.FilterObjectCreationEpoch
|
|
||||||
case fKeyObjPayloadLength:
|
|
||||||
return v2acl.FilterObjectPayloadLength
|
|
||||||
case fKeyObjPayloadHash:
|
|
||||||
return v2acl.FilterObjectPayloadHash
|
|
||||||
case fKeyObjType:
|
|
||||||
return v2acl.FilterObjectType
|
|
||||||
case fKeyObjHomomorphicHash:
|
|
||||||
return v2acl.FilterObjectHomomorphicHash
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFilter creates, initializes and returns blank Filter instance.
|
|
||||||
//
|
|
||||||
// Defaults:
|
|
||||||
// - header type: HeaderTypeUnknown;
|
|
||||||
// - matcher: MatchUnknown;
|
|
||||||
// - key: "";
|
|
||||||
// - value: "".
|
|
||||||
func NewFilter() *Filter {
|
|
||||||
return NewFilterFromV2(new(v2acl.HeaderFilter))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFilterFromV2 converts v2 acl.EACLRecord.Filter message to Filter.
|
|
||||||
func NewFilterFromV2(filter *v2acl.HeaderFilter) *Filter {
|
|
||||||
f := new(Filter)
|
|
||||||
|
|
||||||
if filter == nil {
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
f.from = FilterHeaderTypeFromV2(filter.GetHeaderType())
|
|
||||||
f.matcher = MatchFromV2(filter.GetMatchType())
|
|
||||||
f.key.str = filter.GetKey()
|
|
||||||
f.value = staticStringer(filter.GetValue())
|
|
||||||
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal marshals Filter into a protobuf binary form.
|
|
||||||
//
|
|
||||||
// Buffer is allocated when the argument is empty.
|
|
||||||
// Otherwise, the first buffer is used.
|
|
||||||
func (f *Filter) Marshal(b ...[]byte) ([]byte, error) {
|
|
||||||
var buf []byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
buf = b[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return f.ToV2().
|
|
||||||
StableMarshal(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal unmarshals protobuf binary representation of Filter.
|
|
||||||
func (f *Filter) Unmarshal(data []byte) error {
|
|
||||||
fV2 := new(v2acl.HeaderFilter)
|
|
||||||
if err := fV2.Unmarshal(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*f = *NewFilterFromV2(fV2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Filter to protobuf JSON format.
|
|
||||||
func (f *Filter) MarshalJSON() ([]byte, error) {
|
|
||||||
return f.ToV2().
|
|
||||||
MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Filter from protobuf JSON format.
|
|
||||||
func (f *Filter) UnmarshalJSON(data []byte) error {
|
|
||||||
fV2 := new(v2acl.HeaderFilter)
|
|
||||||
if err := fV2.UnmarshalJSON(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*f = *NewFilterFromV2(fV2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
package eacl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newObjectFilter(match Match, key, val string) *Filter {
|
|
||||||
return &Filter{
|
|
||||||
from: HeaderFromObject,
|
|
||||||
key: filterKey{
|
|
||||||
str: key,
|
|
||||||
},
|
|
||||||
matcher: match,
|
|
||||||
value: staticStringer(val),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilter(t *testing.T) {
|
|
||||||
filter := newObjectFilter(MatchStringEqual, "some name", "200")
|
|
||||||
|
|
||||||
v2 := filter.ToV2()
|
|
||||||
require.NotNil(t, v2)
|
|
||||||
require.Equal(t, v2acl.HeaderTypeObject, v2.GetHeaderType())
|
|
||||||
require.EqualValues(t, v2acl.MatchTypeStringEqual, v2.GetMatchType())
|
|
||||||
require.Equal(t, filter.Key(), v2.GetKey())
|
|
||||||
require.Equal(t, filter.Value(), v2.GetValue())
|
|
||||||
|
|
||||||
newFilter := NewFilterFromV2(v2)
|
|
||||||
require.Equal(t, filter, newFilter)
|
|
||||||
|
|
||||||
t.Run("from nil v2 filter", func(t *testing.T) {
|
|
||||||
require.Equal(t, new(Filter), NewFilterFromV2(nil))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterEncoding(t *testing.T) {
|
|
||||||
f := newObjectFilter(MatchStringEqual, "key", "value")
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data, err := f.Marshal()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
f2 := NewFilter()
|
|
||||||
require.NoError(t, f2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, f, f2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
|
||||||
data, err := f.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
d2 := NewFilter()
|
|
||||||
require.NoError(t, d2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, f, d2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilter_ToV2(t *testing.T) {
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
|
||||||
var x *Filter
|
|
||||||
|
|
||||||
require.Nil(t, x.ToV2())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("default values", func(t *testing.T) {
|
|
||||||
filter := NewFilter()
|
|
||||||
|
|
||||||
// check initial values
|
|
||||||
require.Empty(t, filter.Key())
|
|
||||||
require.Empty(t, filter.Value())
|
|
||||||
require.Equal(t, HeaderTypeUnknown, filter.From())
|
|
||||||
require.Equal(t, MatchUnknown, filter.Matcher())
|
|
||||||
|
|
||||||
// convert to v2 message
|
|
||||||
filterV2 := filter.ToV2()
|
|
||||||
|
|
||||||
require.Empty(t, filterV2.GetKey())
|
|
||||||
require.Empty(t, filterV2.GetValue())
|
|
||||||
require.Equal(t, acl.HeaderTypeUnknown, filterV2.GetHeaderType())
|
|
||||||
require.Equal(t, acl.MatchTypeUnknown, filterV2.GetMatchType())
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,284 +0,0 @@
|
||||||
package eacl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
|
||||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Record of the EACL rule, that defines EACL action, targets for this action,
|
|
||||||
// object service operation and filters for request headers.
|
|
||||||
//
|
|
||||||
// Record is compatible with v2 acl.EACLRecord message.
|
|
||||||
type Record struct {
|
|
||||||
action Action
|
|
||||||
operation Operation
|
|
||||||
filters []*Filter
|
|
||||||
targets []*Target
|
|
||||||
}
|
|
||||||
|
|
||||||
// Targets returns list of target subjects to apply ACL rule to.
|
|
||||||
func (r Record) Targets() []*Target {
|
|
||||||
return r.targets
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTargets sets list of target subjects to apply ACL rule to.
|
|
||||||
func (r *Record) SetTargets(targets ...*Target) {
|
|
||||||
r.targets = targets
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filters returns list of filters to match and see if rule is applicable.
|
|
||||||
func (r Record) Filters() []*Filter {
|
|
||||||
return r.filters
|
|
||||||
}
|
|
||||||
|
|
||||||
// Operation returns NeoFS request verb to match.
|
|
||||||
func (r Record) Operation() Operation {
|
|
||||||
return r.operation
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOperation sets NeoFS request verb to match.
|
|
||||||
func (r *Record) SetOperation(operation Operation) {
|
|
||||||
r.operation = operation
|
|
||||||
}
|
|
||||||
|
|
||||||
// Action returns rule execution result.
|
|
||||||
func (r Record) Action() Action {
|
|
||||||
return r.action
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAction sets rule execution result.
|
|
||||||
func (r *Record) SetAction(action Action) {
|
|
||||||
r.action = action
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddTarget adds target subject with specified Role and key list.
|
|
||||||
//
|
|
||||||
// Deprecated: use AddFormedTarget instead.
|
|
||||||
func (r *Record) AddTarget(role Role, keys ...ecdsa.PublicKey) {
|
|
||||||
AddFormedTarget(r, role, keys...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddRecordTarget adds single Target to the Record.
|
|
||||||
func AddRecordTarget(r *Record, t *Target) {
|
|
||||||
r.SetTargets(append(r.Targets(), t)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddFormedTarget forms Target with specified Role and list of
|
|
||||||
// ECDSA public keys and adds it to the Record.
|
|
||||||
func AddFormedTarget(r *Record, role Role, keys ...ecdsa.PublicKey) {
|
|
||||||
t := NewTarget()
|
|
||||||
t.SetRole(role)
|
|
||||||
SetTargetECDSAKeys(t, ecdsaKeysToPtrs(keys)...)
|
|
||||||
|
|
||||||
AddRecordTarget(r, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Record) addFilter(from FilterHeaderType, m Match, keyTyp filterKeyType, key string, val fmt.Stringer) {
|
|
||||||
filter := &Filter{
|
|
||||||
from: from,
|
|
||||||
key: filterKey{
|
|
||||||
typ: keyTyp,
|
|
||||||
str: key,
|
|
||||||
},
|
|
||||||
matcher: m,
|
|
||||||
value: val,
|
|
||||||
}
|
|
||||||
|
|
||||||
r.filters = append(r.filters, filter)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Record) addObjectFilter(m Match, keyTyp filterKeyType, key string, val fmt.Stringer) {
|
|
||||||
r.addFilter(HeaderFromObject, m, keyTyp, key, val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Record) addObjectReservedFilter(m Match, typ filterKeyType, val fmt.Stringer) {
|
|
||||||
r.addObjectFilter(m, typ, "", val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddFilter adds generic filter.
|
|
||||||
func (r *Record) AddFilter(from FilterHeaderType, matcher Match, name, value string) {
|
|
||||||
r.addFilter(from, matcher, 0, name, staticStringer(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectAttributeFilter adds filter by object attribute.
|
|
||||||
func (r *Record) AddObjectAttributeFilter(m Match, key, value string) {
|
|
||||||
r.addObjectFilter(m, 0, key, staticStringer(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectVersionFilter adds filter by object version.
|
|
||||||
func (r *Record) AddObjectVersionFilter(m Match, v *pkg.Version) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjVersion, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectIDFilter adds filter by object ID.
|
|
||||||
func (r *Record) AddObjectIDFilter(m Match, id *object.ID) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjID, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectContainerIDFilter adds filter by object container ID.
|
|
||||||
func (r *Record) AddObjectContainerIDFilter(m Match, id *cid.ID) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjContainerID, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectOwnerIDFilter adds filter by object owner ID.
|
|
||||||
func (r *Record) AddObjectOwnerIDFilter(m Match, id *owner.ID) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjOwnerID, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectCreationEpoch adds filter by object creation epoch.
|
|
||||||
func (r *Record) AddObjectCreationEpoch(m Match, epoch uint64) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjCreationEpoch, u64Stringer(epoch))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectPayloadLengthFilter adds filter by object payload length.
|
|
||||||
func (r *Record) AddObjectPayloadLengthFilter(m Match, size uint64) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjPayloadLength, u64Stringer(size))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectPayloadHashFilter adds filter by object payload hash value.
|
|
||||||
func (r *Record) AddObjectPayloadHashFilter(m Match, h *pkg.Checksum) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjPayloadHash, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectTypeFilter adds filter by object type.
|
|
||||||
func (r *Record) AddObjectTypeFilter(m Match, t object.Type) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjType, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddObjectHomomorphicHashFilter adds filter by object payload homomorphic hash value.
|
|
||||||
func (r *Record) AddObjectHomomorphicHashFilter(m Match, h *pkg.Checksum) {
|
|
||||||
r.addObjectReservedFilter(m, fKeyObjHomomorphicHash, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Record to v2 acl.EACLRecord message.
|
|
||||||
//
|
|
||||||
// Nil Record converts to nil.
|
|
||||||
func (r *Record) ToV2() *v2acl.Record {
|
|
||||||
if r == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
v2 := new(v2acl.Record)
|
|
||||||
|
|
||||||
if r.targets != nil {
|
|
||||||
targets := make([]*v2acl.Target, 0, len(r.targets))
|
|
||||||
for _, target := range r.targets {
|
|
||||||
targets = append(targets, target.ToV2())
|
|
||||||
}
|
|
||||||
|
|
||||||
v2.SetTargets(targets)
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.filters != nil {
|
|
||||||
filters := make([]*v2acl.HeaderFilter, 0, len(r.filters))
|
|
||||||
for _, filter := range r.filters {
|
|
||||||
filters = append(filters, filter.ToV2())
|
|
||||||
}
|
|
||||||
|
|
||||||
v2.SetFilters(filters)
|
|
||||||
}
|
|
||||||
|
|
||||||
v2.SetAction(r.action.ToV2())
|
|
||||||
v2.SetOperation(r.operation.ToV2())
|
|
||||||
|
|
||||||
return v2
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRecord creates and returns blank Record instance.
|
|
||||||
//
|
|
||||||
// Defaults:
|
|
||||||
// - action: ActionUnknown;
|
|
||||||
// - operation: OperationUnknown;
|
|
||||||
// - targets: nil,
|
|
||||||
// - filters: nil.
|
|
||||||
func NewRecord() *Record {
|
|
||||||
return new(Record)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateRecord creates, initializes with parameters and returns Record instance.
|
|
||||||
func CreateRecord(action Action, operation Operation) *Record {
|
|
||||||
r := NewRecord()
|
|
||||||
r.action = action
|
|
||||||
r.operation = operation
|
|
||||||
r.targets = []*Target{}
|
|
||||||
r.filters = []*Filter{}
|
|
||||||
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRecordFromV2 converts v2 acl.EACLRecord message to Record.
|
|
||||||
func NewRecordFromV2(record *v2acl.Record) *Record {
|
|
||||||
r := NewRecord()
|
|
||||||
|
|
||||||
if record == nil {
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
r.action = ActionFromV2(record.GetAction())
|
|
||||||
r.operation = OperationFromV2(record.GetOperation())
|
|
||||||
|
|
||||||
v2targets := record.GetTargets()
|
|
||||||
v2filters := record.GetFilters()
|
|
||||||
|
|
||||||
r.targets = make([]*Target, 0, len(v2targets))
|
|
||||||
for i := range v2targets {
|
|
||||||
r.targets = append(r.targets, NewTargetFromV2(v2targets[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
r.filters = make([]*Filter, 0, len(v2filters))
|
|
||||||
for i := range v2filters {
|
|
||||||
r.filters = append(r.filters, NewFilterFromV2(v2filters[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal marshals Record into a protobuf binary form.
|
|
||||||
//
|
|
||||||
// Buffer is allocated when the argument is empty.
|
|
||||||
// Otherwise, the first buffer is used.
|
|
||||||
func (r *Record) Marshal(b ...[]byte) ([]byte, error) {
|
|
||||||
var buf []byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
buf = b[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.ToV2().
|
|
||||||
StableMarshal(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal unmarshals protobuf binary representation of Record.
|
|
||||||
func (r *Record) Unmarshal(data []byte) error {
|
|
||||||
fV2 := new(v2acl.Record)
|
|
||||||
if err := fV2.Unmarshal(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*r = *NewRecordFromV2(fV2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Record to protobuf JSON format.
|
|
||||||
func (r *Record) MarshalJSON() ([]byte, error) {
|
|
||||||
return r.ToV2().
|
|
||||||
MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Record from protobuf JSON format.
|
|
||||||
func (r *Record) UnmarshalJSON(data []byte) error {
|
|
||||||
tV2 := new(v2acl.Record)
|
|
||||||
if err := tV2.UnmarshalJSON(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*r = *NewRecordFromV2(tV2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,250 +0,0 @@
|
||||||
package eacl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
|
||||||
objecttest "github.com/nspcc-dev/neofs-api-go/pkg/object/test"
|
|
||||||
ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test"
|
|
||||||
refstest "github.com/nspcc-dev/neofs-api-go/pkg/test"
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
"github.com/nspcc-dev/neofs-crypto/test"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestRecord(t *testing.T) {
|
|
||||||
record := NewRecord()
|
|
||||||
record.SetOperation(OperationRange)
|
|
||||||
record.SetAction(ActionAllow)
|
|
||||||
record.AddFilter(HeaderFromRequest, MatchStringEqual, "A", "B")
|
|
||||||
record.AddFilter(HeaderFromRequest, MatchStringNotEqual, "C", "D")
|
|
||||||
|
|
||||||
target := NewTarget()
|
|
||||||
target.SetRole(RoleSystem)
|
|
||||||
AddRecordTarget(record, target)
|
|
||||||
|
|
||||||
v2 := record.ToV2()
|
|
||||||
require.NotNil(t, v2)
|
|
||||||
require.Equal(t, v2acl.OperationRange, v2.GetOperation())
|
|
||||||
require.Equal(t, v2acl.ActionAllow, v2.GetAction())
|
|
||||||
require.Len(t, v2.GetFilters(), len(record.Filters()))
|
|
||||||
require.Len(t, v2.GetTargets(), len(record.Targets()))
|
|
||||||
|
|
||||||
newRecord := NewRecordFromV2(v2)
|
|
||||||
require.Equal(t, record, newRecord)
|
|
||||||
|
|
||||||
t.Run("create record", func(t *testing.T) {
|
|
||||||
record := CreateRecord(ActionAllow, OperationGet)
|
|
||||||
require.Equal(t, ActionAllow, record.Action())
|
|
||||||
require.Equal(t, OperationGet, record.Operation())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("new from nil v2 record", func(t *testing.T) {
|
|
||||||
require.Equal(t, new(Record), NewRecordFromV2(nil))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAddFormedTarget(t *testing.T) {
|
|
||||||
items := []struct {
|
|
||||||
role Role
|
|
||||||
keys []ecdsa.PublicKey
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
role: RoleUnknown,
|
|
||||||
keys: []ecdsa.PublicKey{test.DecodeKey(1).PublicKey},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: RoleSystem,
|
|
||||||
keys: []ecdsa.PublicKey{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
targets := make([]*Target, 0, len(items))
|
|
||||||
|
|
||||||
r := NewRecord()
|
|
||||||
|
|
||||||
for _, item := range items {
|
|
||||||
tgt := NewTarget()
|
|
||||||
tgt.SetRole(item.role)
|
|
||||||
SetTargetECDSAKeys(tgt, ecdsaKeysToPtrs(item.keys)...)
|
|
||||||
|
|
||||||
targets = append(targets, tgt)
|
|
||||||
|
|
||||||
AddFormedTarget(r, item.role, item.keys...)
|
|
||||||
}
|
|
||||||
|
|
||||||
tgts := r.Targets()
|
|
||||||
require.Len(t, tgts, len(targets))
|
|
||||||
|
|
||||||
for _, tgt := range targets {
|
|
||||||
require.Contains(t, tgts, tgt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRecord_AddFilter(t *testing.T) {
|
|
||||||
filters := []*Filter{
|
|
||||||
newObjectFilter(MatchStringEqual, "some name", "ContainerID"),
|
|
||||||
newObjectFilter(MatchStringNotEqual, "X-Header-Name", "X-Header-Value"),
|
|
||||||
}
|
|
||||||
|
|
||||||
r := NewRecord()
|
|
||||||
for _, filter := range filters {
|
|
||||||
r.AddFilter(filter.From(), filter.Matcher(), filter.Key(), filter.Value())
|
|
||||||
}
|
|
||||||
|
|
||||||
require.Equal(t, filters, r.Filters())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRecordEncoding(t *testing.T) {
|
|
||||||
r := NewRecord()
|
|
||||||
r.SetOperation(OperationHead)
|
|
||||||
r.SetAction(ActionDeny)
|
|
||||||
r.AddObjectAttributeFilter(MatchStringEqual, "key", "value")
|
|
||||||
AddFormedTarget(r, RoleSystem, test.DecodeKey(-1).PublicKey)
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data, err := r.Marshal()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
r2 := NewRecord()
|
|
||||||
require.NoError(t, r2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, r, r2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
|
||||||
data, err := r.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
r2 := NewRecord()
|
|
||||||
require.NoError(t, r2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, r, r2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRecord_ToV2(t *testing.T) {
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
|
||||||
var x *Record
|
|
||||||
|
|
||||||
require.Nil(t, x.ToV2())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("default values", func(t *testing.T) {
|
|
||||||
record := NewRecord()
|
|
||||||
|
|
||||||
// check initial values
|
|
||||||
require.Equal(t, OperationUnknown, record.Operation())
|
|
||||||
require.Equal(t, ActionUnknown, record.Action())
|
|
||||||
require.Nil(t, record.Targets())
|
|
||||||
require.Nil(t, record.Filters())
|
|
||||||
|
|
||||||
// convert to v2 message
|
|
||||||
recordV2 := record.ToV2()
|
|
||||||
|
|
||||||
require.Equal(t, v2acl.OperationUnknown, recordV2.GetOperation())
|
|
||||||
require.Equal(t, v2acl.ActionUnknown, recordV2.GetAction())
|
|
||||||
require.Nil(t, recordV2.GetTargets())
|
|
||||||
require.Nil(t, recordV2.GetFilters())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReservedRecords(t *testing.T) {
|
|
||||||
var (
|
|
||||||
v = refstest.Version()
|
|
||||||
oid = objecttest.ID()
|
|
||||||
cid = cidtest.Generate()
|
|
||||||
ownerid = ownertest.Generate()
|
|
||||||
h = refstest.Checksum()
|
|
||||||
typ = new(object.Type)
|
|
||||||
)
|
|
||||||
|
|
||||||
testSuit := []struct {
|
|
||||||
f func(r *Record)
|
|
||||||
key string
|
|
||||||
value string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectAttributeFilter(MatchStringEqual, "foo", "bar") },
|
|
||||||
key: "foo",
|
|
||||||
value: "bar",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectVersionFilter(MatchStringEqual, v) },
|
|
||||||
key: v2acl.FilterObjectVersion,
|
|
||||||
value: v.String(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectIDFilter(MatchStringEqual, oid) },
|
|
||||||
key: v2acl.FilterObjectID,
|
|
||||||
value: oid.String(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectContainerIDFilter(MatchStringEqual, cid) },
|
|
||||||
key: v2acl.FilterObjectContainerID,
|
|
||||||
value: cid.String(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectOwnerIDFilter(MatchStringEqual, ownerid) },
|
|
||||||
key: v2acl.FilterObjectOwnerID,
|
|
||||||
value: ownerid.String(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectCreationEpoch(MatchStringEqual, 100) },
|
|
||||||
key: v2acl.FilterObjectCreationEpoch,
|
|
||||||
value: "100",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectPayloadLengthFilter(MatchStringEqual, 5000) },
|
|
||||||
key: v2acl.FilterObjectPayloadLength,
|
|
||||||
value: "5000",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectPayloadHashFilter(MatchStringEqual, h) },
|
|
||||||
key: v2acl.FilterObjectPayloadHash,
|
|
||||||
value: h.String(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) { r.AddObjectHomomorphicHashFilter(MatchStringEqual, h) },
|
|
||||||
key: v2acl.FilterObjectHomomorphicHash,
|
|
||||||
value: h.String(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) {
|
|
||||||
require.True(t, typ.FromString("REGULAR"))
|
|
||||||
r.AddObjectTypeFilter(MatchStringEqual, *typ)
|
|
||||||
},
|
|
||||||
key: v2acl.FilterObjectType,
|
|
||||||
value: "REGULAR",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) {
|
|
||||||
require.True(t, typ.FromString("TOMBSTONE"))
|
|
||||||
r.AddObjectTypeFilter(MatchStringEqual, *typ)
|
|
||||||
},
|
|
||||||
key: v2acl.FilterObjectType,
|
|
||||||
value: "TOMBSTONE",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: func(r *Record) {
|
|
||||||
require.True(t, typ.FromString("STORAGE_GROUP"))
|
|
||||||
r.AddObjectTypeFilter(MatchStringEqual, *typ)
|
|
||||||
},
|
|
||||||
key: v2acl.FilterObjectType,
|
|
||||||
value: "STORAGE_GROUP",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for n, testCase := range testSuit {
|
|
||||||
desc := fmt.Sprintf("case #%d", n)
|
|
||||||
record := NewRecord()
|
|
||||||
testCase.f(record)
|
|
||||||
require.Len(t, record.Filters(), 1, desc)
|
|
||||||
f := record.Filters()[0]
|
|
||||||
require.Equal(t, f.Key(), testCase.key, desc)
|
|
||||||
require.Equal(t, f.Value(), testCase.value, desc)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,210 +0,0 @@
|
||||||
package eacl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha256"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
|
||||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/session"
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Table is a group of EACL records for single container.
|
|
||||||
//
|
|
||||||
// Table is compatible with v2 acl.EACLTable message.
|
|
||||||
type Table struct {
|
|
||||||
version pkg.Version
|
|
||||||
cid *cid.ID
|
|
||||||
token *session.Token
|
|
||||||
sig *pkg.Signature
|
|
||||||
records []*Record
|
|
||||||
}
|
|
||||||
|
|
||||||
// CID returns identifier of the container that should use given access control rules.
|
|
||||||
func (t Table) CID() *cid.ID {
|
|
||||||
return t.cid
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCID sets identifier of the container that should use given access control rules.
|
|
||||||
func (t *Table) SetCID(cid *cid.ID) {
|
|
||||||
t.cid = cid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version returns version of eACL format.
|
|
||||||
func (t Table) Version() pkg.Version {
|
|
||||||
return t.version
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetVersion sets version of eACL format.
|
|
||||||
func (t *Table) SetVersion(version pkg.Version) {
|
|
||||||
t.version = version
|
|
||||||
}
|
|
||||||
|
|
||||||
// Records returns list of extended ACL rules.
|
|
||||||
func (t Table) Records() []*Record {
|
|
||||||
return t.records
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddRecord adds single eACL rule.
|
|
||||||
func (t *Table) AddRecord(r *Record) {
|
|
||||||
if r != nil {
|
|
||||||
t.records = append(t.records, r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionToken returns token of the session
|
|
||||||
// within which Table was set.
|
|
||||||
func (t Table) SessionToken() *session.Token {
|
|
||||||
return t.token
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSessionToken sets token of the session
|
|
||||||
// within which Table was set.
|
|
||||||
func (t *Table) SetSessionToken(tok *session.Token) {
|
|
||||||
t.token = tok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signature returns Table signature.
|
|
||||||
func (t Table) Signature() *pkg.Signature {
|
|
||||||
return t.sig
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSignature sets Table signature.
|
|
||||||
func (t *Table) SetSignature(sig *pkg.Signature) {
|
|
||||||
t.sig = sig
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Table to v2 acl.EACLTable message.
|
|
||||||
//
|
|
||||||
// Nil Table converts to nil.
|
|
||||||
func (t *Table) ToV2() *v2acl.Table {
|
|
||||||
if t == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
v2 := new(v2acl.Table)
|
|
||||||
|
|
||||||
if t.cid != nil {
|
|
||||||
v2.SetContainerID(t.cid.ToV2())
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.records != nil {
|
|
||||||
records := make([]*v2acl.Record, 0, len(t.records))
|
|
||||||
for _, record := range t.records {
|
|
||||||
records = append(records, record.ToV2())
|
|
||||||
}
|
|
||||||
|
|
||||||
v2.SetRecords(records)
|
|
||||||
}
|
|
||||||
|
|
||||||
v2.SetVersion(t.version.ToV2())
|
|
||||||
|
|
||||||
return v2
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTable creates, initializes and returns blank Table instance.
|
|
||||||
//
|
|
||||||
// Defaults:
|
|
||||||
// - version: pkg.SDKVersion();
|
|
||||||
// - container ID: nil;
|
|
||||||
// - records: nil;
|
|
||||||
// - session token: nil;
|
|
||||||
// - signature: nil.
|
|
||||||
func NewTable() *Table {
|
|
||||||
t := new(Table)
|
|
||||||
t.SetVersion(*pkg.SDKVersion())
|
|
||||||
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateTable creates, initializes with parameters and returns Table instance.
|
|
||||||
func CreateTable(cid cid.ID) *Table {
|
|
||||||
t := NewTable()
|
|
||||||
t.SetCID(&cid)
|
|
||||||
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTableFromV2 converts v2 acl.EACLTable message to Table.
|
|
||||||
func NewTableFromV2(table *v2acl.Table) *Table {
|
|
||||||
t := new(Table)
|
|
||||||
|
|
||||||
if table == nil {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// set version
|
|
||||||
if v := table.GetVersion(); v != nil {
|
|
||||||
version := pkg.Version{}
|
|
||||||
version.SetMajor(v.GetMajor())
|
|
||||||
version.SetMinor(v.GetMinor())
|
|
||||||
|
|
||||||
t.SetVersion(version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set container id
|
|
||||||
if id := table.GetContainerID(); id != nil {
|
|
||||||
if t.cid == nil {
|
|
||||||
t.cid = new(cid.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
var h [sha256.Size]byte
|
|
||||||
|
|
||||||
copy(h[:], id.GetValue())
|
|
||||||
t.cid.SetSHA256(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set eacl records
|
|
||||||
v2records := table.GetRecords()
|
|
||||||
t.records = make([]*Record, 0, len(v2records))
|
|
||||||
|
|
||||||
for i := range v2records {
|
|
||||||
t.records = append(t.records, NewRecordFromV2(v2records[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal marshals Table into a protobuf binary form.
|
|
||||||
//
|
|
||||||
// Buffer is allocated when the argument is empty.
|
|
||||||
// Otherwise, the first buffer is used.
|
|
||||||
func (t *Table) Marshal(b ...[]byte) ([]byte, error) {
|
|
||||||
var buf []byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
buf = b[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.ToV2().
|
|
||||||
StableMarshal(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal unmarshals protobuf binary representation of Table.
|
|
||||||
func (t *Table) Unmarshal(data []byte) error {
|
|
||||||
fV2 := new(v2acl.Table)
|
|
||||||
if err := fV2.Unmarshal(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*t = *NewTableFromV2(fV2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Table to protobuf JSON format.
|
|
||||||
func (t *Table) MarshalJSON() ([]byte, error) {
|
|
||||||
return t.ToV2().
|
|
||||||
MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Table from protobuf JSON format.
|
|
||||||
func (t *Table) UnmarshalJSON(data []byte) error {
|
|
||||||
tV2 := new(v2acl.Table)
|
|
||||||
if err := tV2.UnmarshalJSON(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*t = *NewTableFromV2(tV2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,138 +0,0 @@
|
||||||
package eacl_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha256"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
|
||||||
eacltest "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl/test"
|
|
||||||
cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test"
|
|
||||||
sessiontest "github.com/nspcc-dev/neofs-api-go/pkg/session/test"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTable(t *testing.T) {
|
|
||||||
var (
|
|
||||||
v pkg.Version
|
|
||||||
)
|
|
||||||
|
|
||||||
sha := sha256.Sum256([]byte("container id"))
|
|
||||||
id := cidtest.GenerateWithChecksum(sha)
|
|
||||||
|
|
||||||
v.SetMajor(3)
|
|
||||||
v.SetMinor(2)
|
|
||||||
|
|
||||||
table := eacl.NewTable()
|
|
||||||
table.SetVersion(v)
|
|
||||||
table.SetCID(id)
|
|
||||||
table.AddRecord(eacl.CreateRecord(eacl.ActionAllow, eacl.OperationPut))
|
|
||||||
|
|
||||||
v2 := table.ToV2()
|
|
||||||
require.NotNil(t, v2)
|
|
||||||
require.Equal(t, uint32(3), v2.GetVersion().GetMajor())
|
|
||||||
require.Equal(t, uint32(2), v2.GetVersion().GetMinor())
|
|
||||||
require.Equal(t, sha[:], v2.GetContainerID().GetValue())
|
|
||||||
require.Len(t, v2.GetRecords(), 1)
|
|
||||||
|
|
||||||
newTable := eacl.NewTableFromV2(v2)
|
|
||||||
require.Equal(t, table, newTable)
|
|
||||||
|
|
||||||
t.Run("new from nil v2 table", func(t *testing.T) {
|
|
||||||
require.Equal(t, new(eacl.Table), eacl.NewTableFromV2(nil))
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("create table", func(t *testing.T) {
|
|
||||||
id := cidtest.Generate()
|
|
||||||
|
|
||||||
table := eacl.CreateTable(*id)
|
|
||||||
require.Equal(t, id, table.CID())
|
|
||||||
require.Equal(t, *pkg.SDKVersion(), table.Version())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTable_AddRecord(t *testing.T) {
|
|
||||||
records := []*eacl.Record{
|
|
||||||
eacl.CreateRecord(eacl.ActionDeny, eacl.OperationDelete),
|
|
||||||
eacl.CreateRecord(eacl.ActionAllow, eacl.OperationPut),
|
|
||||||
}
|
|
||||||
|
|
||||||
table := eacl.NewTable()
|
|
||||||
for _, record := range records {
|
|
||||||
table.AddRecord(record)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.Equal(t, records, table.Records())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTableEncoding(t *testing.T) {
|
|
||||||
tab := eacltest.Table()
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data, err := tab.Marshal()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
tab2 := eacl.NewTable()
|
|
||||||
require.NoError(t, tab2.Unmarshal(data))
|
|
||||||
|
|
||||||
// FIXME: we compare v2 messages because
|
|
||||||
// Filter contains fmt.Stringer interface
|
|
||||||
require.Equal(t, tab.ToV2(), tab2.ToV2())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
|
||||||
data, err := tab.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
tab2 := eacl.NewTable()
|
|
||||||
require.NoError(t, tab2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, tab.ToV2(), tab2.ToV2())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTable_SessionToken(t *testing.T) {
|
|
||||||
tok := sessiontest.Generate()
|
|
||||||
|
|
||||||
table := eacl.NewTable()
|
|
||||||
table.SetSessionToken(tok)
|
|
||||||
|
|
||||||
require.Equal(t, tok, table.SessionToken())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTable_Signature(t *testing.T) {
|
|
||||||
sig := pkg.NewSignature()
|
|
||||||
sig.SetKey([]byte{1, 2, 3})
|
|
||||||
sig.SetSign([]byte{4, 5, 6})
|
|
||||||
|
|
||||||
table := eacl.NewTable()
|
|
||||||
table.SetSignature(sig)
|
|
||||||
|
|
||||||
require.Equal(t, sig, table.Signature())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTable_ToV2(t *testing.T) {
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
|
||||||
var x *eacl.Table
|
|
||||||
|
|
||||||
require.Nil(t, x.ToV2())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("default values", func(t *testing.T) {
|
|
||||||
table := eacl.NewTable()
|
|
||||||
|
|
||||||
// check initial values
|
|
||||||
require.Equal(t, *pkg.SDKVersion(), table.Version())
|
|
||||||
require.Nil(t, table.Records())
|
|
||||||
require.Nil(t, table.CID())
|
|
||||||
require.Nil(t, table.SessionToken())
|
|
||||||
require.Nil(t, table.Signature())
|
|
||||||
|
|
||||||
// convert to v2 message
|
|
||||||
tableV2 := table.ToV2()
|
|
||||||
|
|
||||||
require.Equal(t, pkg.SDKVersion().ToV2(), tableV2.GetVersion())
|
|
||||||
require.Nil(t, tableV2.GetRecords())
|
|
||||||
require.Nil(t, tableV2.GetContainerID())
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,191 +0,0 @@
|
||||||
package eacl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Target is a group of request senders to match EACL. Defined by role enum
|
|
||||||
// and set of public keys.
|
|
||||||
//
|
|
||||||
// Target is compatible with v2 acl.EACLRecord.Target message.
|
|
||||||
type Target struct {
|
|
||||||
role Role
|
|
||||||
keys [][]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func ecdsaKeysToPtrs(keys []ecdsa.PublicKey) []*ecdsa.PublicKey {
|
|
||||||
keysPtr := make([]*ecdsa.PublicKey, len(keys))
|
|
||||||
|
|
||||||
for i := range keys {
|
|
||||||
keysPtr[i] = &keys[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
return keysPtr
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetKeys sets list of ECDSA public keys to identify target subject.
|
|
||||||
//
|
|
||||||
// Deprecated: use SetTargetECDSAKeys instead.
|
|
||||||
func (t *Target) SetKeys(keys ...ecdsa.PublicKey) {
|
|
||||||
SetTargetECDSAKeys(t, ecdsaKeysToPtrs(keys)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys returns list of ECDSA public keys to identify target subject.
|
|
||||||
// If some key has a different format, it is ignored.
|
|
||||||
//
|
|
||||||
// Deprecated: use TargetECDSAKeys instead.
|
|
||||||
func (t *Target) Keys() []ecdsa.PublicKey {
|
|
||||||
keysPtr := TargetECDSAKeys(t)
|
|
||||||
keys := make([]ecdsa.PublicKey, 0, len(keysPtr))
|
|
||||||
|
|
||||||
for i := range keysPtr {
|
|
||||||
if keysPtr[i] != nil {
|
|
||||||
keys = append(keys, *keysPtr[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// BinaryKeys returns list of public keys to identify
|
|
||||||
// target subject in a binary format.
|
|
||||||
func (t *Target) BinaryKeys() [][]byte {
|
|
||||||
return t.keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBinaryKeys sets list of binary public keys to identify
|
|
||||||
// target subject.
|
|
||||||
func (t *Target) SetBinaryKeys(keys [][]byte) {
|
|
||||||
t.keys = keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTargetECDSAKeys converts ECDSA public keys to a binary
|
|
||||||
// format and stores them in Target.
|
|
||||||
func SetTargetECDSAKeys(t *Target, keys ...*ecdsa.PublicKey) {
|
|
||||||
binKeys := t.BinaryKeys()
|
|
||||||
ln := len(keys)
|
|
||||||
|
|
||||||
if cap(binKeys) >= ln {
|
|
||||||
binKeys = binKeys[:0]
|
|
||||||
} else {
|
|
||||||
binKeys = make([][]byte, 0, ln)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < ln; i++ {
|
|
||||||
binKeys = append(binKeys, crypto.MarshalPublicKey(keys[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
t.SetBinaryKeys(binKeys)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TargetECDSAKeys interprets binary public keys of Target
|
|
||||||
// as ECDSA public keys. If any key has a different format,
|
|
||||||
// the corresponding element will be nil.
|
|
||||||
func TargetECDSAKeys(t *Target) []*ecdsa.PublicKey {
|
|
||||||
binKeys := t.BinaryKeys()
|
|
||||||
ln := len(binKeys)
|
|
||||||
|
|
||||||
keys := make([]*ecdsa.PublicKey, ln)
|
|
||||||
|
|
||||||
for i := 0; i < ln; i++ {
|
|
||||||
keys[i] = crypto.UnmarshalPublicKey(binKeys[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRole sets target subject's role class.
|
|
||||||
func (t *Target) SetRole(r Role) {
|
|
||||||
t.role = r
|
|
||||||
}
|
|
||||||
|
|
||||||
// Role returns target subject's role class.
|
|
||||||
func (t Target) Role() Role {
|
|
||||||
return t.role
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Target to v2 acl.EACLRecord.Target message.
|
|
||||||
//
|
|
||||||
// Nil Target converts to nil.
|
|
||||||
func (t *Target) ToV2() *v2acl.Target {
|
|
||||||
if t == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
target := new(v2acl.Target)
|
|
||||||
|
|
||||||
target.SetRole(t.role.ToV2())
|
|
||||||
target.SetKeys(t.keys)
|
|
||||||
|
|
||||||
return target
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTarget creates, initializes and returns blank Target instance.
|
|
||||||
//
|
|
||||||
// Defaults:
|
|
||||||
// - role: RoleUnknown;
|
|
||||||
// - keys: nil.
|
|
||||||
func NewTarget() *Target {
|
|
||||||
return NewTargetFromV2(new(v2acl.Target))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTargetFromV2 converts v2 acl.EACLRecord.Target message to Target.
|
|
||||||
func NewTargetFromV2(target *v2acl.Target) *Target {
|
|
||||||
t := new(Target)
|
|
||||||
|
|
||||||
if target == nil {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
t.role = RoleFromV2(target.GetRole())
|
|
||||||
t.keys = target.GetKeys()
|
|
||||||
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal marshals Target into a protobuf binary form.
|
|
||||||
//
|
|
||||||
// Buffer is allocated when the argument is empty.
|
|
||||||
// Otherwise, the first buffer is used.
|
|
||||||
func (t *Target) Marshal(b ...[]byte) ([]byte, error) {
|
|
||||||
var buf []byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
buf = b[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.ToV2().
|
|
||||||
StableMarshal(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal unmarshals protobuf binary representation of Target.
|
|
||||||
func (t *Target) Unmarshal(data []byte) error {
|
|
||||||
fV2 := new(v2acl.Target)
|
|
||||||
if err := fV2.Unmarshal(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*t = *NewTargetFromV2(fV2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Target to protobuf JSON format.
|
|
||||||
func (t *Target) MarshalJSON() ([]byte, error) {
|
|
||||||
return t.ToV2().
|
|
||||||
MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Target from protobuf JSON format.
|
|
||||||
func (t *Target) UnmarshalJSON(data []byte) error {
|
|
||||||
tV2 := new(v2acl.Target)
|
|
||||||
if err := tV2.UnmarshalJSON(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*t = *NewTargetFromV2(tV2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
package eacl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
|
||||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
|
||||||
"github.com/nspcc-dev/neofs-crypto/test"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTarget(t *testing.T) {
|
|
||||||
keys := []*ecdsa.PublicKey{
|
|
||||||
&test.DecodeKey(1).PublicKey,
|
|
||||||
&test.DecodeKey(2).PublicKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
target := NewTarget()
|
|
||||||
target.SetRole(RoleSystem)
|
|
||||||
SetTargetECDSAKeys(target, keys...)
|
|
||||||
|
|
||||||
v2 := target.ToV2()
|
|
||||||
require.NotNil(t, v2)
|
|
||||||
require.Equal(t, v2acl.RoleSystem, v2.GetRole())
|
|
||||||
require.Len(t, v2.GetKeys(), len(keys))
|
|
||||||
for i, key := range v2.GetKeys() {
|
|
||||||
require.Equal(t, key, crypto.MarshalPublicKey(keys[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
newTarget := NewTargetFromV2(v2)
|
|
||||||
require.Equal(t, target, newTarget)
|
|
||||||
|
|
||||||
t.Run("from nil v2 target", func(t *testing.T) {
|
|
||||||
require.Equal(t, new(Target), NewTargetFromV2(nil))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTargetEncoding(t *testing.T) {
|
|
||||||
tar := NewTarget()
|
|
||||||
tar.SetRole(RoleSystem)
|
|
||||||
SetTargetECDSAKeys(tar, &test.DecodeKey(-1).PublicKey)
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data, err := tar.Marshal()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
tar2 := NewTarget()
|
|
||||||
require.NoError(t, tar2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, tar, tar2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
|
||||||
data, err := tar.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
tar2 := NewTarget()
|
|
||||||
require.NoError(t, tar2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, tar, tar2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTarget_ToV2(t *testing.T) {
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
|
||||||
var x *Target
|
|
||||||
|
|
||||||
require.Nil(t, x.ToV2())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("default values", func(t *testing.T) {
|
|
||||||
target := NewTarget()
|
|
||||||
|
|
||||||
// check initial values
|
|
||||||
require.Equal(t, RoleUnknown, target.Role())
|
|
||||||
require.Nil(t, target.BinaryKeys())
|
|
||||||
|
|
||||||
// convert to v2 message
|
|
||||||
targetV2 := target.ToV2()
|
|
||||||
|
|
||||||
require.Equal(t, acl.RoleUnknown, targetV2.GetRole())
|
|
||||||
require.Nil(t, targetV2.GetKeys())
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
package eacltest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
|
||||||
cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test"
|
|
||||||
ownertest "github.com/nspcc-dev/neofs-api-go/pkg/owner/test"
|
|
||||||
refstest "github.com/nspcc-dev/neofs-api-go/pkg/test"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Target returns random eacl.Target.
|
|
||||||
func Target() *eacl.Target {
|
|
||||||
x := eacl.NewTarget()
|
|
||||||
|
|
||||||
x.SetRole(eacl.RoleSystem)
|
|
||||||
x.SetBinaryKeys([][]byte{
|
|
||||||
{1, 2, 3},
|
|
||||||
{4, 5, 6},
|
|
||||||
})
|
|
||||||
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record returns random eacl.Record.
|
|
||||||
func Record() *eacl.Record {
|
|
||||||
x := eacl.NewRecord()
|
|
||||||
|
|
||||||
x.SetAction(eacl.ActionAllow)
|
|
||||||
x.SetOperation(eacl.OperationRangeHash)
|
|
||||||
x.SetTargets(Target(), Target())
|
|
||||||
x.AddObjectContainerIDFilter(eacl.MatchStringEqual, cidtest.Generate())
|
|
||||||
x.AddObjectOwnerIDFilter(eacl.MatchStringNotEqual, ownertest.Generate())
|
|
||||||
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
func Table() *eacl.Table {
|
|
||||||
x := eacl.NewTable()
|
|
||||||
|
|
||||||
x.SetCID(cidtest.Generate())
|
|
||||||
x.AddRecord(Record())
|
|
||||||
x.AddRecord(Record())
|
|
||||||
x.SetVersion(*refstest.Version())
|
|
||||||
|
|
||||||
return x
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package acl
|
|
||||||
|
|
||||||
const (
|
|
||||||
// PublicBasicRule is a basic ACL value for public-read-write container.
|
|
||||||
PublicBasicRule = 0x1FBFBFFF
|
|
||||||
|
|
||||||
// PrivateBasicRule is a basic ACL value for private container.
|
|
||||||
PrivateBasicRule = 0x1C8C8CCC
|
|
||||||
|
|
||||||
// ReadOnlyBasicRule is a basic ACL value for public-read container.
|
|
||||||
ReadOnlyBasicRule = 0x1FBF8CFF
|
|
||||||
|
|
||||||
// PublicAppendRule is a basic ACL value for public-append container.
|
|
||||||
PublicAppendRule = 0x1FBF9FFF
|
|
||||||
)
|
|
|
@ -1,330 +0,0 @@
|
||||||
package audit
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
|
||||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/audit"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Result represents v2-compatible data audit result.
|
|
||||||
type Result audit.DataAuditResult
|
|
||||||
|
|
||||||
// NewFromV2 wraps v2 DataAuditResult message to Result.
|
|
||||||
//
|
|
||||||
// Nil audit.DataAuditResult converts to nil.
|
|
||||||
func NewResultFromV2(aV2 *audit.DataAuditResult) *Result {
|
|
||||||
return (*Result)(aV2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates and initializes blank Result.
|
|
||||||
//
|
|
||||||
// Defaults:
|
|
||||||
// - version: pkg.SDKVersion();
|
|
||||||
// - complete: false;
|
|
||||||
// - cid: nil;
|
|
||||||
// - pubKey: nil;
|
|
||||||
// - passSG, failSG: nil;
|
|
||||||
// - failNodes, passNodes: nil;
|
|
||||||
// - hit, miss, fail: 0;
|
|
||||||
// - requests, retries: 0;
|
|
||||||
// - auditEpoch: 0.
|
|
||||||
func NewResult() *Result {
|
|
||||||
r := NewResultFromV2(new(audit.DataAuditResult))
|
|
||||||
r.SetVersion(pkg.SDKVersion())
|
|
||||||
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Result to v2 DataAuditResult message.
|
|
||||||
//
|
|
||||||
// Nil Result converts to nil.
|
|
||||||
func (r *Result) ToV2() *audit.DataAuditResult {
|
|
||||||
return (*audit.DataAuditResult)(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal marshals Result into a protobuf binary form.
|
|
||||||
//
|
|
||||||
// Buffer is allocated when the argument is empty.
|
|
||||||
// Otherwise, the first buffer is used.
|
|
||||||
func (r *Result) Marshal(b ...[]byte) ([]byte, error) {
|
|
||||||
var buf []byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
buf = b[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
StableMarshal(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal unmarshals protobuf binary representation of Result.
|
|
||||||
func (r *Result) Unmarshal(data []byte) error {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
Unmarshal(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Result to protobuf JSON format.
|
|
||||||
func (r *Result) MarshalJSON() ([]byte, error) {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Result from protobuf JSON format.
|
|
||||||
func (r *Result) UnmarshalJSON(data []byte) error {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
UnmarshalJSON(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version returns Data Audit structure version.
|
|
||||||
func (r *Result) Version() *pkg.Version {
|
|
||||||
return pkg.NewVersionFromV2(
|
|
||||||
(*audit.DataAuditResult)(r).GetVersion(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetVersion sets Data Audit structure version.
|
|
||||||
func (r *Result) SetVersion(v *pkg.Version) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetVersion(v.ToV2())
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuditEpoch returns epoch number when the Data Audit was conducted.
|
|
||||||
func (r *Result) AuditEpoch() uint64 {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetAuditEpoch()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAuditEpoch sets epoch number when the Data Audit was conducted.
|
|
||||||
func (r *Result) SetAuditEpoch(epoch uint64) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetAuditEpoch(epoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContainerID returns container under audit.
|
|
||||||
func (r *Result) ContainerID() *cid.ID {
|
|
||||||
return cid.NewFromV2(
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
GetContainerID(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetContainerID sets container under audit.
|
|
||||||
func (r *Result) SetContainerID(id *cid.ID) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetContainerID(id.ToV2())
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublicKey returns public key of the auditing InnerRing node in a binary format.
|
|
||||||
func (r *Result) PublicKey() []byte {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetPublicKey()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPublicKey sets public key of the auditing InnerRing node in a binary format.
|
|
||||||
func (r *Result) SetPublicKey(key []byte) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetPublicKey(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete returns completion state of audit result.
|
|
||||||
func (r *Result) Complete() bool {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetComplete()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetComplete sets completion state of audit result.
|
|
||||||
func (r *Result) SetComplete(v bool) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetComplete(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Requests returns number of requests made by PoR audit check to get
|
|
||||||
// all headers of the objects inside storage groups.
|
|
||||||
func (r *Result) Requests() uint32 {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetRequests()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRequests sets number of requests made by PoR audit check to get
|
|
||||||
// all headers of the objects inside storage groups.
|
|
||||||
func (r *Result) SetRequests(v uint32) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetRequests(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retries returns number of retries made by PoR audit check to get
|
|
||||||
// all headers of the objects inside storage groups.
|
|
||||||
func (r *Result) Retries() uint32 {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetRetries()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRetries sets number of retries made by PoR audit check to get
|
|
||||||
// all headers of the objects inside storage groups.
|
|
||||||
func (r *Result) SetRetries(v uint32) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetRetries(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PassSG returns list of Storage Groups that passed audit PoR stage.
|
|
||||||
func (r *Result) PassSG() []*object.ID {
|
|
||||||
mV2 := (*audit.DataAuditResult)(r).
|
|
||||||
GetPassSG()
|
|
||||||
|
|
||||||
if mV2 == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
m := make([]*object.ID, len(mV2))
|
|
||||||
|
|
||||||
for i := range mV2 {
|
|
||||||
m[i] = object.NewIDFromV2(mV2[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPassSG sets list of Storage Groups that passed audit PoR stage.
|
|
||||||
func (r *Result) SetPassSG(list []*object.ID) {
|
|
||||||
mV2 := (*audit.DataAuditResult)(r).
|
|
||||||
GetPassSG()
|
|
||||||
|
|
||||||
if list == nil {
|
|
||||||
mV2 = nil
|
|
||||||
} else {
|
|
||||||
ln := len(list)
|
|
||||||
|
|
||||||
if cap(mV2) >= ln {
|
|
||||||
mV2 = mV2[:0]
|
|
||||||
} else {
|
|
||||||
mV2 = make([]*refs.ObjectID, 0, ln)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < ln; i++ {
|
|
||||||
mV2 = append(mV2, list[i].ToV2())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetPassSG(mV2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FailSG returns list of Storage Groups that failed audit PoR stage.
|
|
||||||
func (r *Result) FailSG() []*object.ID {
|
|
||||||
mV2 := (*audit.DataAuditResult)(r).
|
|
||||||
GetFailSG()
|
|
||||||
|
|
||||||
if mV2 == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
m := make([]*object.ID, len(mV2))
|
|
||||||
|
|
||||||
for i := range mV2 {
|
|
||||||
m[i] = object.NewIDFromV2(mV2[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFailSG sets list of Storage Groups that failed audit PoR stage.
|
|
||||||
func (r *Result) SetFailSG(list []*object.ID) {
|
|
||||||
mV2 := (*audit.DataAuditResult)(r).
|
|
||||||
GetFailSG()
|
|
||||||
|
|
||||||
if list == nil {
|
|
||||||
mV2 = nil
|
|
||||||
} else {
|
|
||||||
ln := len(list)
|
|
||||||
|
|
||||||
if cap(mV2) >= ln {
|
|
||||||
mV2 = mV2[:0]
|
|
||||||
} else {
|
|
||||||
mV2 = make([]*refs.ObjectID, 0, ln)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < ln; i++ {
|
|
||||||
mV2 = append(mV2, list[i].ToV2())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetFailSG(mV2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hit returns number of sampled objects under audit placed
|
|
||||||
// in an optimal way according to the containers placement policy
|
|
||||||
// when checking PoP.
|
|
||||||
func (r *Result) Hit() uint32 {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetHit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHit sets number of sampled objects under audit placed
|
|
||||||
// in an optimal way according to the containers placement policy
|
|
||||||
// when checking PoP.
|
|
||||||
func (r *Result) SetHit(hit uint32) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetHit(hit)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Miss returns number of sampled objects under audit placed
|
|
||||||
// in suboptimal way according to the containers placement policy,
|
|
||||||
// but still at a satisfactory level when checking PoP.
|
|
||||||
func (r *Result) Miss() uint32 {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetMiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMiss sets number of sampled objects under audit placed
|
|
||||||
// in suboptimal way according to the containers placement policy,
|
|
||||||
// but still at a satisfactory level when checking PoP.
|
|
||||||
func (r *Result) SetMiss(miss uint32) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetMiss(miss)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fail returns number of sampled objects under audit stored
|
|
||||||
// in a way not confirming placement policy or not found at all
|
|
||||||
// when checking PoP.
|
|
||||||
func (r *Result) Fail() uint32 {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetFail()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFail sets number of sampled objects under audit stored
|
|
||||||
// in a way not confirming placement policy or not found at all
|
|
||||||
// when checking PoP.
|
|
||||||
func (r *Result) SetFail(fail uint32) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetFail(fail)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PassNodes returns list of storage node public keys that
|
|
||||||
// passed at least one PDP.
|
|
||||||
func (r *Result) PassNodes() [][]byte {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetPassNodes()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPassNodes sets list of storage node public keys that
|
|
||||||
// passed at least one PDP.
|
|
||||||
func (r *Result) SetPassNodes(list [][]byte) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetPassNodes(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FailNodes returns list of storage node public keys that
|
|
||||||
// failed at least one PDP.
|
|
||||||
func (r *Result) FailNodes() [][]byte {
|
|
||||||
return (*audit.DataAuditResult)(r).
|
|
||||||
GetFailNodes()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFailNodes sets list of storage node public keys that
|
|
||||||
// failed at least one PDP.
|
|
||||||
func (r *Result) SetFailNodes(list [][]byte) {
|
|
||||||
(*audit.DataAuditResult)(r).
|
|
||||||
SetFailNodes(list)
|
|
||||||
}
|
|
|
@ -1,154 +0,0 @@
|
||||||
package audit_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/audit"
|
|
||||||
audittest "github.com/nspcc-dev/neofs-api-go/pkg/audit/test"
|
|
||||||
cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
|
||||||
objecttest "github.com/nspcc-dev/neofs-api-go/pkg/object/test"
|
|
||||||
auditv2 "github.com/nspcc-dev/neofs-api-go/v2/audit"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestResult(t *testing.T) {
|
|
||||||
r := audit.NewResult()
|
|
||||||
require.Equal(t, pkg.SDKVersion(), r.Version())
|
|
||||||
|
|
||||||
epoch := uint64(13)
|
|
||||||
r.SetAuditEpoch(epoch)
|
|
||||||
require.Equal(t, epoch, r.AuditEpoch())
|
|
||||||
|
|
||||||
cid := cidtest.Generate()
|
|
||||||
r.SetContainerID(cid)
|
|
||||||
require.Equal(t, cid, r.ContainerID())
|
|
||||||
|
|
||||||
key := []byte{1, 2, 3}
|
|
||||||
r.SetPublicKey(key)
|
|
||||||
require.Equal(t, key, r.PublicKey())
|
|
||||||
|
|
||||||
r.SetComplete(true)
|
|
||||||
require.True(t, r.Complete())
|
|
||||||
|
|
||||||
requests := uint32(2)
|
|
||||||
r.SetRequests(requests)
|
|
||||||
require.Equal(t, requests, r.Requests())
|
|
||||||
|
|
||||||
retries := uint32(1)
|
|
||||||
r.SetRetries(retries)
|
|
||||||
require.Equal(t, retries, r.Retries())
|
|
||||||
|
|
||||||
passSG := []*object.ID{objecttest.ID(), objecttest.ID()}
|
|
||||||
r.SetPassSG(passSG)
|
|
||||||
require.Equal(t, passSG, r.PassSG())
|
|
||||||
|
|
||||||
failSG := []*object.ID{objecttest.ID(), objecttest.ID()}
|
|
||||||
r.SetFailSG(failSG)
|
|
||||||
require.Equal(t, failSG, r.FailSG())
|
|
||||||
|
|
||||||
hit := uint32(1)
|
|
||||||
r.SetHit(hit)
|
|
||||||
require.Equal(t, hit, r.Hit())
|
|
||||||
|
|
||||||
miss := uint32(2)
|
|
||||||
r.SetMiss(miss)
|
|
||||||
require.Equal(t, miss, r.Miss())
|
|
||||||
|
|
||||||
fail := uint32(3)
|
|
||||||
r.SetFail(fail)
|
|
||||||
require.Equal(t, fail, r.Fail())
|
|
||||||
|
|
||||||
passNodes := [][]byte{{1}, {2}}
|
|
||||||
r.SetPassNodes(passNodes)
|
|
||||||
require.Equal(t, passNodes, r.PassNodes())
|
|
||||||
|
|
||||||
failNodes := [][]byte{{3}, {4}}
|
|
||||||
r.SetFailNodes(failNodes)
|
|
||||||
require.Equal(t, failNodes, r.FailNodes())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStorageGroupEncoding(t *testing.T) {
|
|
||||||
r := audittest.Generate()
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data, err := r.Marshal()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
r2 := audit.NewResult()
|
|
||||||
require.NoError(t, r2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, r, r2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
|
||||||
data, err := r.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
r2 := audit.NewResult()
|
|
||||||
require.NoError(t, r2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, r, r2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResult_ToV2(t *testing.T) {
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
|
||||||
var x *audit.Result
|
|
||||||
|
|
||||||
require.Nil(t, x.ToV2())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("default values", func(t *testing.T) {
|
|
||||||
result := audit.NewResult()
|
|
||||||
|
|
||||||
// check initial values
|
|
||||||
require.Equal(t, pkg.SDKVersion(), result.Version())
|
|
||||||
|
|
||||||
require.False(t, result.Complete())
|
|
||||||
|
|
||||||
require.Nil(t, result.ContainerID())
|
|
||||||
require.Nil(t, result.PublicKey())
|
|
||||||
require.Nil(t, result.PassSG())
|
|
||||||
require.Nil(t, result.FailSG())
|
|
||||||
require.Nil(t, result.PassNodes())
|
|
||||||
require.Nil(t, result.FailNodes())
|
|
||||||
|
|
||||||
require.Zero(t, result.Hit())
|
|
||||||
require.Zero(t, result.Miss())
|
|
||||||
require.Zero(t, result.Fail())
|
|
||||||
require.Zero(t, result.Requests())
|
|
||||||
require.Zero(t, result.Retries())
|
|
||||||
require.Zero(t, result.AuditEpoch())
|
|
||||||
|
|
||||||
// convert to v2 message
|
|
||||||
resultV2 := result.ToV2()
|
|
||||||
|
|
||||||
require.Equal(t, pkg.SDKVersion().ToV2(), resultV2.GetVersion())
|
|
||||||
|
|
||||||
require.False(t, resultV2.GetComplete())
|
|
||||||
|
|
||||||
require.Nil(t, resultV2.GetContainerID())
|
|
||||||
require.Nil(t, resultV2.GetPublicKey())
|
|
||||||
require.Nil(t, resultV2.GetPassSG())
|
|
||||||
require.Nil(t, resultV2.GetFailSG())
|
|
||||||
require.Nil(t, resultV2.GetPassNodes())
|
|
||||||
require.Nil(t, resultV2.GetFailNodes())
|
|
||||||
|
|
||||||
require.Zero(t, resultV2.GetHit())
|
|
||||||
require.Zero(t, resultV2.GetMiss())
|
|
||||||
require.Zero(t, resultV2.GetFail())
|
|
||||||
require.Zero(t, resultV2.GetRequests())
|
|
||||||
require.Zero(t, resultV2.GetRetries())
|
|
||||||
require.Zero(t, resultV2.GetAuditEpoch())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResultFromV2(t *testing.T) {
|
|
||||||
t.Run("from nil", func(t *testing.T) {
|
|
||||||
var x *auditv2.DataAuditResult
|
|
||||||
|
|
||||||
require.Nil(t, audit.NewResultFromV2(x))
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package audittest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/audit"
|
|
||||||
cidtest "github.com/nspcc-dev/neofs-api-go/pkg/container/id/test"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
|
||||||
objecttest "github.com/nspcc-dev/neofs-api-go/pkg/object/test"
|
|
||||||
refstest "github.com/nspcc-dev/neofs-api-go/pkg/test"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Generate returns random audit.Result.
|
|
||||||
func Generate() *audit.Result {
|
|
||||||
x := audit.NewResult()
|
|
||||||
|
|
||||||
x.SetVersion(refstest.Version())
|
|
||||||
x.SetContainerID(cidtest.Generate())
|
|
||||||
x.SetPublicKey([]byte("key"))
|
|
||||||
x.SetComplete(true)
|
|
||||||
x.SetAuditEpoch(44)
|
|
||||||
x.SetHit(55)
|
|
||||||
x.SetMiss(66)
|
|
||||||
x.SetFail(77)
|
|
||||||
x.SetRetries(88)
|
|
||||||
x.SetRequests(99)
|
|
||||||
x.SetFailNodes([][]byte{
|
|
||||||
[]byte("node1"),
|
|
||||||
[]byte("node2"),
|
|
||||||
})
|
|
||||||
x.SetPassNodes([][]byte{
|
|
||||||
[]byte("node3"),
|
|
||||||
[]byte("node4"),
|
|
||||||
})
|
|
||||||
x.SetPassSG([]*object.ID{objecttest.ID(), objecttest.ID()})
|
|
||||||
x.SetFailSG([]*object.ID{objecttest.ID(), objecttest.ID()})
|
|
||||||
|
|
||||||
return x
|
|
||||||
}
|
|
198
pkg/checksum.go
198
pkg/checksum.go
|
@ -1,198 +0,0 @@
|
||||||
package pkg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Checksum represents v2-compatible checksum.
|
|
||||||
type Checksum refs.Checksum
|
|
||||||
|
|
||||||
// ChecksumType represents the enumeration
|
|
||||||
// of checksum types.
|
|
||||||
type ChecksumType uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ChecksumUnknown is an undefined checksum type.
|
|
||||||
ChecksumUnknown ChecksumType = iota
|
|
||||||
|
|
||||||
// ChecksumSHA256 is a SHA256 checksum type.
|
|
||||||
ChecksumSHA256
|
|
||||||
|
|
||||||
// ChecksumTZ is a Tillich-Zemor checksum type.
|
|
||||||
ChecksumTZ
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewChecksumFromV2 wraps v2 Checksum message to Checksum.
|
|
||||||
//
|
|
||||||
// Nil refs.Checksum converts to nil.
|
|
||||||
func NewChecksumFromV2(cV2 *refs.Checksum) *Checksum {
|
|
||||||
return (*Checksum)(cV2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewChecksum creates and initializes blank Checksum.
|
|
||||||
//
|
|
||||||
// Works similar as NewChecksumFromV2(new(Checksum)).
|
|
||||||
//
|
|
||||||
// Defaults:
|
|
||||||
// - sum: nil;
|
|
||||||
// - type: ChecksumUnknown.
|
|
||||||
func NewChecksum() *Checksum {
|
|
||||||
return NewChecksumFromV2(new(refs.Checksum))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type returns checksum type.
|
|
||||||
func (c *Checksum) Type() ChecksumType {
|
|
||||||
switch (*refs.Checksum)(c).GetType() {
|
|
||||||
case refs.SHA256:
|
|
||||||
return ChecksumSHA256
|
|
||||||
case refs.TillichZemor:
|
|
||||||
return ChecksumTZ
|
|
||||||
default:
|
|
||||||
return ChecksumUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sum returns checksum bytes.
|
|
||||||
func (c *Checksum) Sum() []byte {
|
|
||||||
return (*refs.Checksum)(c).GetSum()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSHA256 sets checksum to SHA256 hash.
|
|
||||||
func (c *Checksum) SetSHA256(v [sha256.Size]byte) {
|
|
||||||
checksum := (*refs.Checksum)(c)
|
|
||||||
|
|
||||||
checksum.SetType(refs.SHA256)
|
|
||||||
checksum.SetSum(v[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTillichZemor sets checksum to Tillich-Zemor hash.
|
|
||||||
func (c *Checksum) SetTillichZemor(v [64]byte) {
|
|
||||||
checksum := (*refs.Checksum)(c)
|
|
||||||
|
|
||||||
checksum.SetType(refs.TillichZemor)
|
|
||||||
checksum.SetSum(v[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Checksum to v2 Checksum message.
|
|
||||||
//
|
|
||||||
// Nil Checksum converts to nil.
|
|
||||||
func (c *Checksum) ToV2() *refs.Checksum {
|
|
||||||
return (*refs.Checksum)(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func EqualChecksums(cs1, cs2 *Checksum) bool {
|
|
||||||
return cs1.Type() == cs2.Type() && bytes.Equal(cs1.Sum(), cs2.Sum())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal marshals Checksum into a protobuf binary form.
|
|
||||||
//
|
|
||||||
// Buffer is allocated when the argument is empty.
|
|
||||||
// Otherwise, the first buffer is used.
|
|
||||||
func (c *Checksum) Marshal(b ...[]byte) ([]byte, error) {
|
|
||||||
var buf []byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
buf = b[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return (*refs.Checksum)(c).
|
|
||||||
StableMarshal(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal unmarshals protobuf binary representation of Checksum.
|
|
||||||
func (c *Checksum) Unmarshal(data []byte) error {
|
|
||||||
return (*refs.Checksum)(c).
|
|
||||||
Unmarshal(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Checksum to protobuf JSON format.
|
|
||||||
func (c *Checksum) MarshalJSON() ([]byte, error) {
|
|
||||||
return (*refs.Checksum)(c).
|
|
||||||
MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Checksum from protobuf JSON format.
|
|
||||||
func (c *Checksum) UnmarshalJSON(data []byte) error {
|
|
||||||
return (*refs.Checksum)(c).
|
|
||||||
UnmarshalJSON(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Checksum) String() string {
|
|
||||||
return hex.EncodeToString(
|
|
||||||
(*refs.Checksum)(c).
|
|
||||||
GetSum(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses Checksum from its string representation.
|
|
||||||
func (c *Checksum) Parse(s string) error {
|
|
||||||
data, err := hex.DecodeString(s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var typ refs.ChecksumType
|
|
||||||
|
|
||||||
switch ln := len(data); ln {
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unsupported checksum length %d", ln)
|
|
||||||
case sha256.Size:
|
|
||||||
typ = refs.SHA256
|
|
||||||
case 64:
|
|
||||||
typ = refs.TillichZemor
|
|
||||||
}
|
|
||||||
|
|
||||||
cV2 := (*refs.Checksum)(c)
|
|
||||||
cV2.SetType(typ)
|
|
||||||
cV2.SetSum(data)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns string representation of ChecksumType.
|
|
||||||
//
|
|
||||||
// String mapping:
|
|
||||||
// * ChecksumTZ: TZ;
|
|
||||||
// * ChecksumSHA256: SHA256;
|
|
||||||
// * ChecksumUnknown, default: CHECKSUM_TYPE_UNSPECIFIED.
|
|
||||||
func (m ChecksumType) String() string {
|
|
||||||
var m2 refs.ChecksumType
|
|
||||||
|
|
||||||
switch m {
|
|
||||||
default:
|
|
||||||
m2 = refs.UnknownChecksum
|
|
||||||
case ChecksumTZ:
|
|
||||||
m2 = refs.TillichZemor
|
|
||||||
case ChecksumSHA256:
|
|
||||||
m2 = refs.SHA256
|
|
||||||
}
|
|
||||||
|
|
||||||
return m2.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromString parses ChecksumType from a string representation.
|
|
||||||
// It is a reverse action to String().
|
|
||||||
//
|
|
||||||
// Returns true if s was parsed successfully.
|
|
||||||
func (m *ChecksumType) FromString(s string) bool {
|
|
||||||
var g refs.ChecksumType
|
|
||||||
|
|
||||||
ok := g.FromString(s)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
switch g {
|
|
||||||
default:
|
|
||||||
*m = ChecksumUnknown
|
|
||||||
case refs.TillichZemor:
|
|
||||||
*m = ChecksumTZ
|
|
||||||
case refs.SHA256:
|
|
||||||
*m = ChecksumSHA256
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok
|
|
||||||
}
|
|
|
@ -1,175 +0,0 @@
|
||||||
package pkg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/sha256"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func randSHA256(t *testing.T) [sha256.Size]byte {
|
|
||||||
cSHA256 := [sha256.Size]byte{}
|
|
||||||
_, err := rand.Read(cSHA256[:])
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return cSHA256
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksum(t *testing.T) {
|
|
||||||
c := NewChecksum()
|
|
||||||
|
|
||||||
cSHA256 := [sha256.Size]byte{}
|
|
||||||
_, _ = rand.Read(cSHA256[:])
|
|
||||||
|
|
||||||
c.SetSHA256(cSHA256)
|
|
||||||
|
|
||||||
require.Equal(t, ChecksumSHA256, c.Type())
|
|
||||||
require.Equal(t, cSHA256[:], c.Sum())
|
|
||||||
|
|
||||||
cV2 := c.ToV2()
|
|
||||||
|
|
||||||
require.Equal(t, refs.SHA256, cV2.GetType())
|
|
||||||
require.Equal(t, cSHA256[:], cV2.GetSum())
|
|
||||||
|
|
||||||
cTZ := [64]byte{}
|
|
||||||
_, _ = rand.Read(cSHA256[:])
|
|
||||||
|
|
||||||
c.SetTillichZemor(cTZ)
|
|
||||||
|
|
||||||
require.Equal(t, ChecksumTZ, c.Type())
|
|
||||||
require.Equal(t, cTZ[:], c.Sum())
|
|
||||||
|
|
||||||
cV2 = c.ToV2()
|
|
||||||
|
|
||||||
require.Equal(t, refs.TillichZemor, cV2.GetType())
|
|
||||||
require.Equal(t, cTZ[:], cV2.GetSum())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEqualChecksums(t *testing.T) {
|
|
||||||
require.True(t, EqualChecksums(nil, nil))
|
|
||||||
|
|
||||||
csSHA := [sha256.Size]byte{}
|
|
||||||
_, _ = rand.Read(csSHA[:])
|
|
||||||
|
|
||||||
cs1 := NewChecksum()
|
|
||||||
cs1.SetSHA256(csSHA)
|
|
||||||
|
|
||||||
cs2 := NewChecksum()
|
|
||||||
cs2.SetSHA256(csSHA)
|
|
||||||
|
|
||||||
require.True(t, EqualChecksums(cs1, cs2))
|
|
||||||
|
|
||||||
csSHA[0]++
|
|
||||||
cs2.SetSHA256(csSHA)
|
|
||||||
|
|
||||||
require.False(t, EqualChecksums(cs1, cs2))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksumEncoding(t *testing.T) {
|
|
||||||
cs := NewChecksum()
|
|
||||||
cs.SetSHA256(randSHA256(t))
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data, err := cs.Marshal()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
c2 := NewChecksum()
|
|
||||||
require.NoError(t, c2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, cs, c2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
|
||||||
data, err := cs.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cs2 := NewChecksum()
|
|
||||||
require.NoError(t, cs2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, cs, cs2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("string", func(t *testing.T) {
|
|
||||||
cs2 := NewChecksum()
|
|
||||||
|
|
||||||
require.NoError(t, cs2.Parse(cs.String()))
|
|
||||||
|
|
||||||
require.Equal(t, cs, cs2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewChecksumFromV2(t *testing.T) {
|
|
||||||
t.Run("from nil", func(t *testing.T) {
|
|
||||||
var x *refs.Checksum
|
|
||||||
|
|
||||||
require.Nil(t, NewChecksumFromV2(x))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksum_ToV2(t *testing.T) {
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
|
||||||
var x *Checksum
|
|
||||||
|
|
||||||
require.Nil(t, x.ToV2())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewChecksum(t *testing.T) {
|
|
||||||
t.Run("default values", func(t *testing.T) {
|
|
||||||
chs := NewChecksum()
|
|
||||||
|
|
||||||
// check initial values
|
|
||||||
require.Equal(t, ChecksumUnknown, chs.Type())
|
|
||||||
require.Nil(t, chs.Sum())
|
|
||||||
|
|
||||||
// convert to v2 message
|
|
||||||
chsV2 := chs.ToV2()
|
|
||||||
|
|
||||||
require.Equal(t, refs.UnknownChecksum, chsV2.GetType())
|
|
||||||
require.Nil(t, chsV2.GetSum())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type enumIface interface {
|
|
||||||
FromString(string) bool
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type enumStringItem struct {
|
|
||||||
val enumIface
|
|
||||||
str string
|
|
||||||
}
|
|
||||||
|
|
||||||
func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) {
|
|
||||||
for _, item := range items {
|
|
||||||
require.Equal(t, item.str, item.val.String())
|
|
||||||
|
|
||||||
s := item.val.String()
|
|
||||||
|
|
||||||
require.True(t, e.FromString(s), s)
|
|
||||||
|
|
||||||
require.EqualValues(t, item.val, e, item.val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// incorrect strings
|
|
||||||
for _, str := range []string{
|
|
||||||
"some string",
|
|
||||||
"undefined",
|
|
||||||
} {
|
|
||||||
require.False(t, e.FromString(str))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksumType_String(t *testing.T) {
|
|
||||||
toPtr := func(v ChecksumType) *ChecksumType {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
testEnumStrings(t, new(ChecksumType), []enumStringItem{
|
|
||||||
{val: toPtr(ChecksumTZ), str: "TZ"},
|
|
||||||
{val: toPtr(ChecksumSHA256), str: "SHA256"},
|
|
||||||
{val: toPtr(ChecksumUnknown), str: "CHECKSUM_TYPE_UNSPECIFIED"},
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/accounting"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/client"
|
|
||||||
v2accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting"
|
|
||||||
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
|
|
||||||
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Accounting contains methods related to balance querying.
|
|
||||||
type Accounting interface {
|
|
||||||
// GetBalance returns balance of provided account.
|
|
||||||
GetBalance(context.Context, *owner.ID, ...CallOption) (*accounting.Decimal, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientImpl) GetBalance(ctx context.Context, owner *owner.ID, opts ...CallOption) (*accounting.Decimal, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2accounting.BalanceRequestBody)
|
|
||||||
reqBody.SetOwnerID(owner.ToV2())
|
|
||||||
|
|
||||||
req := new(v2accounting.BalanceRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.Balance(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("transport error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return accounting.NewDecimalFromV2(resp.GetBody().GetBalance()), nil
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Client represents NeoFS client.
|
|
||||||
type Client interface {
|
|
||||||
Accounting
|
|
||||||
Container
|
|
||||||
Netmap
|
|
||||||
Object
|
|
||||||
Session
|
|
||||||
Reputation
|
|
||||||
|
|
||||||
// Raw must return underlying raw protobuf client.
|
|
||||||
Raw() *client.Client
|
|
||||||
|
|
||||||
// Conn must return underlying connection.
|
|
||||||
//
|
|
||||||
// Must return a non-nil result after the first RPC call
|
|
||||||
// completed without a connection error.
|
|
||||||
Conn() io.Closer
|
|
||||||
}
|
|
||||||
|
|
||||||
type clientImpl struct {
|
|
||||||
onceInit sync.Once
|
|
||||||
|
|
||||||
raw *client.Client
|
|
||||||
|
|
||||||
opts *clientOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(opts ...Option) (Client, error) {
|
|
||||||
clientOptions := defaultClientOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](clientOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &clientImpl{
|
|
||||||
opts: clientOptions,
|
|
||||||
}, nil
|
|
||||||
}
|
|
|
@ -1,477 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
|
||||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/session"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/client"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/util/signature"
|
|
||||||
v2container "github.com/nspcc-dev/neofs-api-go/v2/container"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
||||||
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
|
|
||||||
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Container contains methods related to container and ACL.
|
|
||||||
type Container interface {
|
|
||||||
// PutContainer creates new container in the NeoFS network.
|
|
||||||
PutContainer(context.Context, *container.Container, ...CallOption) (*cid.ID, error)
|
|
||||||
|
|
||||||
// GetContainer returns container by ID.
|
|
||||||
GetContainer(context.Context, *cid.ID, ...CallOption) (*container.Container, error)
|
|
||||||
|
|
||||||
// ListContainers return container list with the provided owner.
|
|
||||||
ListContainers(context.Context, *owner.ID, ...CallOption) ([]*cid.ID, error)
|
|
||||||
|
|
||||||
// DeleteContainer removes container from NeoFS network.
|
|
||||||
DeleteContainer(context.Context, *cid.ID, ...CallOption) error
|
|
||||||
|
|
||||||
// GetEACL returns extended ACL for a given container.
|
|
||||||
GetEACL(context.Context, *cid.ID, ...CallOption) (*EACLWithSignature, error)
|
|
||||||
|
|
||||||
// SetEACL sets extended ACL.
|
|
||||||
SetEACL(context.Context, *eacl.Table, ...CallOption) error
|
|
||||||
|
|
||||||
// AnnounceContainerUsedSpace announces amount of space which is taken by stored objects.
|
|
||||||
AnnounceContainerUsedSpace(context.Context, []container.UsedSpaceAnnouncement, ...CallOption) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type delContainerSignWrapper struct {
|
|
||||||
body *v2container.DeleteRequestBody
|
|
||||||
}
|
|
||||||
|
|
||||||
// EACLWithSignature represents eACL table/signature pair.
|
|
||||||
type EACLWithSignature struct {
|
|
||||||
table *eacl.Table
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c delContainerSignWrapper) ReadSignedData(bytes []byte) ([]byte, error) {
|
|
||||||
return c.body.GetContainerID().GetValue(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c delContainerSignWrapper) SignedDataSize() int {
|
|
||||||
return len(c.body.GetContainerID().GetValue())
|
|
||||||
}
|
|
||||||
|
|
||||||
// EACL returns eACL table.
|
|
||||||
func (e EACLWithSignature) EACL() *eacl.Table {
|
|
||||||
return e.table
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signature returns table signature.
|
|
||||||
//
|
|
||||||
// Deprecated: use EACL().Signature() instead.
|
|
||||||
func (e EACLWithSignature) Signature() *pkg.Signature {
|
|
||||||
return e.table.Signature()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientImpl) PutContainer(ctx context.Context, cnr *container.Container, opts ...CallOption) (*cid.ID, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set transport version
|
|
||||||
cnr.SetVersion(pkg.SDKVersion())
|
|
||||||
|
|
||||||
// if container owner is not set, then use client key as owner
|
|
||||||
if cnr.OwnerID() == nil {
|
|
||||||
w, err := owner.NEO3WalletFromPublicKey(&callOptions.key.PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ownerID := new(owner.ID)
|
|
||||||
ownerID.SetNeo3Wallet(w)
|
|
||||||
|
|
||||||
cnr.SetOwnerID(ownerID)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2container.PutRequestBody)
|
|
||||||
reqBody.SetContainer(cnr.ToV2())
|
|
||||||
|
|
||||||
// sign container
|
|
||||||
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainer()}
|
|
||||||
|
|
||||||
err := signature.SignDataWithHandler(callOptions.key, signWrapper, func(key []byte, sig []byte) {
|
|
||||||
containerSignature := new(refs.Signature)
|
|
||||||
containerSignature.SetKey(key)
|
|
||||||
containerSignature.SetSign(sig)
|
|
||||||
reqBody.SetSignature(containerSignature)
|
|
||||||
}, signature.SignWithRFC6979())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req := new(v2container.PutRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
|
|
||||||
meta := v2MetaHeaderFromOpts(callOptions)
|
|
||||||
meta.SetSessionToken(cnr.SessionToken().ToV2())
|
|
||||||
|
|
||||||
req.SetMetaHeader(meta)
|
|
||||||
|
|
||||||
err = v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.PutContainer(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cid.NewFromV2(resp.GetBody().GetContainerID()), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetContainer receives container structure through NeoFS API call.
|
|
||||||
//
|
|
||||||
// Returns error if container structure is received but does not meet NeoFS API specification.
|
|
||||||
func (c *clientImpl) GetContainer(ctx context.Context, id *cid.ID, opts ...CallOption) (*container.Container, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2container.GetRequestBody)
|
|
||||||
reqBody.SetContainerID(id.ToV2())
|
|
||||||
|
|
||||||
req := new(v2container.GetRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.GetContainer(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("transport error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
body := resp.GetBody()
|
|
||||||
|
|
||||||
cnr := container.NewContainerFromV2(body.GetContainer())
|
|
||||||
|
|
||||||
cnr.SetSessionToken(
|
|
||||||
session.NewTokenFromV2(body.GetSessionToken()),
|
|
||||||
)
|
|
||||||
|
|
||||||
cnr.SetSignature(
|
|
||||||
pkg.NewSignatureFromV2(body.GetSignature()),
|
|
||||||
)
|
|
||||||
|
|
||||||
return cnr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetVerifiedContainerStructure is a wrapper over Client.GetContainer method
|
|
||||||
// which checks if the structure of the resulting container matches its identifier.
|
|
||||||
//
|
|
||||||
// Returns an error if container does not match the identifier.
|
|
||||||
func GetVerifiedContainerStructure(ctx context.Context, c Client, id *cid.ID, opts ...CallOption) (*container.Container, error) {
|
|
||||||
cnr, err := c.GetContainer(ctx, id, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !container.CalculateID(cnr).Equal(id) {
|
|
||||||
return nil, errors.New("container structure does not match the identifier")
|
|
||||||
}
|
|
||||||
|
|
||||||
return cnr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientImpl) ListContainers(ctx context.Context, ownerID *owner.ID, opts ...CallOption) ([]*cid.ID, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ownerID == nil {
|
|
||||||
w, err := owner.NEO3WalletFromPublicKey(&callOptions.key.PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ownerID = new(owner.ID)
|
|
||||||
ownerID.SetNeo3Wallet(w)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2container.ListRequestBody)
|
|
||||||
reqBody.SetOwnerID(ownerID.ToV2())
|
|
||||||
|
|
||||||
req := new(v2container.ListRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.ListContainers(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("transport error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
result := make([]*cid.ID, 0, len(resp.GetBody().GetContainerIDs()))
|
|
||||||
for _, cidV2 := range resp.GetBody().GetContainerIDs() {
|
|
||||||
result = append(result, cid.NewFromV2(cidV2))
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientImpl) DeleteContainer(ctx context.Context, id *cid.ID, opts ...CallOption) error {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2container.DeleteRequestBody)
|
|
||||||
reqBody.SetContainerID(id.ToV2())
|
|
||||||
|
|
||||||
// sign container
|
|
||||||
err := signature.SignDataWithHandler(callOptions.key,
|
|
||||||
delContainerSignWrapper{
|
|
||||||
body: reqBody,
|
|
||||||
},
|
|
||||||
func(key []byte, sig []byte) {
|
|
||||||
containerSignature := new(refs.Signature)
|
|
||||||
containerSignature.SetKey(key)
|
|
||||||
containerSignature.SetSign(sig)
|
|
||||||
reqBody.SetSignature(containerSignature)
|
|
||||||
},
|
|
||||||
signature.SignWithRFC6979())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
req := new(v2container.DeleteRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err = v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.DeleteContainer(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("transport error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := v2signature.VerifyServiceMessage(resp); err != nil {
|
|
||||||
return fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientImpl) GetEACL(ctx context.Context, id *cid.ID, opts ...CallOption) (*EACLWithSignature, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2container.GetExtendedACLRequestBody)
|
|
||||||
reqBody.SetContainerID(id.ToV2())
|
|
||||||
|
|
||||||
req := new(v2container.GetExtendedACLRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.GetEACL(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("transport error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
body := resp.GetBody()
|
|
||||||
|
|
||||||
table := eacl.NewTableFromV2(body.GetEACL())
|
|
||||||
|
|
||||||
table.SetSessionToken(
|
|
||||||
session.NewTokenFromV2(body.GetSessionToken()),
|
|
||||||
)
|
|
||||||
|
|
||||||
table.SetSignature(
|
|
||||||
pkg.NewSignatureFromV2(body.GetSignature()),
|
|
||||||
)
|
|
||||||
|
|
||||||
return &EACLWithSignature{
|
|
||||||
table: table,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientImpl) SetEACL(ctx context.Context, eacl *eacl.Table, opts ...CallOption) error {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2container.SetExtendedACLRequestBody)
|
|
||||||
reqBody.SetEACL(eacl.ToV2())
|
|
||||||
reqBody.GetEACL().SetVersion(pkg.SDKVersion().ToV2())
|
|
||||||
|
|
||||||
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetEACL()}
|
|
||||||
|
|
||||||
err := signature.SignDataWithHandler(callOptions.key, signWrapper, func(key []byte, sig []byte) {
|
|
||||||
eaclSignature := new(refs.Signature)
|
|
||||||
eaclSignature.SetKey(key)
|
|
||||||
eaclSignature.SetSign(sig)
|
|
||||||
reqBody.SetSignature(eaclSignature)
|
|
||||||
}, signature.SignWithRFC6979())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
req := new(v2container.SetExtendedACLRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
|
|
||||||
meta := v2MetaHeaderFromOpts(callOptions)
|
|
||||||
meta.SetSessionToken(eacl.SessionToken().ToV2())
|
|
||||||
|
|
||||||
req.SetMetaHeader(meta)
|
|
||||||
|
|
||||||
err = v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.SetEACL(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("transport error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnnounceContainerUsedSpace used by storage nodes to estimate their container
|
|
||||||
// sizes during lifetime. Use it only in storage node applications.
|
|
||||||
func (c *clientImpl) AnnounceContainerUsedSpace(
|
|
||||||
ctx context.Context,
|
|
||||||
announce []container.UsedSpaceAnnouncement,
|
|
||||||
opts ...CallOption) error {
|
|
||||||
callOptions := c.defaultCallOptions() // apply all available options
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert list of SDK announcement structures into NeoFS-API v2 list
|
|
||||||
v2announce := make([]*v2container.UsedSpaceAnnouncement, 0, len(announce))
|
|
||||||
for i := range announce {
|
|
||||||
v2announce = append(v2announce, announce[i].ToV2())
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare body of the NeoFS-API v2 request and request itself
|
|
||||||
reqBody := new(v2container.AnnounceUsedSpaceRequestBody)
|
|
||||||
reqBody.SetAnnouncements(v2announce)
|
|
||||||
|
|
||||||
req := new(v2container.AnnounceUsedSpaceRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
// sign the request
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.AnnounceUsedSpace(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("transport error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,124 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/client"
|
|
||||||
v2netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap"
|
|
||||||
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
|
|
||||||
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Netmap contains methods related to netmap.
|
|
||||||
type Netmap interface {
|
|
||||||
// EndpointInfo returns attributes, address and public key of the node, specified
|
|
||||||
// in client constructor via address or open connection. This can be used as a
|
|
||||||
// health check to see if node is alive and responses to requests.
|
|
||||||
EndpointInfo(context.Context, ...CallOption) (*EndpointInfo, error)
|
|
||||||
|
|
||||||
// NetworkInfo returns information about the NeoFS network of which the remote server is a part.
|
|
||||||
NetworkInfo(context.Context, ...CallOption) (*netmap.NetworkInfo, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EACLWithSignature represents eACL table/signature pair.
|
|
||||||
type EndpointInfo struct {
|
|
||||||
version *pkg.Version
|
|
||||||
|
|
||||||
ni *netmap.NodeInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
// LatestVersion returns latest NeoFS API version in use.
|
|
||||||
func (e *EndpointInfo) LatestVersion() *pkg.Version {
|
|
||||||
return e.version
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeInfo returns returns information about the NeoFS node.
|
|
||||||
func (e *EndpointInfo) NodeInfo() *netmap.NodeInfo {
|
|
||||||
return e.ni
|
|
||||||
}
|
|
||||||
|
|
||||||
// EndpointInfo returns attributes, address and public key of the node, specified
|
|
||||||
// in client constructor via address or open connection. This can be used as a
|
|
||||||
// health check to see if node is alive and responses to requests.
|
|
||||||
func (c *clientImpl) EndpointInfo(ctx context.Context, opts ...CallOption) (*EndpointInfo, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2netmap.LocalNodeInfoRequestBody)
|
|
||||||
|
|
||||||
req := new(v2netmap.LocalNodeInfoRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.LocalNodeInfo(c.Raw(), req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("transport error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
body := resp.GetBody()
|
|
||||||
|
|
||||||
return &EndpointInfo{
|
|
||||||
version: pkg.NewVersionFromV2(body.GetVersion()),
|
|
||||||
ni: netmap.NewNodeInfoFromV2(body.GetNodeInfo()),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NetworkInfo returns information about the NeoFS network of which the remote server is a part.
|
|
||||||
func (c *clientImpl) NetworkInfo(ctx context.Context, opts ...CallOption) (*netmap.NetworkInfo, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2netmap.NetworkInfoRequestBody)
|
|
||||||
|
|
||||||
req := new(v2netmap.NetworkInfoRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.NetworkInfo(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("v2 NetworkInfo RPC failure: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("response message verification failed: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return netmap.NewNetworkInfoFromV2(resp.GetBody().GetNetworkInfo()), nil
|
|
||||||
}
|
|
1373
pkg/client/object.go
1373
pkg/client/object.go
File diff suppressed because it is too large
Load diff
|
@ -1,95 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/object"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/signature"
|
|
||||||
"github.com/nspcc-dev/neofs-crypto/test"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
type singleResponseStream struct {
|
|
||||||
called bool
|
|
||||||
resp object.GetResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *singleResponseStream) Read(r *object.GetResponse) error {
|
|
||||||
if x.called {
|
|
||||||
return io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
x.called = true
|
|
||||||
|
|
||||||
*r = x.resp
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var key = test.DecodeKey(0)
|
|
||||||
|
|
||||||
func chunkResponse(c []byte) (r object.GetResponse) {
|
|
||||||
chunkPart := new(object.GetObjectPartChunk)
|
|
||||||
chunkPart.SetChunk(c)
|
|
||||||
|
|
||||||
body := new(object.GetResponseBody)
|
|
||||||
body.SetObjectPart(chunkPart)
|
|
||||||
|
|
||||||
r.SetBody(body)
|
|
||||||
|
|
||||||
if err := signature.SignServiceMessage(key, &r); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func data(sz int) []byte {
|
|
||||||
data := make([]byte, sz)
|
|
||||||
|
|
||||||
for i := range data {
|
|
||||||
data[i] = byte(i) % ^byte(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkFullRead(t *testing.T, r io.Reader, buf, payload []byte) {
|
|
||||||
var (
|
|
||||||
restored []byte
|
|
||||||
read int
|
|
||||||
)
|
|
||||||
|
|
||||||
for {
|
|
||||||
n, err := r.Read(buf)
|
|
||||||
|
|
||||||
read += n
|
|
||||||
restored = append(restored, buf[:n]...)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
require.Equal(t, err, io.EOF)
|
|
||||||
break
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require.Equal(t, payload, restored)
|
|
||||||
require.EqualValues(t, len(payload), read)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestObjectPayloadReader_Read(t *testing.T) {
|
|
||||||
t.Run("read with tail", func(t *testing.T) {
|
|
||||||
payload := data(10)
|
|
||||||
|
|
||||||
buf := make([]byte, len(payload)-1)
|
|
||||||
|
|
||||||
var r io.Reader = &objectPayloadReader{
|
|
||||||
stream: &singleResponseStream{
|
|
||||||
resp: chunkResponse(payload),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
checkFullRead(t, r, buf, payload)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,189 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/tls"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/session"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/token"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/client"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
||||||
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
CallOption func(*callOptions)
|
|
||||||
|
|
||||||
Option func(*clientOptions)
|
|
||||||
|
|
||||||
callOptions struct {
|
|
||||||
version *pkg.Version
|
|
||||||
xHeaders []*pkg.XHeader
|
|
||||||
ttl uint32
|
|
||||||
epoch uint64
|
|
||||||
key *ecdsa.PrivateKey
|
|
||||||
session *session.Token
|
|
||||||
bearer *token.BearerToken
|
|
||||||
}
|
|
||||||
|
|
||||||
clientOptions struct {
|
|
||||||
key *ecdsa.PrivateKey
|
|
||||||
|
|
||||||
rawOpts []client.Option
|
|
||||||
|
|
||||||
cbRespInfo func(ResponseMetaInfo) error
|
|
||||||
}
|
|
||||||
|
|
||||||
v2SessionReqInfo struct {
|
|
||||||
addr *refs.Address
|
|
||||||
verb v2session.ObjectSessionVerb
|
|
||||||
|
|
||||||
exp, nbf, iat uint64
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *clientImpl) defaultCallOptions() *callOptions {
|
|
||||||
return &callOptions{
|
|
||||||
version: pkg.SDKVersion(),
|
|
||||||
ttl: 2,
|
|
||||||
key: c.opts.key,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithXHeader(x *pkg.XHeader) CallOption {
|
|
||||||
return func(opts *callOptions) {
|
|
||||||
opts.xHeaders = append(opts.xHeaders, x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithTTL(ttl uint32) CallOption {
|
|
||||||
return func(opts *callOptions) {
|
|
||||||
opts.ttl = ttl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithKey sets client's key for the next request.
|
|
||||||
func WithKey(key *ecdsa.PrivateKey) CallOption {
|
|
||||||
return func(opts *callOptions) {
|
|
||||||
opts.key = key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithEpoch(epoch uint64) CallOption {
|
|
||||||
return func(opts *callOptions) {
|
|
||||||
opts.epoch = epoch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithSession(token *session.Token) CallOption {
|
|
||||||
return func(opts *callOptions) {
|
|
||||||
opts.session = token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithBearer(token *token.BearerToken) CallOption {
|
|
||||||
return func(opts *callOptions) {
|
|
||||||
opts.bearer = token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func v2MetaHeaderFromOpts(options *callOptions) *v2session.RequestMetaHeader {
|
|
||||||
meta := new(v2session.RequestMetaHeader)
|
|
||||||
meta.SetVersion(options.version.ToV2())
|
|
||||||
meta.SetTTL(options.ttl)
|
|
||||||
meta.SetEpoch(options.epoch)
|
|
||||||
|
|
||||||
xhdrs := make([]*v2session.XHeader, len(options.xHeaders))
|
|
||||||
for i := range options.xHeaders {
|
|
||||||
xhdrs[i] = options.xHeaders[i].ToV2()
|
|
||||||
}
|
|
||||||
|
|
||||||
meta.SetXHeaders(xhdrs)
|
|
||||||
|
|
||||||
if options.bearer != nil {
|
|
||||||
meta.SetBearerToken(options.bearer.ToV2())
|
|
||||||
}
|
|
||||||
|
|
||||||
meta.SetSessionToken(options.session.ToV2())
|
|
||||||
|
|
||||||
return meta
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultClientOptions() *clientOptions {
|
|
||||||
return &clientOptions{
|
|
||||||
rawOpts: make([]client.Option, 0, 4),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAddress returns option to specify
|
|
||||||
// network address of the remote server.
|
|
||||||
//
|
|
||||||
// Ignored if WithGRPCConnection is provided.
|
|
||||||
func WithAddress(addr string) Option {
|
|
||||||
return func(opts *clientOptions) {
|
|
||||||
opts.rawOpts = append(opts.rawOpts, client.WithNetworkAddress(addr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDialTimeout returns option to set connection timeout to the remote node.
|
|
||||||
//
|
|
||||||
// Ignored if WithGRPCConn is provided.
|
|
||||||
func WithDialTimeout(dur time.Duration) Option {
|
|
||||||
return func(opts *clientOptions) {
|
|
||||||
opts.rawOpts = append(opts.rawOpts, client.WithDialTimeout(dur))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithTLSConfig returns option to set connection's TLS config to the remote node.
|
|
||||||
//
|
|
||||||
// Ignored if WithGRPCConnection is provided.
|
|
||||||
func WithTLSConfig(cfg *tls.Config) Option {
|
|
||||||
return func(opts *clientOptions) {
|
|
||||||
opts.rawOpts = append(opts.rawOpts, client.WithTLSCfg(cfg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDefaultPrivateKey returns option to set default private key
|
|
||||||
// used for the work.
|
|
||||||
func WithDefaultPrivateKey(key *ecdsa.PrivateKey) Option {
|
|
||||||
return func(opts *clientOptions) {
|
|
||||||
opts.key = key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithURIAddress returns option to specify
|
|
||||||
// network address of a remote server and connection
|
|
||||||
// scheme for it.
|
|
||||||
//
|
|
||||||
// Format of the URI:
|
|
||||||
//
|
|
||||||
// [scheme://]host:port
|
|
||||||
//
|
|
||||||
// Supported schemes:
|
|
||||||
// - grpc;
|
|
||||||
// - grpcs.
|
|
||||||
//
|
|
||||||
// tls.Cfg second argument is optional and is taken into
|
|
||||||
// account only in case of `grpcs` scheme.
|
|
||||||
//
|
|
||||||
// Falls back to WithNetworkAddress if address is not a valid URI.
|
|
||||||
//
|
|
||||||
// Do not use along with WithAddress and WithTLSConfig.
|
|
||||||
//
|
|
||||||
// Ignored if WithGRPCConnection is provided.
|
|
||||||
func WithURIAddress(addr string, tlsCfg *tls.Config) Option {
|
|
||||||
return func(opts *clientOptions) {
|
|
||||||
opts.rawOpts = append(opts.rawOpts, client.WithNetworkURIAddress(addr, tlsCfg)...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithGRPCConnection returns option to set GRPC connection to
|
|
||||||
// the remote node.
|
|
||||||
func WithGRPCConnection(grpcConn *grpc.ClientConn) Option {
|
|
||||||
return func(opts *clientOptions) {
|
|
||||||
opts.rawOpts = append(opts.rawOpts, client.WithGRPCConn(grpcConn))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Raw returns underlying raw protobuf client.
|
|
||||||
func (c *clientImpl) Raw() *client.Client {
|
|
||||||
c.onceInit.Do(func() {
|
|
||||||
c.raw = client.New(c.opts.rawOpts...)
|
|
||||||
})
|
|
||||||
|
|
||||||
return c.raw
|
|
||||||
}
|
|
||||||
|
|
||||||
// implements Client.Conn method.
|
|
||||||
func (c *clientImpl) Conn() io.Closer {
|
|
||||||
return c.raw.Conn()
|
|
||||||
}
|
|
|
@ -1,171 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/reputation"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/rpc/client"
|
|
||||||
v2reputation "github.com/nspcc-dev/neofs-api-go/v2/reputation"
|
|
||||||
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
|
|
||||||
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reputation contains methods for working with Reputation system values.
|
|
||||||
type Reputation interface {
|
|
||||||
// AnnounceLocalTrust announces local trust values of local peer.
|
|
||||||
AnnounceLocalTrust(context.Context, AnnounceLocalTrustPrm, ...CallOption) (*AnnounceLocalTrustRes, error)
|
|
||||||
|
|
||||||
// AnnounceIntermediateTrust announces the intermediate result of the iterative algorithm for calculating
|
|
||||||
// the global reputation of the node.
|
|
||||||
AnnounceIntermediateTrust(context.Context, AnnounceIntermediateTrustPrm, ...CallOption) (*AnnounceIntermediateTrustRes, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnnounceLocalTrustPrm groups parameters of AnnounceLocalTrust operation.
|
|
||||||
type AnnounceLocalTrustPrm struct {
|
|
||||||
epoch uint64
|
|
||||||
|
|
||||||
trusts []*reputation.Trust
|
|
||||||
}
|
|
||||||
|
|
||||||
// Epoch returns epoch in which the trust was assessed.
|
|
||||||
func (x AnnounceLocalTrustPrm) Epoch() uint64 {
|
|
||||||
return x.epoch
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEpoch sets epoch in which the trust was assessed.
|
|
||||||
func (x *AnnounceLocalTrustPrm) SetEpoch(epoch uint64) {
|
|
||||||
x.epoch = epoch
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trusts returns list of local trust values.
|
|
||||||
func (x AnnounceLocalTrustPrm) Trusts() []*reputation.Trust {
|
|
||||||
return x.trusts
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTrusts sets list of local trust values.
|
|
||||||
func (x *AnnounceLocalTrustPrm) SetTrusts(trusts []*reputation.Trust) {
|
|
||||||
x.trusts = trusts
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnnounceLocalTrustRes groups results of AnnounceLocalTrust operation.
|
|
||||||
type AnnounceLocalTrustRes struct{}
|
|
||||||
|
|
||||||
func (c *clientImpl) AnnounceLocalTrust(ctx context.Context, prm AnnounceLocalTrustPrm, opts ...CallOption) (*AnnounceLocalTrustRes, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2reputation.AnnounceLocalTrustRequestBody)
|
|
||||||
reqBody.SetEpoch(prm.Epoch())
|
|
||||||
reqBody.SetTrusts(reputation.TrustsToV2(prm.Trusts()))
|
|
||||||
|
|
||||||
req := new(v2reputation.AnnounceLocalTrustRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.AnnounceLocalTrust(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return new(AnnounceLocalTrustRes), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnnounceIntermediateTrustPrm groups parameters of AnnounceIntermediateTrust operation.
|
|
||||||
type AnnounceIntermediateTrustPrm struct {
|
|
||||||
epoch uint64
|
|
||||||
|
|
||||||
iter uint32
|
|
||||||
|
|
||||||
trust *reputation.PeerToPeerTrust
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AnnounceIntermediateTrustPrm) Epoch() uint64 {
|
|
||||||
return x.epoch
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AnnounceIntermediateTrustPrm) SetEpoch(epoch uint64) {
|
|
||||||
x.epoch = epoch
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iteration returns sequence number of the iteration.
|
|
||||||
func (x AnnounceIntermediateTrustPrm) Iteration() uint32 {
|
|
||||||
return x.iter
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetIteration sets sequence number of the iteration.
|
|
||||||
func (x *AnnounceIntermediateTrustPrm) SetIteration(iter uint32) {
|
|
||||||
x.iter = iter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trust returns current global trust value computed at the specified iteration.
|
|
||||||
func (x AnnounceIntermediateTrustPrm) Trust() *reputation.PeerToPeerTrust {
|
|
||||||
return x.trust
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTrust sets current global trust value computed at the specified iteration.
|
|
||||||
func (x *AnnounceIntermediateTrustPrm) SetTrust(trust *reputation.PeerToPeerTrust) {
|
|
||||||
x.trust = trust
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnnounceIntermediateTrustRes groups results of AnnounceIntermediateTrust operation.
|
|
||||||
type AnnounceIntermediateTrustRes struct{}
|
|
||||||
|
|
||||||
func (c *clientImpl) AnnounceIntermediateTrust(ctx context.Context, prm AnnounceIntermediateTrustPrm, opts ...CallOption) (*AnnounceIntermediateTrustRes, error) {
|
|
||||||
// apply all available options
|
|
||||||
callOptions := c.defaultCallOptions()
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](callOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := new(v2reputation.AnnounceIntermediateResultRequestBody)
|
|
||||||
reqBody.SetEpoch(prm.Epoch())
|
|
||||||
reqBody.SetIteration(prm.Iteration())
|
|
||||||
reqBody.SetTrust(prm.Trust().ToV2())
|
|
||||||
|
|
||||||
req := new(v2reputation.AnnounceIntermediateResultRequest)
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
||||||
|
|
||||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := rpcapi.AnnounceIntermediateResult(c.Raw(), req, client.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle response meta info
|
|
||||||
if err := c.handleResponseInfoV2(callOptions, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v2signature.VerifyServiceMessage(resp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't verify response message: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return new(AnnounceIntermediateTrustRes), nil
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue