4ff9c00de3
[ #4 ] Rename NeoFS mentions in comments and method names
...
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2022-12-30 13:40:50 +03:00
Denis Kirillov
8c0c7789ca
[ #365 ] pool: Add request callback
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2022-12-29 16:34:13 +03:00
Pavel Karpy
4c779423f5
Move to frostfs-sdk-go
...
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2022-12-14 09:59:29 +03:00
Denis Kirillov
b4b07a3c4e
[ #364 ] pool: Adopt client stream timeout param
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-11-15 17:08:20 +03:00
Denis Kirillov
d047289182
[ #360 ] object: Add new package relations
...
Package relations provides feature to process inner object structure.
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-11-14 17:46:17 +03:00
Denis Kirillov
1cacf472a3
[ #360 ] pool: Fix removing virtual object
...
Include phy objects in session token scope
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-11-14 17:46:17 +03:00
Denis Kirillov
e35f0df1ca
[ #358 ] pool: Make ErrPoolClientUnhealthy unexported
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-11-09 10:22:33 +03:00
Denis Kirillov
5f9d846fb4
[ #358 ] pool: Don't init session with dead node
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-11-09 10:22:33 +03:00
Denis Kirillov
2eefdab0e4
[ #358 ] pool: Start even if not all node healthy
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-11-09 10:22:33 +03:00
Leonard Lyubich
8c682641bf
[ #343 ] pool: Provide dial context to clients
...
After recent changes `client.Client` accepts dial context. There is a
need to forward the context passed into `Pool.Dial` to the underlying
`Client` instances.
Define type aliases of different client constructors: context-based and
non-context. Use context-based constructor in `Pool`. Pass `ctx`
parameter of `Pool.Dial` method to the client builder.
Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
2022-10-07 13:24:02 +03:00
Leonard Lyubich
1325b4f272
[ #336 ] session: Support group object sessions
...
Rename `LimitByObject` method of the `session.Object` type to
`LimitByObjects` and make it to accept variadic parameter.
Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
2022-10-05 13:39:51 +04:00
Evgenii Stratonikov
4662d39886
[ #315 ] client/status: Add NodeUnderMaintenance status
...
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2022-09-19 16:49:27 +04:00
Evgenii Stratonikov
d6d6a41f5d
[ #323 ] client: Refactor object.Put
...
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2022-08-26 17:34:27 +03:00
Evgenii Stratonikov
724d30db1a
[ #323 ] client: Refactor object.Get
...
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2022-08-26 17:34:27 +03:00
Evgenii Stratonikov
1f593d0fb2
[ #323 ] client: Refactor object.GetRange
...
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2022-08-26 17:34:27 +03:00
Evgenii Stratonikov
6a43accf96
[ #323 ] client: Refactor object.Search
...
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2022-08-26 17:34:27 +03:00
Evgenii Stratonikov
84888854ab
[ #322 ] *: Go fmt -s
...
go1.19 rewrites comments to proper render them in docs.
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2022-08-24 18:58:59 +03:00
Leonard Lyubich
737e690482
[ #299 ] pool: Do not use pointers to the resulting values
...
In previous implementation `pool` package provided access to resulting
values as pointers to them. This caused clients to handle nil
cases even when the field presence in the response is required.
Avoid returning pointers to values in result getters. This also reduces
reference counter load and allows values from `client.Client` to be
forwarded directly without additional assignment.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-08-16 15:31:57 +04:00
Leonard Lyubich
4e31b4f231
[ #299 ] client: Do not use pointers to required response fields
...
In previous implementation `client` package provided access to nested
response fields as pointers to them. This caused clients to handle nil
cases even when the field presence in the response is required.
Avoid returning pointers to required fields in response getters. This
also reduces reference counter load and allows fields to be decoded
directly without additional assignment.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-08-08 12:55:25 +03:00
Denis Kirillov
30bf79f075
[ #302 ] client: Adopt SetCopiesNumber
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-08-03 15:22:13 +03:00
Denis Kirillov
90255e9efa
[ #291 ] pool: Use more robust way to init methods
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-26 21:47:06 +03:00
Denis Kirillov
828cfdc5bf
[ #291 ] pool: Improve docs
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-26 21:47:06 +03:00
Denis Kirillov
f4ac75423c
[ #283 ] pool: Store methods status in slice
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
b4f4ee4f79
[ #283 ] pool: Compute avg time for every method
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
54145916a9
[ #283 ] pool: Change batch of atomics to mutex
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
0d54757545
[ #283 ] pool: Add res nil check
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
58fe1768cc
[ #283 ] pool: Fix incErrorRate
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
0b8c53ebc9
[ #283 ] pool: Add number of requests to statistic
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
1b30d228da
[ #283 ] pool: Expose statistic
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
423804de84
[ #283 ] pool: Add latency calculating
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
99e185690e
[ #283 ] pool: Add error threshold
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
9d3a1835d1
[ #283 ] pool: Drop gomock
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Denis Kirillov
e6cb5f2ee1
[ #283 ] pool: Add counter for errors
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-07-22 15:57:37 +03:00
Pavel Karpy
c6fee6d01a
[ #240 ] pool: Add SyncContainerWithNetwork
...
It is a helper function that uses a `Pool` to fetch network information and
apply it to the container (change the container if it does not fit the
network). Currently, only applies the homomorphic hashing parameter.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
2022-07-05 15:37:49 +03:00
Leonard Lyubich
70845147f6
[ #225 ] container: Refactor and document package functionality
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-07-04 11:21:16 +03:00
Angira Kekteeva
86a447bc80
[ #288 ] pool: Fix lost err in fmt.Errorf
...
Signed-off-by: Angira Kekteeva <kira@nspcc.ru>
2022-07-01 15:09:26 +03:00
Leonard Lyubich
1e1139f305
[ #278 ] pool: Avoid using strings.Contains
for error assertion
...
`client` package now provides functions for error checking.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-06-28 09:06:13 +03:00
Leonard Lyubich
721df386c5
[ #276 ] container: Remove session token and signature from Container/eACL
...
Session token and signature isn't presented in `Container` and
`EACLTable` messages of NeoFS API V2 protocol. These entities are needed
for access control and doesn't carry payload of these messages.
Remove `SetSessionToken` / `SessionToken` methods of
`container.Container` and `eacl.Table` types. Provide methods to specify
these components in corresponding `Client` operations.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-06-21 20:03:07 +03:00
Leonard Lyubich
ca523f1ff1
[ #227 ] netmap: Refactor and document package functionality
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-06-15 20:50:32 +03:00
Denis Kirillov
3953c2166e
[ #255 ] Create session token using arbitrary key
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-05-30 20:09:43 +03:00
Leonard Lyubich
f0a5eb6dbc
[ #251 ] object/address: Refactor and document package functionality
...
Merge `address` package into `oid` one. Bring `session.Object`
implementation into conformity with the NeoFS API protocol.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-05-27 12:41:35 +03:00
Leonard Lyubich
4cbbbdd3e2
[ #197 ] pool: Change function signature
...
Make `createSessionTokenForDuration` to accept a pointer to
`session.Object` and write the response on session creation request
through the pointer. Rename function to `initSessionForDuration`. As a
consequence, problem in `openDefaultSession` with uncached sessions is
fixed.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-04-27 11:09:29 +03:00
Leonard Lyubich
f0134ef26e
[ #197 ] pool: Remove no longer needed test func
...
`TestCopySessionTokenWithoutSignatureAndContext` was based on already
removed function.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-04-27 11:09:29 +03:00
Leonard Lyubich
e468f409d7
[ #197 ] pool: Remove unused function parameter
...
`owner.ID` parameter of `createSessionTokenForDuration` function is no
longer used since session owner is set automatically during the sign
operation. As a consequence, remove `Pool.sessionOwner` field and its
getter.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-04-27 11:09:29 +03:00
Leonard Lyubich
552c7875bf
[ #197 ] session: Refactor and document the package
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-04-27 11:09:29 +03:00
Leonard Lyubich
1ed426b8a6
[ #199 ] owner: Rename to user
, refactor and doc
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-04-19 18:44:02 +03:00
Leonard Lyubich
ea043f4ca3
[ #190 ] Refactor cryptographic functionality
...
Remove `signature` and `util/signature` packages. Re-implement their
functionality in new `crypto` package. Generalize the approach of
digital signature computation and verification by adding `Signer` and
`PublicKey` primitives similar to standard `crypto` package. Support
already exising in protocol signature schemes.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-04-19 12:55:11 +03:00
Pavel Karpy
1186f2f703
[ #170 ] oid, cid: Add marshal format checks
...
Also add checking presence of the `oid`, `cid` fields via `set` flag.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
2022-04-13 17:32:25 +03:00
Alex Vanin
27cd721422
[ #170 ] bearer: Add docs, refactor
...
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
2022-04-13 11:24:15 +03:00
Denis Kirillov
3e75660802
[ #205 ] pool: fix using default key for requests
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-12 18:12:50 +03:00
Denis Kirillov
53e064e556
[ #206 ] pool: fix waitForContainerRemoved
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-12 18:12:39 +03:00
Denis Kirillov
385f1b10f9
[ #203 ] pool: fix PrmContainerDelete
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-12 14:26:08 +03:00
Denis Kirillov
1e8aa6a99f
[ #85 ] pool: update tests
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-12 10:30:28 +03:00
Denis Kirillov
97c8274dc0
[ #85 ] pool: use non-pointer client inside wrapper
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-12 10:30:28 +03:00
Denis Kirillov
9e8e12f6ae
[ #85 ] pool: make client interface methods private
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-12 10:30:28 +03:00
Denis Kirillov
aa6a4950d5
[ #85 ] pool: fix skipped tests
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-12 10:30:28 +03:00
Denis Kirillov
e56eef495d
[ #85 ] pool: refactor client interface
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-12 10:30:28 +03:00
Denis Kirillov
e50e6d2828
[ #137 ] pool: simplify session creation
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 13:33:16 +03:00
Denis Kirillov
df0573d521
[ #137 ] pool: drop sessionTokenThreshold
...
Description
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 13:33:16 +03:00
Denis Kirillov
c4adb03f8e
[ #137 ] pool: drop retry for object operations
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 13:33:16 +03:00
Denis Kirillov
fcfae4a249
[ #137 ] Use callback response to update epoch
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 13:33:16 +03:00
Denis Kirillov
9814748958
[ #137 ] pool: fix tests
...
Description
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 13:33:16 +03:00
Denis Kirillov
7df00fb0eb
[ #137 ] Add exp to ResSessionCreate
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 13:33:16 +03:00
Denis Kirillov
11a25bb413
[ #137 ] Expire session tokens locally
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 13:33:16 +03:00
Denis Kirillov
b8d2158acd
[ #180 ] eacl: make equal methods functions
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 09:50:02 +03:00
Denis Kirillov
a709cf5444
[ #180 ] pool: make some operations synchronous
...
Operations: PutContainer, DeleteContainer, SetEACL
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 09:50:02 +03:00
Denis Kirillov
0dbea5452a
[ #180 ] pool: add WaitForContainerRemoved
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 09:50:02 +03:00
Denis Kirillov
47345a33da
[ #180 ] pool: add WaitForEACLPresence
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-07 09:50:02 +03:00
Alex Vanin
2104945f9e
[ #193 ] pool: Return copy of session token in cache
...
To avoid side effects after token re-sign.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
2022-04-06 12:06:24 +03:00
Alex Vanin
f38a24e8b5
[ #193 ] pool: Add test to check side effects in token cache
...
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
2022-04-06 12:06:24 +03:00
Denis Kirillov
e0281c3b34
[ #191 ] pool: use bearer token
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-04-06 10:27:58 +04:00
Denis Kirillov
030bbce2cf
[ #165 ] pool: drop prmCommon from container params
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Denis Kirillov
59b49dd7e6
[ #165 ] pool: update WaitForContainerPresence
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Denis Kirillov
191d85e607
[ #165 ] pool: change exported fields to setters
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Denis Kirillov
9be9697856
[ #165 ] pool: make client interface unexported
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Denis Kirillov
52548fe176
[ #165 ] pool: add docs
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Denis Kirillov
7811d8eefc
[ #165 ] pool: distinguish init step and run
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Denis Kirillov
d03523a3bc
[ #165 ] pool: replace options with parameters
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Denis Kirillov
ec5c223f29
[ #165 ] pool: make private inner structs
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Denis Kirillov
f5cabe26cb
[ #165 ] pool: drop builder
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-21 12:41:08 +03:00
Alex Vanin
b91e25f782
[ #168 ] pool: Adopt replacement of pointer slices with struct slices
...
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
2022-03-15 16:59:59 +03:00
Leonard Lyubich
b81122740a
[ #164 ] pool: Make pool.Pool
a struct
...
Connection pool package should not define `Pool` type as an interface
since it provides single particular implementation.
Make `pool.Pool` type a struct instead of interface. Also remove
`Object`, `Container` and `Accounting` interfaces.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-03-10 15:02:10 +03:00
Leonard Lyubich
22dad0573d
[ #164 ] client: Refactor and document package functionality
...
Get rid of `Option` pattern. Define `Init`, `Dial` and `Close` methods
for the corresponding stages of use.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-03-10 15:02:10 +03:00
Denis Kirillov
61f9c3392b
[ #159 ] Add object context to session tokens
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-03-03 15:08:47 +03:00
Evgenii Stratonikov
07817fb403
[ #148 ] client: Allow to iterate over search results
...
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2022-02-28 10:19:35 +03:00
Evgenii Stratonikov
fa670ab57a
*: Fix linter warnings
...
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2022-02-24 18:49:55 +03:00
Leonard Lyubich
29c057272c
[ #147 ] pool: Limit buffer length by 3MB in PutObject
...
In previous implementation we wrote up to 4KB payload chunk per-call.
This led to sending a large number of messages with a large
amount of payload.
Increase buffer length limit to 3MB.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-22 09:09:22 +03:00
Denis Kirillov
5386694a1a
[ #142 ] Drop retry for container operations
...
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
2022-02-21 16:48:28 +03:00
Leonard Lyubich
66bc59da5c
[ #146 ] pool: Set private key in object HEAD/DELETE
...
Use call private key parameterized in `HeadObject` / `DeleteObject`
methods of `Pool` as corresponding key for `ObjectHead` / `ObjectDelete`
methods of `Client`.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-21 15:21:37 +03:00
Leonard Lyubich
69ffface78
[ #131 ] client: Name all methods and types the same way
...
Inherit name format of object operations in all other ones.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
998bae3f1c
[ #131 ] pool: Sign session token before caching in newPool
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
37f0cde78d
[ #131 ] client: Remove SetEACLPrm.SetSessionToken
...
From now session token for `SetEACL` operation should be written into
eACL table structure (similar to `PutContainer`).
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
d90fe8fbab
[ #131 ] client: Remove no longer needed code
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
1130c1f5a6
[ #131 ] pool: Limit session lifetime in openDefaultSession
method
...
Call `createSessionTokenForDuration` function for session opening in
`pool.openDefaultSession` method in order to limit session lifetime
according to pool configuration (`SessionExpirationDuration`).
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
28b49419ab
[ #131 ] client: Re-implement Object Delete and Hash methods
...
Also remove unused methods of `pool.Client` and `pool.Pool`.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
fb3501752d
[ #131 ] client: Re-implement Object.Search method
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
ff4febff6f
[ #131 ] client: Re-implement Object.Range method
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
7de81cd585
[ #131 ] pool: Fix ineffectual error assignments
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
caf31a928c
[ #131 ] client: Re-implement Object.Head method
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00
Leonard Lyubich
8d734d1020
[ #131 ] client: Add ID suffix to ResObjectPut.ReadStoredObject
...
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2022-02-18 17:01:08 +03:00