diff --git a/client/common.go b/client/common.go index 11cec28..65abae5 100644 --- a/client/common.go +++ b/client/common.go @@ -46,15 +46,13 @@ func writeXHeadersToMeta(xHeaders []string, h *v2session.RequestMetaHeader) { // error messages. var ( - errorMissingContainer = errors.New("missing container") - errorMissingObject = errors.New("missing object") - errorAccountNotSet = errors.New("account not set") - errorServerAddrUnset = errors.New("server address is unset or empty") - errorEACLTableNotSet = errors.New("eACL table not set") - errorMissingAnnouncements = errors.New("missing announcements") - errorZeroRangeLength = errors.New("zero range length") - errorMissingRanges = errors.New("missing ranges") - errorInvalidXHeaders = errors.New("xheaders must be presented only as key-value pairs") + errorMissingContainer = errors.New("missing container") + errorMissingObject = errors.New("missing object") + errorAccountNotSet = errors.New("account not set") + errorServerAddrUnset = errors.New("server address is unset or empty") + errorZeroRangeLength = errors.New("zero range length") + errorMissingRanges = errors.New("missing ranges") + errorInvalidXHeaders = errors.New("xheaders must be presented only as key-value pairs") ) type request interface { diff --git a/client/container_set_eacl.go b/client/container_set_eacl.go deleted file mode 100644 index b149334..0000000 --- a/client/container_set_eacl.go +++ /dev/null @@ -1,136 +0,0 @@ -package client - -import ( - "context" - "fmt" - - v2container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container" - "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" - rpcapi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc" - "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client" - v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session" - "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature" - frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto" - frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa" - "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl" - "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session" -) - -// PrmContainerSetEACL groups parameters of ContainerSetEACL operation. -type PrmContainerSetEACL struct { - // FrostFS request X-Headers. - XHeaders []string - - Table *eacl.Table - - Session *session.Container -} - -// SetTable sets eACL table structure to be set for the container. -// Required parameter. -// -// Deprecated: Use PrmContainerSetEACL.Table instead. -func (x *PrmContainerSetEACL) SetTable(table eacl.Table) { - x.Table = &table -} - -// WithinSession specifies session within which extended ACL of the container -// should be saved. -// -// Creator of the session acquires the authorship of the request. This affects -// the execution of an operation (e.g. access control). -// -// Session is optional, if set the following requirements apply: -// - if particular container is specified (ApplyOnlyTo), it MUST equal the container -// for which extended ACL is going to be set -// - session operation MUST be session.VerbContainerSetEACL (ForVerb) -// - token MUST be signed using private key of the owner of the container to be saved -// -// Deprecated: Use PrmContainerSetEACL.Session instead. -func (x *PrmContainerSetEACL) WithinSession(s session.Container) { - x.Session = &s -} - -func (x *PrmContainerSetEACL) buildRequest(c *Client) (*v2container.SetExtendedACLRequest, error) { - if x.Table == nil { - return nil, errorEACLTableNotSet - } - - if len(x.XHeaders)%2 != 0 { - return nil, errorInvalidXHeaders - } - - eaclV2 := x.Table.ToV2() - - var sig frostfscrypto.Signature - - err := sig.Calculate(frostfsecdsa.SignerRFC6979(c.prm.Key), eaclV2.StableMarshal(nil)) - if err != nil { - return nil, fmt.Errorf("calculate signature: %w", err) - } - - var sigv2 refs.Signature - sig.WriteToV2(&sigv2) - - reqBody := new(v2container.SetExtendedACLRequestBody) - reqBody.SetEACL(eaclV2) - reqBody.SetSignature(&sigv2) - - var meta v2session.RequestMetaHeader - writeXHeadersToMeta(x.XHeaders, &meta) - - if x.Session != nil { - var tokv2 v2session.Token - x.Session.WriteToV2(&tokv2) - - meta.SetSessionToken(&tokv2) - } - - var req v2container.SetExtendedACLRequest - req.SetBody(reqBody) - c.prepareRequest(&req, &meta) - return &req, nil -} - -// ResContainerSetEACL groups resulting values of ContainerSetEACL operation. -type ResContainerSetEACL struct { - statusRes -} - -// ContainerSetEACL sends request to update eACL table of the FrostFS container. -// -// Exactly one return value is non-nil. By default, server status is returned in res structure. -// Any client's internal or transport errors are returned as `error`. -// If PrmInit.DisableFrostFSFailuresResolution has been called, unsuccessful -// FrostFS status codes are included in the returned result structure, -// otherwise, are also returned as `error`. -// -// Operation is asynchronous and no guaranteed even in the absence of errors. -// The required time is also not predictable. -// -// Success can be verified by reading by identifier (see EACL). -// -// Returns an error if parameters are set incorrectly (see PrmContainerSetEACL docs). -// Context is required and must not be nil. It is used for network communication. -// -// Return statuses: -// - global (see Client docs). -func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL) (*ResContainerSetEACL, error) { - req, err := prm.buildRequest(c) - if err != nil { - return nil, err - } - - if err := signature.SignServiceMessage(&c.prm.Key, req); err != nil { - return nil, fmt.Errorf("sign request: %w", err) - } - - resp, err := rpcapi.SetEACL(&c.c, req, client.WithContext(ctx)) - if err != nil { - return nil, err - } - - var res ResContainerSetEACL - res.st, err = c.processResponse(resp) - return &res, err -} diff --git a/client/container_space.go b/client/container_space.go deleted file mode 100644 index dda5acc..0000000 --- a/client/container_space.go +++ /dev/null @@ -1,92 +0,0 @@ -package client - -import ( - "context" - "fmt" - - v2container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container" - rpcapi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc" - "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client" - v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session" - "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature" - "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container" -) - -// PrmAnnounceSpace groups parameters of ContainerAnnounceUsedSpace operation. -type PrmAnnounceSpace struct { - XHeaders []string - - Announcements []container.SizeEstimation -} - -// SetValues sets values describing volume of space that is used for the container objects. -// Required parameter. Must not be empty. -// -// Must not be mutated before the end of the operation. -// -// Deprecated: Use PrmAnnounceSpace.Announcements instead. -func (x *PrmAnnounceSpace) SetValues(vs []container.SizeEstimation) { - x.Announcements = vs -} - -func (x *PrmAnnounceSpace) buildRequest(c *Client) (*v2container.AnnounceUsedSpaceRequest, error) { - if len(x.Announcements) == 0 { - return nil, errorMissingAnnouncements - } - - v2announce := make([]v2container.UsedSpaceAnnouncement, len(x.Announcements)) - for i := range x.Announcements { - x.Announcements[i].WriteToV2(&v2announce[i]) - } - - reqBody := new(v2container.AnnounceUsedSpaceRequestBody) - reqBody.SetAnnouncements(v2announce) - - var req v2container.AnnounceUsedSpaceRequest - req.SetBody(reqBody) - c.prepareRequest(&req, new(v2session.RequestMetaHeader)) - return &req, nil -} - -// ResAnnounceSpace groups resulting values of ContainerAnnounceUsedSpace operation. -type ResAnnounceSpace struct { - statusRes -} - -// ContainerAnnounceUsedSpace sends request to announce volume of the space used for the container objects. -// -// Exactly one return value is non-nil. By default, server status is returned in res structure. -// Any client's internal or transport errors are returned as `error`. -// If PrmInit.DisableFrostFSFailuresResolution has been called, unsuccessful -// FrostFS status codes are included in the returned result structure, -// otherwise, are also returned as `error`. -// -// Operation is asynchronous and no guaranteed even in the absence of errors. -// The required time is also not predictable. -// -// At this moment success can not be checked. -// -// Returns an error if parameters are set incorrectly (see PrmAnnounceSpace docs). -// Context is required and must not be nil. It is used for network communication. -// -// Return statuses: -// - global (see Client docs). -func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, prm PrmAnnounceSpace) (*ResAnnounceSpace, error) { - req, err := prm.buildRequest(c) - if err != nil { - return nil, err - } - - if err := signature.SignServiceMessage(&c.prm.Key, req); err != nil { - return nil, fmt.Errorf("sign request: %w", err) - } - - resp, err := rpcapi.AnnounceUsedSpace(&c.c, req, client.WithContext(ctx)) - if err != nil { - return nil, err - } - - var res ResAnnounceSpace - res.st, err = c.processResponse(resp) - return &res, err -} diff --git a/container/size.go b/container/size.go deleted file mode 100644 index 64220ed..0000000 --- a/container/size.go +++ /dev/null @@ -1,104 +0,0 @@ -package container - -import ( - "errors" - "fmt" - - "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container" - "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" - cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" -) - -// SizeEstimation groups information about estimation of the size of the data -// stored in the FrostFS container. -// -// SizeEstimation is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container.UsedSpaceAnnouncement -// message. See ReadFromV2 / WriteToV2 methods. -type SizeEstimation struct { - m container.UsedSpaceAnnouncement -} - -// ReadFromV2 reads SizeEstimation from the container.UsedSpaceAnnouncement message. -// Checks if the message conforms to FrostFS API V2 protocol. -// -// See also WriteToV2. -func (x *SizeEstimation) ReadFromV2(m container.UsedSpaceAnnouncement) error { - cnrV2 := m.GetContainerID() - if cnrV2 == nil { - return errors.New("missing container") - } - - var cnr cid.ID - - err := cnr.ReadFromV2(*cnrV2) - if err != nil { - return fmt.Errorf("invalid container: %w", err) - } - - x.m = m - - return nil -} - -// WriteToV2 writes SizeEstimation into the container.UsedSpaceAnnouncement message. -// The message MUST NOT be nil. -// -// See also ReadFromV2. -func (x SizeEstimation) WriteToV2(m *container.UsedSpaceAnnouncement) { - *m = x.m -} - -// SetEpoch sets epoch when estimation of the container data size was calculated. -// -// See also Epoch. -func (x *SizeEstimation) SetEpoch(epoch uint64) { - x.m.SetEpoch(epoch) -} - -// Epoch return epoch set using SetEpoch. -// -// Zero SizeEstimation represents estimation in zero epoch. -func (x SizeEstimation) Epoch() uint64 { - return x.m.GetEpoch() -} - -// SetContainer specifies the container for which the amount of data is estimated. -// Required by the FrostFS API protocol. -// -// See also Container. -func (x *SizeEstimation) SetContainer(cnr cid.ID) { - var cidV2 refs.ContainerID - cnr.WriteToV2(&cidV2) - - x.m.SetContainerID(&cidV2) -} - -// Container returns container set using SetContainer. -// -// Zero SizeEstimation is not bound to any container (returns zero) which is -// incorrect according to FrostFS API protocol. -func (x SizeEstimation) Container() (res cid.ID) { - m := x.m.GetContainerID() - if m != nil { - err := res.ReadFromV2(*m) - if err != nil { - panic(fmt.Errorf("unexpected error from cid.ID.ReadFromV2: %w", err)) - } - } - - return -} - -// SetValue sets estimated amount of data (in bytes) in the specified container. -// -// See also Value. -func (x *SizeEstimation) SetValue(value uint64) { - x.m.SetUsedSpace(value) -} - -// Value returns data size estimation set using SetValue. -// -// Zero SizeEstimation has zero value. -func (x SizeEstimation) Value() uint64 { - return x.m.GetUsedSpace() -} diff --git a/container/size_test.go b/container/size_test.go deleted file mode 100644 index 77fed4d..0000000 --- a/container/size_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package container_test - -import ( - "crypto/sha256" - "testing" - - v2container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container" - "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" - "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container" - cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" - cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test" - "github.com/stretchr/testify/require" -) - -func TestSizeEstimation_Epoch(t *testing.T) { - var val container.SizeEstimation - - require.Zero(t, val.Epoch()) - - const epoch = 123 - - val.SetEpoch(epoch) - require.EqualValues(t, epoch, val.Epoch()) - - var msg v2container.UsedSpaceAnnouncement - val.WriteToV2(&msg) - - require.EqualValues(t, epoch, msg.GetEpoch()) -} - -func TestSizeEstimation_Container(t *testing.T) { - var val container.SizeEstimation - - require.Zero(t, val.Container()) - - cnr := cidtest.ID() - - val.SetContainer(cnr) - require.True(t, val.Container().Equals(cnr)) - - var msg v2container.UsedSpaceAnnouncement - val.WriteToV2(&msg) - - var msgCnr refs.ContainerID - cnr.WriteToV2(&msgCnr) - - require.Equal(t, &msgCnr, msg.GetContainerID()) -} - -func TestSizeEstimation_Value(t *testing.T) { - var val container.SizeEstimation - - require.Zero(t, val.Value()) - - const value = 876 - - val.SetValue(value) - require.EqualValues(t, value, val.Value()) - - var msg v2container.UsedSpaceAnnouncement - val.WriteToV2(&msg) - - require.EqualValues(t, value, msg.GetUsedSpace()) -} - -func TestSizeEstimation_ReadFromV2(t *testing.T) { - const epoch = 654 - const value = 903 - var cnrMsg refs.ContainerID - - var msg v2container.UsedSpaceAnnouncement - - var val container.SizeEstimation - - require.Error(t, val.ReadFromV2(msg)) - - msg.SetContainerID(&cnrMsg) - - require.Error(t, val.ReadFromV2(msg)) - - cnrMsg.SetValue(make([]byte, sha256.Size)) - - var cnr cid.ID - require.NoError(t, cnr.ReadFromV2(cnrMsg)) - - msg.SetEpoch(epoch) - msg.SetUsedSpace(value) - - require.NoError(t, val.ReadFromV2(msg)) - - require.EqualValues(t, epoch, val.Epoch()) - require.EqualValues(t, value, val.Value()) - require.EqualValues(t, cnr, val.Container()) -} diff --git a/container/test/generate.go b/container/test/generate.go index 7ac0c2a..c242369 100644 --- a/container/test/generate.go +++ b/container/test/generate.go @@ -5,7 +5,6 @@ import ( "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl" - cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test" netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test" usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test" ) @@ -23,15 +22,6 @@ func Container() (x container.Container) { return x } -// SizeEstimation returns random container.SizeEstimation. -func SizeEstimation() (x container.SizeEstimation) { - x.SetContainer(cidtest.ID()) - x.SetEpoch(rand.Uint64()) - x.SetValue(rand.Uint64()) - - return x -} - // BasicACL returns random acl.Basic. func BasicACL() (x acl.Basic) { x.FromBits(rand.Uint32()) diff --git a/go.mod b/go.mod index b4dcb85..a481fb2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.frostfs.info/TrueCloudLab/frostfs-sdk-go go 1.21 require ( - git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240530152826-2f6d3209e1d3 + git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240726072425-3dfa2f4fd65e git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240621131249-49e5270f673e git.frostfs.info/TrueCloudLab/hrw v1.2.1 git.frostfs.info/TrueCloudLab/tzhash v1.8.0 diff --git a/go.sum b/go.sum index dff6ec8..a23b405 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240530152826-2f6d3209e1d3 h1:H5GvrVlowIMWfzqQkhY0p0myooJxQ1sMRVSFfXawwWg= -git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240530152826-2f6d3209e1d3/go.mod h1:OBDSr+DqV1z4VDouoX3YMleNc4DPBVBWTG3WDT2PK1o= +git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240726072425-3dfa2f4fd65e h1:gEWT+70E/RvGkxtSv+PlyUN2vtJVymhQa1mypvrXukM= +git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240726072425-3dfa2f4fd65e/go.mod h1:OBDSr+DqV1z4VDouoX3YMleNc4DPBVBWTG3WDT2PK1o= git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240621131249-49e5270f673e h1:kcBqZBiFIUBATUqEuvVigtkJJWQ2Gug/eYXn967o3M4= git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240621131249-49e5270f673e/go.mod h1:F/fe1OoIDKr5Bz99q4sriuHDuf3aZefZy9ZsCqEtgxc= git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 h1:FxqFDhQYYgpe41qsIHVOcdzSVCB8JNSfPG7Uk4r2oSk= diff --git a/pool/pool.go b/pool/pool.go index 2f9a651..502833d 100644 --- a/pool/pool.go +++ b/pool/pool.go @@ -52,8 +52,6 @@ type client interface { containerDelete(context.Context, PrmContainerDelete) error // see clientWrapper.containerEACL. containerEACL(context.Context, PrmContainerEACL) (eacl.Table, error) - // see clientWrapper.containerSetEACL. - containerSetEACL(context.Context, PrmContainerSetEACL) error // see clientWrapper.apeManagerAddChain. apeManagerAddChain(context.Context, PrmAddAPEChain) error // see clientWrapper.apeManagerRemoveChain. @@ -612,51 +610,6 @@ func (c *clientWrapper) containerEACL(ctx context.Context, prm PrmContainerEACL) return res.Table(), nil } -// containerSetEACL invokes sdkClient.ContainerSetEACL parse response status to error. -// It also waits for the EACL to appear on the network. -func (c *clientWrapper) containerSetEACL(ctx context.Context, prm PrmContainerSetEACL) error { - cl, err := c.getClient() - if err != nil { - return err - } - - cliPrm := sdkClient.PrmContainerSetEACL{ - Table: &prm.Table, - Session: prm.Session, - } - - start := time.Now() - res, err := cl.ContainerSetEACL(ctx, cliPrm) - c.incRequests(time.Since(start), methodContainerSetEACL) - var st apistatus.Status - if res != nil { - st = res.Status() - } - if err = c.handleError(ctx, st, err); err != nil { - return fmt.Errorf("set eacl on client: %w", err) - } - - if prm.WaitParams == nil { - prm.WaitParams = defaultWaitParams() - } - if err := prm.WaitParams.CheckValidity(); err != nil { - return fmt.Errorf("invalid wait parameters: %w", err) - } - - cnrID, _ := prm.Table.CID() - eaclPrm := PrmContainerEACL{ - ContainerID: cnrID, - Session: prm.Session, - } - - err = waitForEACLPresence(ctx, c, eaclPrm, &prm.Table, prm.WaitParams) - if err = c.handleError(ctx, nil, err); err != nil { - return fmt.Errorf("wait eacl presence on client: %w", err) - } - - return nil -} - // apeManagerAddChain invokes sdkClient.APEManagerAddChain and parse response status to error. func (c *clientWrapper) apeManagerAddChain(ctx context.Context, prm PrmAddAPEChain) error { cl, err := c.getClient() @@ -2835,28 +2788,6 @@ func (p *Pool) GetEACL(ctx context.Context, prm PrmContainerEACL) (eacl.Table, e return eaclResult, nil } -// SetEACL sends request to update eACL table of the FrostFS container and waits for the operation to complete. -// -// Waiting parameters can be specified using SetWaitParams. If not called, defaults are used: -// -// polling interval: 5s -// waiting timeout: 120s -// -// Success can be verified by reading by identifier (see GetEACL). -func (p *Pool) SetEACL(ctx context.Context, prm PrmContainerSetEACL) error { - cp, err := p.connection() - if err != nil { - return err - } - - err = cp.containerSetEACL(ctx, prm) - if err != nil { - return fmt.Errorf("set EACL via client '%s': %w", cp.address(), err) - } - - return nil -} - // AddAPEChain sends a request to set APE chain rules for a target (basically, for a container). func (p *Pool) AddAPEChain(ctx context.Context, prm PrmAddAPEChain) error { cp, err := p.connection() @@ -2955,17 +2886,6 @@ func waitForContainerPresence(ctx context.Context, cli client, prm PrmContainerG }) } -// waitForEACLPresence waits until the container eacl is applied on the FrostFS network. -func waitForEACLPresence(ctx context.Context, cli client, prm PrmContainerEACL, table *eacl.Table, waitParams *WaitParams) error { - return waitFor(ctx, waitParams, func(ctx context.Context) bool { - eaclTable, err := cli.containerEACL(ctx, prm) - if err == nil { - return eacl.EqualTables(*table, eaclTable) - } - return false - }) -} - // waitForContainerRemoved waits until the container is removed from the FrostFS network. func waitForContainerRemoved(ctx context.Context, cli client, prm PrmContainerGet, waitParams *WaitParams) error { return waitFor(ctx, waitParams, func(ctx context.Context) bool {