Compare commits

...

No commits in common. "empty" and "master" have entirely different histories.

227 changed files with 28985 additions and 2 deletions

View file

@ -0,0 +1,21 @@
name: DCO action
on: [pull_request]
jobs:
dco:
name: DCO
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: '1.23'
- name: Run commit format checker
uses: https://git.frostfs.info/TrueCloudLab/dco-go@v3
with:
from: 'origin/${{ github.event.pull_request.base.ref }}'

View file

@ -0,0 +1,54 @@
name: Tests and linters
on: [pull_request]
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.23'
cache: true
- name: golangci-lint
uses: https://github.com/golangci/golangci-lint-action@v3
with:
version: latest
tests:
name: Tests
runs-on: ubuntu-latest
strategy:
matrix:
go_versions: [ '1.22', '1.23' ]
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '${{ matrix.go_versions }}'
cache: true
- name: Run tests
run: make test
tests-race:
name: Tests with -race
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.23'
cache: true
- name: Run tests
run: go test ./... -count=1 -race

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
/**/*.pb.go -diff -merge
/**/*.pb.go linguist-generated=true

1
.github/CODEOWNERS vendored Normal file
View file

@ -0,0 +1 @@
* @TrueCloudLab/storage-core @TrueCloudLab/storage-services @TrueCloudLab/committers

45
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,45 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: community, triage, bug
assignees: ''
---
<!--- Provide a general summary of the issue in the Title above -->
## Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->
## Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
## Possible Solution
<!--- Not obligatory -->
<!--- If no reason/fix/additions for the bug can be suggested, -->
<!--- uncomment the following phrase: -->
<!--- No fix can be suggested by a QA engineer. Further solutions shall be up to developers. -->
## Steps to Reproduce (for bugs)
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. -->
1.
## Context
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
## Regression
<!-- Is this issue a regression? (Yes / No) -->
<!-- If Yes, optionally please include version or commit id or PR# that caused this regression, if you have these details. -->
## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Version used:
* Server setup and configuration:
* Operating System and version (`uname -a`):

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1 @@
blank_issues_enabled: false

View file

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: community, triage
assignees: ''
---
## Is your feature request related to a problem? Please describe.
<!--- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
## Describe the solution you'd like
<!--- A clear and concise description of what you want to happen. -->
## Describe alternatives you've considered
<!--- A clear and concise description of any alternative solutions or features you've considered. -->
## Additional context
<!--- Add any other context or screenshots about the feature request here. -->

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.idea
bin
temp

85
.golangci.yml Normal file
View file

@ -0,0 +1,85 @@
# This file contains all available configuration options
# with their default values.
# options for analysis running
run:
# timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 10m
# include test files or not, default is true
tests: false
# output configuration options
output:
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
formats:
- format: tab
# all available settings of specific linters
linters-settings:
exhaustive:
# indicates that switch statements are to be considered exhaustive if a
# 'default' case is present, even if all enum members aren't listed in the
# switch
default-signifies-exhaustive: true
govet:
# report about shadowed variables
check-shadowing: false
funlen:
lines: 80 # default 60
statements: 60 # default 40
gocognit:
min-complexity: 40 # default 30
linters:
enable:
# mandatory linters
- govet
- revive
# some default golangci-lint linters
- errcheck
- gosimple
- godot
- ineffassign
- staticcheck
- typecheck
- unused
# extra linters
- bidichk
- durationcheck
- exhaustive
- copyloopvar
- gofmt
- goimports
- misspell
- predeclared
- reassign
- whitespace
- containedctx
- funlen
- gocognit
- contextcheck
disable-all: true
fast: false
issues:
exclude-files:
- (^|.*/)grpc/(.*)
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- path: v2 # ignore stutters in universal structures due to protobuf compatibility
linters:
- golint
text: "stutters;"
- path: grpc # ignore case errors in grpc setters due to protobuf compatibility
linters:
- golint
text: "should be"
- linters: # ignore SA6002 since we use pool of []byte, however we can switch to *bytes.Buffer
- staticcheck
text: "SA6002:"

42
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,42 @@
ci:
autofix_prs: false
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: check-merge-conflict
- id: check-json
- id: check-xml
- id: check-yaml
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: end-of-file-fixer
exclude: ".key$"
- repo: local
hooks:
- id: gofumpt
name: gofumpt
entry: make fumpt
pass_filenames: false
types: [go]
language: system
- repo: local
hooks:
- id: go-unit-tests
name: go unit tests
entry: make test GOFLAGS=''
pass_filenames: false
types: [go]
language: system
- repo: https://github.com/golangci/golangci-lint
rev: v1.60.3
hooks:
- id: golangci-lint

50
CHANGELOG.md Normal file
View file

@ -0,0 +1,50 @@
# Changelog
## [Unreleased]
### Added
### Fixed
### Changed
### Removed
### Updated
## [2.16.0] - 2023-09-14 - Academy of Sciences Glacier
### Added
- Add impersonate flag to bearer token (#17)
- `NOT` and `UNIQUE` keywords to the placement policy (#26)
- `PutSingle` RPC (#45)
### Fixed
### Changed
- `StableSize()` is optimized and no does no allocations (#49)
- Marshaling code now uses `protowire` package (#50)
### Removed
- Reputation system (#21)
### Updated
- `github.com/stretchr/testify` to `v1.8.3`
- `go.opentelemetry.io/otel` to `v1.15.1`
- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` to `v1.15.1`
- `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` to `v1.15.1`
- `go.opentelemetry.io/otel/sdk` to `v1.15.1`
- `go.opentelemetry.io/otel/trace` to `v1.15.1`
- `golang.org/x/sync` to `v0.2.0`
- `google.golang.org/grpc` to `v1.55.0`
- `google.golang.org/protobuf` to `v1.30.0`
## 2.15.0 - 2023-04-11
### Added
- Basic tracing support (#12)
- Optimize signature checking (#3)
Initial public release.
## Older versions
This project is a fork of [NeoFS](https://github.com/nspcc-dev/neofs-api-go) from version v2.14.0.
To see CHANGELOG for older versions, refer to https://github.com/nspcc-dev/neofs-api-go/blob/master/CHANGELOG.md.
[Unreleased]: https://git.frostfs.info/TrueCloudLab/frostfs-api-go/compare/v2.16.0...master

152
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,152 @@
# Contribution guide
First, thank you for contributing! We love and encourage pull requests from
everyone. Please follow the guidelines:
- Check the open [issues](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/issues) and
[pull requests](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/pulls) for existing
discussions.
- Open an issue first, to discuss a new feature or enhancement.
- Open a pull request, and reference the relevant issue(s).
- Make sure your commits are logically separated and have good comments
explaining the details of your change.
- After receiving feedback, amend your commits or add new ones as
appropriate.
- **Have fun!**
## Development Workflow
Start by forking the `frostfs-api-go` repository, make changes in a branch and then
send a pull request. We encourage pull requests to discuss code changes. Here
are the steps in details:
### Set up your GitHub Repository
Fork [FrostFS node upstream](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/fork) source
repository to your own personal repository. Copy the URL of your fork (you will
need it for the `git clone` command below).
```sh
$ git clone https://git.frostfs.info/TrueCloudLab/frostfs-api-go
```
### Set up git remote as ``upstream``
```sh
$ cd frostfs-api-go
$ git remote add upstream https://git.frostfs.info/TrueCloudLab/frostfs-api-go
$ git fetch upstream
$ git merge upstream/master
...
```
### Create your feature branch
Before making code changes, make sure you create a separate branch for these
changes. Maybe you will find it convenient to name branch in
`<type>/<Issue>-<changes_topic>` format.
```
$ git checkout -b feature/123-something_awesome
```
### Test your changes
After your code changes, make sure
- To add test cases for the new code.
- To run `make lint`
- To squash your commits into a single commit or a series of logically separated
commits run `git rebase -i`. It's okay to force update your pull request.
### Commit changes
After verification, commit your changes. This is a [great
post](https://chris.beams.io/posts/git-commit/) on how to write useful commit
messages. Try following this template:
```
[#Issue] <component> Summary
Description
<Macros>
<Sign-Off>
```
```
$ git commit -am '[#123] Add some feature'
```
### Push to the branch
Push your locally committed changes to the remote origin (your fork)
```
$ git push origin feature/123-something_awesome
```
### Create a Pull Request
Pull requests can be created via GitHub. Refer to [this
document](https://help.github.com/articles/creating-a-pull-request/) for
detailed steps on how to create a pull request. After a Pull Request gets peer
reviewed and approved, it will be merged.
## DCO Sign off
All authors to the project retain copyright to their work. However, to ensure
that they are only submitting work that they have rights to, we are requiring
everyone to acknowledge this by signing their work.
Any copyright notices in this repository should specify the authors as "the
contributors".
To sign your work, just add a line like this at the end of your commit message:
```
Signed-off-by: Samii Sakisaka <samii@ivunojikan.co.jp>
```
This can easily be done with the `--signoff` option to `git commit`.
By doing this you state that you can certify the following (from [The Developer
Certificate of Origin](https://developercertificate.org/)):
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```

31
CREDITS.md Normal file
View file

@ -0,0 +1,31 @@
# Credits
FrostFS continues the development of NeoFS.
Initial NeoFS research and development (2018-2020) was done by
[NeoSPCC](https://nspcc.ru) team.
In alphabetical order:
- Alexey Vanin
- Anastasia Prasolova
- Anatoly Bogatyrev
- Evgeny Kulikov
- Evgeny Stratonikov
- Leonard Liubich
- Sergei Liubich
- Stanislav Bogatyrev
# Contributors
In chronological order:
- Pavel Korotkov
- Pavel Karpy
- Angira Kekteeva
# Special Thanks
For product development support:
- Fabian Wahle
- Neo Global Development

201
LICENSE Normal file
View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

111
Makefile Executable file
View file

@ -0,0 +1,111 @@
#!/usr/bin/make -f
SHELL = bash
VERSION ?= $(shell git describe --tags --match "v*" --abbrev=8 --dirty --always)
PROTOC_VERSION ?= 27.2
PROTOC_GEN_GO_VERSION ?= $(shell go list -f '{{.Version}}' -m google.golang.org/protobuf)
PROTOC_OS_VERSION=osx-x86_64
ifeq ($(shell uname), Linux)
PROTOC_OS_VERSION=linux-x86_64
endif
BIN = bin
PROTOBUF_DIR ?= $(abspath $(BIN))/protobuf
PROTOC_DIR ?= $(PROTOBUF_DIR)/protoc-v$(PROTOC_VERSION)
PROTOC_GEN_GO_DIR ?= $(PROTOBUF_DIR)/protoc-gen-go-$(PROTOC_GEN_GO_VERSION)
.PHONY: dep fmts fumpt imports protoc test lint version help $(BIN)/protogen protoc-test
# Pull go dependencies
dep:
@printf "⇒ Tidy requirements : "
CGO_ENABLED=0 \
go mod tidy -v && echo OK
@printf "⇒ Download requirements: "
CGO_ENABLED=0 \
go mod download && echo OK
@printf "⇒ Install test requirements: "
CGO_ENABLED=0 \
go test ./... && echo OK
# Run all code formatters
fmts: fumpt imports
# Reformat imports
imports:
@echo "⇒ Processing goimports check"
@for f in `find . -type f -name '*.go' -not -name '*.pb.go' -prune`; do \
goimports -w $$f; \
done
# Run gofumpt
fumpt:
@echo "⇒ Processing gofumpt check"
@gofumpt -l -w .
# Install protoc
protoc-install:
@rm -rf $(PROTOBUF_DIR)
@mkdir -p $(PROTOBUF_DIR)
@echo "⇒ Installing protoc... "
@wget -q -O $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip 'https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-$(PROTOC_OS_VERSION).zip'
@unzip -q -o $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip -d $(PROTOC_DIR)
@rm $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip
@echo "⇒ Installing protoc-gen-go..."
@GOBIN=$(PROTOC_GEN_GO_DIR) go install -v google.golang.org/protobuf/...@$(PROTOC_GEN_GO_VERSION)
# Regenerate code for proto files
protoc:
@if [ ! -d "$(PROTOC_DIR)" ] || [ ! -d "$(PROTOC_GEN_GO_DIR)" ]; then \
make protoc-install; \
fi
# Protoc generate
@for f in `find . -type f -name '*.proto' -not -path './bin/*' -not -path './util/proto/test/*'`; do \
echo "⇒ Processing $$f "; \
$(PROTOC_DIR)/bin/protoc \
--proto_path=.:$(PROTOC_DIR)/include:/usr/local/include \
--plugin=protoc-gen-go-frostfs=$(abspath ./bin/protogen) \
--go-frostfs_out=fuzz=true:. \
--go-frostfs_opt=paths=source_relative \
--go-grpc_opt=require_unimplemented_servers=false \
--go-grpc_out=. --go-grpc_opt=paths=source_relative $$f; \
done
$(BIN)/protogen:
@go build -v -trimpath \
-o $(BIN)/protogen \
./util/protogen
protoc-test: protoc $(BIN)/protogen
@$(PROTOC_DIR)/bin/protoc \
--go_out=. --go_opt=paths=source_relative \
--plugin=protoc-gen-go-frostfs=$(abspath $(BIN)/protogen) \
--go-frostfs_opt=Mutil/proto/test/test.proto=git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto/test/custom \
--go-frostfs_opt=module=git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 \
--go-frostfs_out=. --go-frostfs_opt=paths=import \
./util/proto/test/test.proto
# Run Unit Test with go test
test: GOFLAGS ?= "-count=1"
test:
@echo "⇒ Running go test"
@GOFLAGS="$(GOFLAGS)" go test ./...
# Run linters
lint:
@golangci-lint run
# Print version
version:
@echo $(VERSION)
# Show this help prompt
help:
@echo ' Usage:'
@echo ''
@echo ' make <target>'
@echo ''
@echo ' Targets:'
@echo ''
@awk '/^#/{ comment = substr($$0,3) } comment && /^[a-zA-Z][a-zA-Z0-9_-]+ ?:/{ print " ", $$1, comment }' $(MAKEFILE_LIST) | column -t -s ':' | grep -v 'IGNORE' | sort -u

View file

@ -1,3 +1,35 @@
# WIP area: this repo is just a fork!
<p align="center">
<img src="./.github/logo.svg" width="500px" alt="FrostFS">
</p>
<p align="center">
Low-level Golang API for <a href="https://frostfs.info">FrostFS</a>
</p>
Useful things may be published only in [other branches](../../../branches)
---
![Tests](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/badges/workflows/tests.yml/badge.svg)
[![Report](https://goreportcard.com/badge/git.frostfs.info/TrueCloudLab/frostfs-api-go)](https://goreportcard.com/report/git.frostfs.info/TrueCloudLab/frostfs-api-go)
[![Release](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/badges/release.svg)](https://git.frostfs.info/TrueCloudLab/frostfs-api-go)
# Overview
Go implementation of recent [FrostFS API](https://git.frostfs.info/TrueCloudLab/frostfs-api)
versions. For a more high-level SDK see [FrostFS SDK](https://git.frostfs.info/TrueCloudLab/frostfs-sdk-go).
## Frostfs-Api compatibility
|frostfs-api-go version|supported frostfs-api versions|
|:------------------:|:--------------------------:|
|v2.14.x|[v2.14.0](https://git.frostfs.info/TrueCloudLab/frostfs-api/releases/tag/v2.14.0)|
## Contributing
Feel free to contribute to this project after reading the [contributing
guidelines](CONTRIBUTING.md).
Before starting to work on a certain topic, create a new issue first, describing
the feature/topic you are going to implement.
## License
This project is licensed under the Apache 2.0 License -
see the [LICENSE](LICENSE) file for details

104
accounting/accounting.go Normal file
View file

@ -0,0 +1,104 @@
package accounting
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
)
type BalanceRequestBody struct {
ownerID *refs.OwnerID
}
type BalanceResponseBody struct {
bal *Decimal
}
type Decimal struct {
val int64
prec uint32
}
type BalanceRequest struct {
body *BalanceRequestBody
session.RequestHeaders
}
type BalanceResponse struct {
body *BalanceResponseBody
session.ResponseHeaders
}
func (b *BalanceRequestBody) GetOwnerID() *refs.OwnerID {
if b != nil {
return b.ownerID
}
return nil
}
func (b *BalanceRequestBody) SetOwnerID(v *refs.OwnerID) {
b.ownerID = v
}
func (b *BalanceRequest) GetBody() *BalanceRequestBody {
if b != nil {
return b.body
}
return nil
}
func (b *BalanceRequest) SetBody(v *BalanceRequestBody) {
b.body = v
}
func (d *Decimal) GetValue() int64 {
if d != nil {
return d.val
}
return 0
}
func (d *Decimal) SetValue(v int64) {
d.val = v
}
func (d *Decimal) GetPrecision() uint32 {
if d != nil {
return d.prec
}
return 0
}
func (d *Decimal) SetPrecision(v uint32) {
d.prec = v
}
func (br *BalanceResponseBody) GetBalance() *Decimal {
if br != nil {
return br.bal
}
return nil
}
func (br *BalanceResponseBody) SetBalance(v *Decimal) {
br.bal = v
}
func (br *BalanceResponse) GetBody() *BalanceResponseBody {
if br != nil {
return br.body
}
return nil
}
func (br *BalanceResponse) SetBody(v *BalanceResponseBody) {
br.body = v
}

178
accounting/convert.go Normal file
View file

@ -0,0 +1,178 @@
package accounting
import (
accounting "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
refsGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func (b *BalanceRequestBody) ToGRPCMessage() grpc.Message {
var m *accounting.BalanceRequest_Body
if b != nil {
m = new(accounting.BalanceRequest_Body)
m.SetOwnerId(b.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
}
return m
}
func (b *BalanceRequestBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*accounting.BalanceRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
ownerID := v.GetOwnerId()
if ownerID == nil {
b.ownerID = nil
} else {
if b.ownerID == nil {
b.ownerID = new(refs.OwnerID)
}
err = b.ownerID.FromGRPCMessage(ownerID)
}
return err
}
func (b *BalanceRequest) ToGRPCMessage() grpc.Message {
var m *accounting.BalanceRequest
if b != nil {
m = new(accounting.BalanceRequest)
m.SetBody(b.body.ToGRPCMessage().(*accounting.BalanceRequest_Body))
b.RequestHeaders.ToMessage(m)
}
return m
}
func (b *BalanceRequest) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*accounting.BalanceRequest)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
b.body = nil
} else {
if b.body == nil {
b.body = new(BalanceRequestBody)
}
err = b.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return b.RequestHeaders.FromMessage(v)
}
func (d *Decimal) ToGRPCMessage() grpc.Message {
var m *accounting.Decimal
if d != nil {
m = new(accounting.Decimal)
m.SetValue(d.val)
m.SetPrecision(d.prec)
}
return m
}
func (d *Decimal) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*accounting.Decimal)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
d.val = v.GetValue()
d.prec = v.GetPrecision()
return nil
}
func (br *BalanceResponseBody) ToGRPCMessage() grpc.Message {
var m *accounting.BalanceResponse_Body
if br != nil {
m = new(accounting.BalanceResponse_Body)
m.SetBalance(br.bal.ToGRPCMessage().(*accounting.Decimal))
}
return m
}
func (br *BalanceResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*accounting.BalanceResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
bal := v.GetBalance()
if bal == nil {
br.bal = nil
} else {
if br.bal == nil {
br.bal = new(Decimal)
}
err = br.bal.FromGRPCMessage(bal)
}
return err
}
func (br *BalanceResponse) ToGRPCMessage() grpc.Message {
var m *accounting.BalanceResponse
if br != nil {
m = new(accounting.BalanceResponse)
m.SetBody(br.body.ToGRPCMessage().(*accounting.BalanceResponse_Body))
br.ResponseHeaders.ToMessage(m)
}
return m
}
func (br *BalanceResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*accounting.BalanceResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
br.body = nil
} else {
if br.body == nil {
br.body = new(BalanceResponseBody)
}
err = br.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return br.ResponseHeaders.FromMessage(v)
}

BIN
accounting/grpc/service_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,45 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package accounting
func DoFuzzProtoBalanceRequest(data []byte) int {
msg := new(BalanceRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONBalanceRequest(data []byte) int {
msg := new(BalanceRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoBalanceResponse(data []byte) int {
msg := new(BalanceResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONBalanceResponse(data []byte) int {
msg := new(BalanceResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,31 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package accounting
import (
testing "testing"
)
func FuzzProtoBalanceRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoBalanceRequest(data)
})
}
func FuzzJSONBalanceRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONBalanceRequest(data)
})
}
func FuzzProtoBalanceResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoBalanceResponse(data)
})
}
func FuzzJSONBalanceResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONBalanceResponse(data)
})
}

BIN
accounting/grpc/service_grpc.pb.go generated Normal file

Binary file not shown.

BIN
accounting/grpc/types_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,26 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package accounting
func DoFuzzProtoDecimal(data []byte) int {
msg := new(Decimal)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONDecimal(data []byte) int {
msg := new(Decimal)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,21 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package accounting
import (
testing "testing"
)
func FuzzProtoDecimal(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoDecimal(data)
})
}
func FuzzJSONDecimal(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONDecimal(data)
})
}

14
accounting/json.go Normal file
View file

@ -0,0 +1,14 @@
package accounting
import (
accounting "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func (d *Decimal) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(d)
}
func (d *Decimal) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(d, data, new(accounting.Decimal))
}

104
accounting/marshal.go Normal file
View file

@ -0,0 +1,104 @@
package accounting
import (
accounting "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
protoutil "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto"
)
const (
decimalValueField = 1
decimalPrecisionField = 2
balanceReqBodyOwnerField = 1
balanceRespBodyDecimalField = 1
)
func (d *Decimal) StableMarshal(buf []byte) []byte {
if d == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, d.StableSize())
}
var offset int
offset += protoutil.Int64Marshal(decimalValueField, buf[offset:], d.val)
protoutil.UInt32Marshal(decimalPrecisionField, buf[offset:], d.prec)
return buf
}
func (d *Decimal) StableSize() (size int) {
if d == nil {
return 0
}
size += protoutil.Int64Size(decimalValueField, d.val)
size += protoutil.UInt32Size(decimalPrecisionField, d.prec)
return size
}
func (d *Decimal) Unmarshal(data []byte) error {
return message.Unmarshal(d, data, new(accounting.Decimal))
}
func (b *BalanceRequestBody) StableMarshal(buf []byte) []byte {
if b == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, b.StableSize())
}
protoutil.NestedStructureMarshal(balanceReqBodyOwnerField, buf, b.ownerID)
return buf
}
func (b *BalanceRequestBody) StableSize() (size int) {
if b == nil {
return 0
}
size = protoutil.NestedStructureSize(balanceReqBodyOwnerField, b.ownerID)
return size
}
func (b *BalanceRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(b, data, new(accounting.BalanceRequest_Body))
}
func (br *BalanceResponseBody) StableMarshal(buf []byte) []byte {
if br == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, br.StableSize())
}
protoutil.NestedStructureMarshal(balanceRespBodyDecimalField, buf, br.bal)
return buf
}
func (br *BalanceResponseBody) StableSize() (size int) {
if br == nil {
return 0
}
size = protoutil.NestedStructureSize(balanceRespBodyDecimalField, br.bal)
return size
}
func (br *BalanceResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(br, data, new(accounting.BalanceResponse_Body))
}

View file

@ -0,0 +1,19 @@
package accounting_test
import (
"testing"
accountingtest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting/test"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
messagetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message/test"
)
func TestMessage(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return accountingtest.GenerateDecimal(empty) },
func(empty bool) message.Message { return accountingtest.GenerateBalanceRequestBody(empty) },
func(empty bool) message.Message { return accountingtest.GenerateBalanceRequest(empty) },
func(empty bool) message.Message { return accountingtest.GenerateBalanceResponseBody(empty) },
func(empty bool) message.Message { return accountingtest.GenerateBalanceResponse(empty) },
)
}

View file

@ -0,0 +1,64 @@
package accountingtest
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting"
accountingtest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/test"
sessiontest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session/test"
)
func GenerateBalanceRequest(empty bool) *accounting.BalanceRequest {
m := new(accounting.BalanceRequest)
if !empty {
m.SetBody(GenerateBalanceRequestBody(false))
}
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateBalanceRequestBody(empty bool) *accounting.BalanceRequestBody {
m := new(accounting.BalanceRequestBody)
if !empty {
m.SetOwnerID(accountingtest.GenerateOwnerID(false))
}
return m
}
func GenerateBalanceResponse(empty bool) *accounting.BalanceResponse {
m := new(accounting.BalanceResponse)
if !empty {
m.SetBody(GenerateBalanceResponseBody(false))
}
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateBalanceResponseBody(empty bool) *accounting.BalanceResponseBody {
m := new(accounting.BalanceResponseBody)
if !empty {
m.SetBalance(GenerateDecimal(false))
}
return m
}
func GenerateDecimal(empty bool) *accounting.Decimal {
m := new(accounting.Decimal)
if !empty {
m.SetValue(1)
m.SetPrecision(2)
}
return m
}

51
acl/bench_test.go Normal file
View file

@ -0,0 +1,51 @@
package acl_test
import (
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
aclGrpc "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl/grpc"
acltest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl/test"
)
func BenchmarkTable_ToGRPCMessage(b *testing.B) {
const size = 4
tb := new(acl.Table)
rs := make([]acl.Record, size)
for i := range rs {
fs := make([]acl.HeaderFilter, size)
for j := range fs {
fs[j] = *acltest.GenerateFilter(false)
}
ts := make([]acl.Target, size)
for j := range ts {
ts[j] = *acltest.GenerateTarget(false)
}
rs[i].SetFilters(fs)
rs[i].SetTargets(ts)
}
tb.SetRecords(rs)
raw := tb.ToGRPCMessage()
b.Run("to grpc message", func(b *testing.B) {
b.ReportAllocs()
for range b.N {
raw := tb.ToGRPCMessage()
if len(tb.GetRecords()) != len(raw.(*aclGrpc.EACLTable).Records) {
b.FailNow()
}
}
})
b.Run("from grpc message", func(b *testing.B) {
b.ReportAllocs()
for range b.N {
tb := new(acl.Table)
if tb.FromGRPCMessage(raw) != nil {
b.FailNow()
}
}
})
}

592
acl/convert.go Normal file
View file

@ -0,0 +1,592 @@
package acl
import (
acl "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
apeGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
refsGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
// RoleToGRPCField converts unified role enum into grpc enum.
func RoleToGRPCField(t Role) acl.Role {
switch t {
case RoleUser:
return acl.Role_USER
case RoleSystem:
return acl.Role_SYSTEM
case RoleOthers:
return acl.Role_OTHERS
default:
return acl.Role_ROLE_UNSPECIFIED
}
}
// RoleFromGRPCField converts grpc enum into unified role enum.
func RoleFromGRPCField(t acl.Role) Role {
switch t {
case acl.Role_USER:
return RoleUser
case acl.Role_SYSTEM:
return RoleSystem
case acl.Role_OTHERS:
return RoleOthers
default:
return RoleUnknown
}
}
// OperationToGRPCField converts unified operation enum into grpc enum.
func OperationToGRPCField(t Operation) acl.Operation {
switch t {
case OperationPut:
return acl.Operation_PUT
case OperationDelete:
return acl.Operation_DELETE
case OperationGet:
return acl.Operation_GET
case OperationHead:
return acl.Operation_HEAD
case OperationSearch:
return acl.Operation_SEARCH
case OperationRange:
return acl.Operation_GETRANGE
case OperationRangeHash:
return acl.Operation_GETRANGEHASH
default:
return acl.Operation_OPERATION_UNSPECIFIED
}
}
// OperationFromGRPCField converts grpc enum into unified operation enum.
func OperationFromGRPCField(t acl.Operation) Operation {
switch t {
case acl.Operation_PUT:
return OperationPut
case acl.Operation_DELETE:
return OperationDelete
case acl.Operation_GET:
return OperationGet
case acl.Operation_HEAD:
return OperationHead
case acl.Operation_SEARCH:
return OperationSearch
case acl.Operation_GETRANGE:
return OperationRange
case acl.Operation_GETRANGEHASH:
return OperationRangeHash
default:
return OperationUnknown
}
}
// ActionToGRPCField converts unified action enum into grpc enum.
func ActionToGRPCField(t Action) acl.Action {
switch t {
case ActionDeny:
return acl.Action_DENY
case ActionAllow:
return acl.Action_ALLOW
default:
return acl.Action_ACTION_UNSPECIFIED
}
}
// ActionFromGRPCField converts grpc enum into unified action enum.
func ActionFromGRPCField(t acl.Action) Action {
switch t {
case acl.Action_DENY:
return ActionDeny
case acl.Action_ALLOW:
return ActionAllow
default:
return ActionUnknown
}
}
// HeaderTypeToGRPCField converts unified header type enum into grpc enum.
func HeaderTypeToGRPCField(t HeaderType) acl.HeaderType {
switch t {
case HeaderTypeRequest:
return acl.HeaderType_REQUEST
case HeaderTypeObject:
return acl.HeaderType_OBJECT
case HeaderTypeService:
return acl.HeaderType_SERVICE
default:
return acl.HeaderType_HEADER_UNSPECIFIED
}
}
// HeaderTypeFromGRPCField converts grpc enum into unified header type enum.
func HeaderTypeFromGRPCField(t acl.HeaderType) HeaderType {
switch t {
case acl.HeaderType_REQUEST:
return HeaderTypeRequest
case acl.HeaderType_OBJECT:
return HeaderTypeObject
case acl.HeaderType_SERVICE:
return HeaderTypeService
default:
return HeaderTypeUnknown
}
}
// MatchTypeToGRPCField converts unified match type enum into grpc enum.
func MatchTypeToGRPCField(t MatchType) acl.MatchType {
switch t {
case MatchTypeStringEqual:
return acl.MatchType_STRING_EQUAL
case MatchTypeStringNotEqual:
return acl.MatchType_STRING_NOT_EQUAL
default:
return acl.MatchType_MATCH_TYPE_UNSPECIFIED
}
}
// MatchTypeFromGRPCField converts grpc enum into unified match type enum.
func MatchTypeFromGRPCField(t acl.MatchType) MatchType {
switch t {
case acl.MatchType_STRING_EQUAL:
return MatchTypeStringEqual
case acl.MatchType_STRING_NOT_EQUAL:
return MatchTypeStringNotEqual
default:
return MatchTypeUnknown
}
}
func (f *HeaderFilter) ToGRPCMessage() grpc.Message {
var m *acl.EACLRecord_Filter
if f != nil {
m = new(acl.EACLRecord_Filter)
m.SetKey(f.key)
m.SetValue(f.value)
m.SetHeaderType(HeaderTypeToGRPCField(f.hdrType))
m.SetMatchType(MatchTypeToGRPCField(f.matchType))
}
return m
}
func (f *HeaderFilter) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*acl.EACLRecord_Filter)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
f.key = v.GetKey()
f.value = v.GetValue()
f.hdrType = HeaderTypeFromGRPCField(v.GetHeaderType())
f.matchType = MatchTypeFromGRPCField(v.GetMatchType())
return nil
}
func HeaderFiltersToGRPC(fs []HeaderFilter) (res []acl.EACLRecord_Filter) {
if fs != nil {
res = make([]acl.EACLRecord_Filter, 0, len(fs))
for i := range fs {
res = append(res, *fs[i].ToGRPCMessage().(*acl.EACLRecord_Filter))
}
}
return
}
func HeaderFiltersFromGRPC(fs []acl.EACLRecord_Filter) (res []HeaderFilter, err error) {
if fs != nil {
res = make([]HeaderFilter, len(fs))
for i := range fs {
err = res[i].FromGRPCMessage(&fs[i])
if err != nil {
return
}
}
}
return
}
func (t *Target) ToGRPCMessage() grpc.Message {
var m *acl.EACLRecord_Target
if t != nil {
m = new(acl.EACLRecord_Target)
m.SetRole(RoleToGRPCField(t.role))
m.SetKeys(t.keys)
}
return m
}
func (t *Target) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*acl.EACLRecord_Target)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
t.role = RoleFromGRPCField(v.GetRole())
t.keys = v.GetKeys()
return nil
}
func TargetsToGRPC(ts []Target) (res []acl.EACLRecord_Target) {
if ts != nil {
res = make([]acl.EACLRecord_Target, 0, len(ts))
for i := range ts {
res = append(res, *ts[i].ToGRPCMessage().(*acl.EACLRecord_Target))
}
}
return
}
func TargetsFromGRPC(fs []acl.EACLRecord_Target) (res []Target, err error) {
if fs != nil {
res = make([]Target, len(fs))
for i := range fs {
err = res[i].FromGRPCMessage(&fs[i])
if err != nil {
return
}
}
}
return
}
func (r *Record) ToGRPCMessage() grpc.Message {
var m *acl.EACLRecord
if r != nil {
m = new(acl.EACLRecord)
m.SetOperation(OperationToGRPCField(r.op))
m.SetAction(ActionToGRPCField(r.action))
m.SetFilters(HeaderFiltersToGRPC(r.filters))
m.SetTargets(TargetsToGRPC(r.targets))
}
return m
}
func (r *Record) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*acl.EACLRecord)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
r.filters, err = HeaderFiltersFromGRPC(v.GetFilters())
if err != nil {
return err
}
r.targets, err = TargetsFromGRPC(v.GetTargets())
if err != nil {
return err
}
r.op = OperationFromGRPCField(v.GetOperation())
r.action = ActionFromGRPCField(v.GetAction())
return nil
}
func RecordsToGRPC(ts []Record) (res []acl.EACLRecord) {
if ts != nil {
res = make([]acl.EACLRecord, 0, len(ts))
for i := range ts {
res = append(res, *ts[i].ToGRPCMessage().(*acl.EACLRecord))
}
}
return
}
func RecordsFromGRPC(fs []acl.EACLRecord) (res []Record, err error) {
if fs != nil {
res = make([]Record, len(fs))
for i := range fs {
err = res[i].FromGRPCMessage(&fs[i])
if err != nil {
return
}
}
}
return
}
func (t *Table) ToGRPCMessage() grpc.Message {
var m *acl.EACLTable
if t != nil {
m = new(acl.EACLTable)
m.SetVersion(t.version.ToGRPCMessage().(*refsGRPC.Version))
m.SetContainerId(t.cid.ToGRPCMessage().(*refsGRPC.ContainerID))
m.SetRecords(RecordsToGRPC(t.records))
}
return m
}
func (t *Table) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*acl.EACLTable)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
cid := v.GetContainerId()
if cid == nil {
t.cid = nil
} else {
if t.cid == nil {
t.cid = new(refs.ContainerID)
}
err = t.cid.FromGRPCMessage(cid)
if err != nil {
return err
}
}
version := v.GetVersion()
if version == nil {
t.version = nil
} else {
if t.version == nil {
t.version = new(refs.Version)
}
err = t.version.FromGRPCMessage(version)
if err != nil {
return err
}
}
t.records, err = RecordsFromGRPC(v.GetRecords())
return err
}
func (l *TokenLifetime) ToGRPCMessage() grpc.Message {
var m *acl.BearerToken_Body_TokenLifetime
if l != nil {
m = new(acl.BearerToken_Body_TokenLifetime)
m.SetExp(l.exp)
m.SetIat(l.iat)
m.SetNbf(l.nbf)
}
return m
}
func (l *TokenLifetime) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*acl.BearerToken_Body_TokenLifetime)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
l.exp = v.GetExp()
l.iat = v.GetIat()
l.nbf = v.GetNbf()
return nil
}
func (c *APEOverride) ToGRPCMessage() grpc.Message {
var m *acl.BearerToken_Body_APEOverride
if c != nil {
m = new(acl.BearerToken_Body_APEOverride)
m.SetTarget(c.target.ToGRPCMessage().(*apeGRPC.ChainTarget))
if len(c.chains) > 0 {
apeChains := make([]apeGRPC.Chain, len(c.chains))
for i := range c.chains {
apeChains[i] = *c.chains[i].ToGRPCMessage().(*apeGRPC.Chain)
}
m.SetChains(apeChains)
}
}
return m
}
func (c *APEOverride) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*acl.BearerToken_Body_APEOverride)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
if targetGRPC := v.GetTarget(); targetGRPC != nil {
if c.target == nil {
c.target = new(ape.ChainTarget)
}
if err := c.target.FromGRPCMessage(v.GetTarget()); err != nil {
return err
}
}
if apeChains := v.GetChains(); len(apeChains) > 0 {
c.chains = make([]*ape.Chain, len(apeChains))
for i := range apeChains {
c.chains[i] = new(ape.Chain)
if err := c.chains[i].FromGRPCMessage(&apeChains[i]); err != nil {
return err
}
}
}
return nil
}
func (bt *BearerTokenBody) ToGRPCMessage() grpc.Message {
var m *acl.BearerToken_Body
if bt != nil {
m = new(acl.BearerToken_Body)
m.SetOwnerId(bt.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
m.SetLifetime(bt.lifetime.ToGRPCMessage().(*acl.BearerToken_Body_TokenLifetime))
m.SetEaclTable(bt.eacl.ToGRPCMessage().(*acl.EACLTable))
m.SetAllowImpersonate(bt.impersonate)
m.SetApeOverride(bt.apeOverride.ToGRPCMessage().(*acl.BearerToken_Body_APEOverride))
}
return m
}
func (bt *BearerTokenBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*acl.BearerToken_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
ownerID := v.GetOwnerId()
if ownerID == nil {
bt.ownerID = nil
} else {
if bt.ownerID == nil {
bt.ownerID = new(refs.OwnerID)
}
err = bt.ownerID.FromGRPCMessage(ownerID)
if err != nil {
return err
}
}
lifetime := v.GetLifetime()
if lifetime == nil {
bt.lifetime = nil
} else {
if bt.lifetime == nil {
bt.lifetime = new(TokenLifetime)
}
err = bt.lifetime.FromGRPCMessage(lifetime)
if err != nil {
return err
}
}
eacl := v.GetEaclTable()
if eacl == nil {
bt.eacl = nil
} else {
if bt.eacl == nil {
bt.eacl = new(Table)
}
if err = bt.eacl.FromGRPCMessage(eacl); err != nil {
return err
}
}
if apeOverrideGRPC := v.GetApeOverride(); apeOverrideGRPC != nil {
if bt.apeOverride == nil {
bt.apeOverride = new(APEOverride)
}
err = bt.apeOverride.FromGRPCMessage(apeOverrideGRPC)
if err != nil {
return err
}
}
bt.impersonate = v.GetAllowImpersonate()
return err
}
func (bt *BearerToken) ToGRPCMessage() grpc.Message {
var m *acl.BearerToken
if bt != nil {
m = new(acl.BearerToken)
m.SetBody(bt.body.ToGRPCMessage().(*acl.BearerToken_Body))
m.SetSignature(bt.sig.ToGRPCMessage().(*refsGRPC.Signature))
}
return m
}
func (bt *BearerToken) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*acl.BearerToken)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
bt.body = nil
} else {
if bt.body == nil {
bt.body = new(BearerTokenBody)
}
err = bt.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
sig := v.GetSignature()
if sig == nil {
bt.sig = nil
} else {
if bt.sig == nil {
bt.sig = new(refs.Signature)
}
err = bt.sig.FromGRPCMessage(sig)
}
return err
}

33
acl/filters.go Normal file
View file

@ -0,0 +1,33 @@
package acl
// ObjectFilterPrefix is a prefix of key to object header value or property.
const ObjectFilterPrefix = "$Object:"
const (
// FilterObjectVersion is a filter key to "version" field of the object header.
FilterObjectVersion = ObjectFilterPrefix + "version"
// FilterObjectID is a filter key to "object_id" field of the object.
FilterObjectID = ObjectFilterPrefix + "objectID"
// FilterObjectContainerID is a filter key to "container_id" field of the object header.
FilterObjectContainerID = ObjectFilterPrefix + "containerID"
// FilterObjectOwnerID is a filter key to "owner_id" field of the object header.
FilterObjectOwnerID = ObjectFilterPrefix + "ownerID"
// FilterObjectCreationEpoch is a filter key to "creation_epoch" field of the object header.
FilterObjectCreationEpoch = ObjectFilterPrefix + "creationEpoch"
// FilterObjectPayloadLength is a filter key to "payload_length" field of the object header.
FilterObjectPayloadLength = ObjectFilterPrefix + "payloadLength"
// FilterObjectPayloadHash is a filter key to "payload_hash" field of the object header.
FilterObjectPayloadHash = ObjectFilterPrefix + "payloadHash"
// FilterObjectType is a filter key to "object_type" field of the object header.
FilterObjectType = ObjectFilterPrefix + "objectType"
// FilterObjectHomomorphicHash is a filter key to "homomorphic_hash" field of the object header.
FilterObjectHomomorphicHash = ObjectFilterPrefix + "homomorphicHash"
)

BIN
acl/grpc/types_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,64 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package acl
func DoFuzzProtoEACLRecord(data []byte) int {
msg := new(EACLRecord)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONEACLRecord(data []byte) int {
msg := new(EACLRecord)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoEACLTable(data []byte) int {
msg := new(EACLTable)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONEACLTable(data []byte) int {
msg := new(EACLTable)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoBearerToken(data []byte) int {
msg := new(BearerToken)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONBearerToken(data []byte) int {
msg := new(BearerToken)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,41 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package acl
import (
testing "testing"
)
func FuzzProtoEACLRecord(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoEACLRecord(data)
})
}
func FuzzJSONEACLRecord(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONEACLRecord(data)
})
}
func FuzzProtoEACLTable(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoEACLTable(data)
})
}
func FuzzJSONEACLTable(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONEACLTable(data)
})
}
func FuzzProtoBearerToken(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoBearerToken(data)
})
}
func FuzzJSONBearerToken(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONBearerToken(data)
})
}

70
acl/json.go Normal file
View file

@ -0,0 +1,70 @@
package acl
import (
acl "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func (f *HeaderFilter) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(f)
}
func (f *HeaderFilter) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(f, data, new(acl.EACLRecord_Filter))
}
func (t *Target) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(t)
}
func (t *Target) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(t, data, new(acl.EACLRecord_Target))
}
func (a *APEOverride) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(a)
}
func (a *APEOverride) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(a, data, new(acl.BearerToken_Body_APEOverride))
}
func (r *Record) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(r)
}
func (r *Record) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(r, data, new(acl.EACLRecord))
}
func (t *Table) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(t)
}
func (t *Table) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(t, data, new(acl.EACLTable))
}
func (l *TokenLifetime) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(l)
}
func (l *TokenLifetime) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(l, data, new(acl.BearerToken_Body_TokenLifetime))
}
func (bt *BearerTokenBody) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(bt)
}
func (bt *BearerTokenBody) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(bt, data, new(acl.BearerToken_Body))
}
func (bt *BearerToken) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(bt)
}
func (bt *BearerToken) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(bt, data, new(acl.BearerToken))
}

350
acl/marshal.go Normal file
View file

@ -0,0 +1,350 @@
package acl
import (
acl "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
protoutil "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto"
)
const (
filterHeaderTypeField = 1
filterMatchTypeField = 2
filterNameField = 3
filterValueField = 4
targetTypeField = 1
targetKeysField = 2
recordOperationField = 1
recordActionField = 2
recordFiltersField = 3
recordTargetsField = 4
tableVersionField = 1
tableContainerIDField = 2
tableRecordsField = 3
lifetimeExpirationField = 1
lifetimeNotValidBeforeField = 2
lifetimeIssuedAtField = 3
tokenAPEChainsTargetField = 1
tokenAPEChainsChainsField = 2
bearerTokenBodyACLField = 1
bearerTokenBodyOwnerField = 2
bearerTokenBodyLifetimeField = 3
bearerTokenBodyImpersonate = 4
bearerTokenTokenAPEChainsField = 5
bearerTokenBodyField = 1
bearerTokenSignatureField = 2
)
// StableMarshal marshals unified acl table structure in a protobuf
// compatible way without field order shuffle.
func (t *Table) StableMarshal(buf []byte) []byte {
if t == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, t.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(tableVersionField, buf[offset:], t.version)
offset += protoutil.NestedStructureMarshal(tableContainerIDField, buf[offset:], t.cid)
for i := range t.records {
offset += protoutil.NestedStructureMarshal(tableRecordsField, buf[offset:], &t.records[i])
}
return buf
}
// StableSize of acl table structure marshalled by StableMarshal function.
func (t *Table) StableSize() (size int) {
if t == nil {
return 0
}
size += protoutil.NestedStructureSize(tableVersionField, t.version)
size += protoutil.NestedStructureSize(tableContainerIDField, t.cid)
for i := range t.records {
size += protoutil.NestedStructureSize(tableRecordsField, &t.records[i])
}
return size
}
func (t *Table) Unmarshal(data []byte) error {
return message.Unmarshal(t, data, new(acl.EACLTable))
}
// StableMarshal marshals unified acl record structure in a protobuf
// compatible way without field order shuffle.
func (r *Record) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
var offset int
offset += protoutil.EnumMarshal(recordOperationField, buf[offset:], int32(r.op))
offset += protoutil.EnumMarshal(recordActionField, buf[offset:], int32(r.action))
for i := range r.filters {
offset += protoutil.NestedStructureMarshal(recordFiltersField, buf[offset:], &r.filters[i])
}
for i := range r.targets {
offset += protoutil.NestedStructureMarshal(recordTargetsField, buf[offset:], &r.targets[i])
}
return buf
}
// StableSize of acl record structure marshalled by StableMarshal function.
func (r *Record) StableSize() (size int) {
if r == nil {
return 0
}
size += protoutil.EnumSize(recordOperationField, int32(r.op))
size += protoutil.EnumSize(recordActionField, int32(r.action))
for i := range r.filters {
size += protoutil.NestedStructureSize(recordFiltersField, &r.filters[i])
}
for i := range r.targets {
size += protoutil.NestedStructureSize(recordTargetsField, &r.targets[i])
}
return size
}
func (r *Record) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(acl.EACLRecord))
}
// StableMarshal marshals unified header filter structure in a protobuf
// compatible way without field order shuffle.
func (f *HeaderFilter) StableMarshal(buf []byte) []byte {
if f == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, f.StableSize())
}
var offset int
offset += protoutil.EnumMarshal(filterHeaderTypeField, buf[offset:], int32(f.hdrType))
offset += protoutil.EnumMarshal(filterMatchTypeField, buf[offset:], int32(f.matchType))
offset += protoutil.StringMarshal(filterNameField, buf[offset:], f.key)
protoutil.StringMarshal(filterValueField, buf[offset:], f.value)
return buf
}
// StableSize of header filter structure marshalled by StableMarshal function.
func (f *HeaderFilter) StableSize() (size int) {
if f == nil {
return 0
}
size += protoutil.EnumSize(filterHeaderTypeField, int32(f.hdrType))
size += protoutil.EnumSize(filterMatchTypeField, int32(f.matchType))
size += protoutil.StringSize(filterNameField, f.key)
size += protoutil.StringSize(filterValueField, f.value)
return size
}
func (f *HeaderFilter) Unmarshal(data []byte) error {
return message.Unmarshal(f, data, new(acl.EACLRecord_Filter))
}
// StableMarshal marshals unified role info structure in a protobuf
// compatible way without field order shuffle.
func (t *Target) StableMarshal(buf []byte) []byte {
if t == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, t.StableSize())
}
var offset int
offset += protoutil.EnumMarshal(targetTypeField, buf[offset:], int32(t.role))
protoutil.RepeatedBytesMarshal(targetKeysField, buf[offset:], t.keys)
return buf
}
// StableSize of role info structure marshalled by StableMarshal function.
func (t *Target) StableSize() (size int) {
if t == nil {
return 0
}
size += protoutil.EnumSize(targetTypeField, int32(t.role))
size += protoutil.RepeatedBytesSize(targetKeysField, t.keys)
return size
}
func (t *Target) Unmarshal(data []byte) error {
return message.Unmarshal(t, data, new(acl.EACLRecord_Target))
}
func (l *TokenLifetime) StableMarshal(buf []byte) []byte {
if l == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, l.StableSize())
}
var offset int
offset += protoutil.UInt64Marshal(lifetimeExpirationField, buf[offset:], l.exp)
offset += protoutil.UInt64Marshal(lifetimeNotValidBeforeField, buf[offset:], l.nbf)
protoutil.UInt64Marshal(lifetimeIssuedAtField, buf[offset:], l.iat)
return buf
}
func (l *TokenLifetime) StableSize() (size int) {
if l == nil {
return 0
}
size += protoutil.UInt64Size(lifetimeExpirationField, l.exp)
size += protoutil.UInt64Size(lifetimeNotValidBeforeField, l.nbf)
size += protoutil.UInt64Size(lifetimeIssuedAtField, l.iat)
return size
}
func (l *TokenLifetime) Unmarshal(data []byte) error {
return message.Unmarshal(l, data, new(acl.BearerToken_Body_TokenLifetime))
}
func (c *APEOverride) StableMarshal(buf []byte) []byte {
if c == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, c.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(tokenAPEChainsTargetField, buf[offset:], c.target)
for i := range c.chains {
offset += protoutil.NestedStructureMarshal(tokenAPEChainsChainsField, buf[offset:], c.chains[i])
}
return buf
}
func (c *APEOverride) StableSize() (size int) {
if c == nil {
return 0
}
size += protoutil.NestedStructureSize(tokenAPEChainsTargetField, c.target)
for i := range c.chains {
size += protoutil.NestedStructureSize(tokenAPEChainsChainsField, c.chains[i])
}
return size
}
func (c *APEOverride) Unmarshal(data []byte) error {
return message.Unmarshal(c, data, new(acl.BearerToken_Body_APEOverride))
}
func (bt *BearerTokenBody) StableMarshal(buf []byte) []byte {
if bt == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, bt.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(bearerTokenBodyACLField, buf[offset:], bt.eacl)
offset += protoutil.NestedStructureMarshal(bearerTokenBodyOwnerField, buf[offset:], bt.ownerID)
offset += protoutil.NestedStructureMarshal(bearerTokenBodyLifetimeField, buf[offset:], bt.lifetime)
offset += protoutil.BoolMarshal(bearerTokenBodyImpersonate, buf[offset:], bt.impersonate)
protoutil.NestedStructureMarshal(bearerTokenTokenAPEChainsField, buf[offset:], bt.apeOverride)
return buf
}
func (bt *BearerTokenBody) StableSize() (size int) {
if bt == nil {
return 0
}
size += protoutil.NestedStructureSize(bearerTokenBodyACLField, bt.eacl)
size += protoutil.NestedStructureSize(bearerTokenBodyOwnerField, bt.ownerID)
size += protoutil.NestedStructureSize(bearerTokenBodyLifetimeField, bt.lifetime)
size += protoutil.BoolSize(bearerTokenBodyImpersonate, bt.impersonate)
size += protoutil.NestedStructureSize(bearerTokenTokenAPEChainsField, bt.apeOverride)
return size
}
func (bt *BearerTokenBody) Unmarshal(data []byte) error {
return message.Unmarshal(bt, data, new(acl.BearerToken_Body))
}
func (bt *BearerToken) StableMarshal(buf []byte) []byte {
if bt == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, bt.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(bearerTokenBodyField, buf[offset:], bt.body)
protoutil.NestedStructureMarshal(bearerTokenSignatureField, buf[offset:], bt.sig)
return buf
}
func (bt *BearerToken) StableSize() (size int) {
if bt == nil {
return 0
}
size += protoutil.NestedStructureSize(bearerTokenBodyField, bt.body)
size += protoutil.NestedStructureSize(bearerTokenSignatureField, bt.sig)
return size
}
func (bt *BearerToken) Unmarshal(data []byte) error {
return message.Unmarshal(bt, data, new(acl.BearerToken))
}

21
acl/message_test.go Normal file
View file

@ -0,0 +1,21 @@
package acl_test
import (
"testing"
acltest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl/test"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
messagetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return acltest.GenerateFilter(empty) },
func(empty bool) message.Message { return acltest.GenerateTarget(empty) },
func(empty bool) message.Message { return acltest.GenerateRecord(empty) },
func(empty bool) message.Message { return acltest.GenerateTable(empty) },
func(empty bool) message.Message { return acltest.GenerateTokenLifetime(empty) },
func(empty bool) message.Message { return acltest.GenerateBearerTokenBody(empty) },
func(empty bool) message.Message { return acltest.GenerateBearerToken(empty) },
)
}

110
acl/string.go Normal file
View file

@ -0,0 +1,110 @@
package acl
import (
acl "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl/grpc"
)
// String returns string representation of Action.
func (x Action) String() string {
return ActionToGRPCField(x).String()
}
// FromString parses Action from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *Action) FromString(s string) bool {
var g acl.Action
ok := g.FromString(s)
if ok {
*x = ActionFromGRPCField(g)
}
return ok
}
// String returns string representation of Role.
func (x Role) String() string {
return RoleToGRPCField(x).String()
}
// FromString parses Role from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *Role) FromString(s string) bool {
var g acl.Role
ok := g.FromString(s)
if ok {
*x = RoleFromGRPCField(g)
}
return ok
}
// String returns string representation of Operation.
func (x Operation) String() string {
return OperationToGRPCField(x).String()
}
// FromString parses Operation from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *Operation) FromString(s string) bool {
var g acl.Operation
ok := g.FromString(s)
if ok {
*x = OperationFromGRPCField(g)
}
return ok
}
// String returns string representation of MatchType.
func (x MatchType) String() string {
return MatchTypeToGRPCField(x).String()
}
// FromString parses MatchType from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *MatchType) FromString(s string) bool {
var g acl.MatchType
ok := g.FromString(s)
if ok {
*x = MatchTypeFromGRPCField(g)
}
return ok
}
// String returns string representation of HeaderType.
func (x HeaderType) String() string {
return HeaderTypeToGRPCField(x).String()
}
// FromString parses HeaderType from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *HeaderType) FromString(s string) bool {
var g acl.HeaderType
ok := g.FromString(s)
if ok {
*x = HeaderTypeFromGRPCField(g)
}
return ok
}

144
acl/test/generate.go Normal file
View file

@ -0,0 +1,144 @@
package acltest
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
apetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/test"
accountingtest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/test"
)
func GenerateBearerToken(empty bool) *acl.BearerToken {
m := new(acl.BearerToken)
if !empty {
m.SetBody(GenerateBearerTokenBody(false))
}
m.SetSignature(accountingtest.GenerateSignature(empty))
return m
}
func GenerateBearerTokenBody(empty bool) *acl.BearerTokenBody {
m := new(acl.BearerTokenBody)
if !empty {
m.SetOwnerID(accountingtest.GenerateOwnerID(false))
m.SetLifetime(GenerateTokenLifetime(false))
m.SetAPEOverride(GenerateAPEOverride(empty))
}
return m
}
func GenerateAPEOverride(empty bool) *acl.APEOverride {
var m *acl.APEOverride
if !empty {
m = new(acl.APEOverride)
m.SetTarget(apetest.GenerateChainTarget(empty))
m.SetChains(apetest.GenerateRawChains(false, 3))
}
return m
}
func GenerateTable(empty bool) *acl.Table {
m := new(acl.Table)
if !empty {
m.SetRecords(GenerateRecords(false))
m.SetContainerID(accountingtest.GenerateContainerID(false))
}
m.SetVersion(accountingtest.GenerateVersion(empty))
return m
}
func GenerateRecords(empty bool) []acl.Record {
var rs []acl.Record
if !empty {
rs = append(rs,
*GenerateRecord(false),
*GenerateRecord(false),
)
}
return rs
}
func GenerateRecord(empty bool) *acl.Record {
m := new(acl.Record)
if !empty {
m.SetAction(acl.ActionAllow)
m.SetOperation(acl.OperationGet)
m.SetFilters(GenerateFilters(false))
m.SetTargets(GenerateTargets(false))
}
return m
}
func GenerateFilters(empty bool) []acl.HeaderFilter {
var fs []acl.HeaderFilter
if !empty {
fs = append(fs,
*GenerateFilter(false),
*GenerateFilter(false),
)
}
return fs
}
func GenerateFilter(empty bool) *acl.HeaderFilter {
m := new(acl.HeaderFilter)
if !empty {
m.SetKey("key")
m.SetValue("val")
m.SetHeaderType(acl.HeaderTypeRequest)
m.SetMatchType(acl.MatchTypeStringEqual)
}
return m
}
func GenerateTargets(empty bool) []acl.Target {
var ts []acl.Target
if !empty {
ts = append(ts,
*GenerateTarget(false),
*GenerateTarget(false),
)
}
return ts
}
func GenerateTarget(empty bool) *acl.Target {
m := new(acl.Target)
if !empty {
m.SetRole(acl.RoleSystem)
m.SetKeys([][]byte{{1}, {2}})
}
return m
}
func GenerateTokenLifetime(empty bool) *acl.TokenLifetime {
m := new(acl.TokenLifetime)
if !empty {
m.SetExp(1)
m.SetIat(2)
m.SetExp(3)
}
return m
}

426
acl/types.go Normal file
View file

@ -0,0 +1,426 @@
package acl
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
)
// HeaderFilter is a unified structure of FilterInfo
// message from proto definition.
type HeaderFilter struct {
hdrType HeaderType
matchType MatchType
key, value string
}
// Target is a unified structure of Target
// message from proto definition.
type Target struct {
role Role
keys [][]byte
}
// Record is a unified structure of EACLRecord
// message from proto definition.
type Record struct {
op Operation
action Action
filters []HeaderFilter
targets []Target
}
// Table is a unified structure of EACLTable
// message from proto definition.
type Table struct {
version *refs.Version
cid *refs.ContainerID
records []Record
}
type TokenLifetime struct {
exp, nbf, iat uint64
}
type APEOverride struct {
target *ape.ChainTarget
chains []*ape.Chain
}
type BearerTokenBody struct {
eacl *Table
ownerID *refs.OwnerID
lifetime *TokenLifetime
apeOverride *APEOverride
impersonate bool
}
type BearerToken struct {
body *BearerTokenBody
sig *refs.Signature
}
// Target is a unified enum of MatchType enum from proto definition.
type MatchType uint32
// HeaderType is a unified enum of HeaderType enum from proto definition.
type HeaderType uint32
// Action is a unified enum of Action enum from proto definition.
type Action uint32
// Operation is a unified enum of Operation enum from proto definition.
type Operation uint32
// Role is a unified enum of Role enum from proto definition.
type Role uint32
const (
MatchTypeUnknown MatchType = iota
MatchTypeStringEqual
MatchTypeStringNotEqual
)
const (
HeaderTypeUnknown HeaderType = iota
HeaderTypeRequest
HeaderTypeObject
HeaderTypeService
)
const (
ActionUnknown Action = iota
ActionAllow
ActionDeny
)
const (
OperationUnknown Operation = iota
OperationGet
OperationHead
OperationPut
OperationDelete
OperationSearch
OperationRange
OperationRangeHash
)
const (
RoleUnknown Role = iota
RoleUser
RoleSystem
RoleOthers
)
func (f *HeaderFilter) GetHeaderType() HeaderType {
if f != nil {
return f.hdrType
}
return HeaderTypeUnknown
}
func (f *HeaderFilter) SetHeaderType(v HeaderType) {
f.hdrType = v
}
func (f *HeaderFilter) GetMatchType() MatchType {
if f != nil {
return f.matchType
}
return MatchTypeUnknown
}
func (f *HeaderFilter) SetMatchType(v MatchType) {
f.matchType = v
}
func (f *HeaderFilter) GetKey() string {
if f != nil {
return f.key
}
return ""
}
func (f *HeaderFilter) SetKey(v string) {
f.key = v
}
func (f *HeaderFilter) GetValue() string {
if f != nil {
return f.value
}
return ""
}
func (f *HeaderFilter) SetValue(v string) {
f.value = v
}
func (t *Target) GetRole() Role {
if t != nil {
return t.role
}
return RoleUnknown
}
func (t *Target) SetRole(v Role) {
t.role = v
}
func (t *Target) GetKeys() [][]byte {
if t != nil {
return t.keys
}
return nil
}
func (t *Target) SetKeys(v [][]byte) {
t.keys = v
}
func (r *Record) GetOperation() Operation {
if r != nil {
return r.op
}
return OperationUnknown
}
func (r *Record) SetOperation(v Operation) {
r.op = v
}
func (r *Record) GetAction() Action {
if r != nil {
return r.action
}
return ActionUnknown
}
func (r *Record) SetAction(v Action) {
r.action = v
}
func (r *Record) GetFilters() []HeaderFilter {
if r != nil {
return r.filters
}
return nil
}
func (r *Record) SetFilters(v []HeaderFilter) {
r.filters = v
}
func (r *Record) GetTargets() []Target {
if r != nil {
return r.targets
}
return nil
}
func (r *Record) SetTargets(v []Target) {
r.targets = v
}
func (t *Table) GetVersion() *refs.Version {
if t != nil {
return t.version
}
return nil
}
func (t *Table) SetVersion(v *refs.Version) {
t.version = v
}
func (t *Table) GetContainerID() *refs.ContainerID {
if t != nil {
return t.cid
}
return nil
}
func (t *Table) SetContainerID(v *refs.ContainerID) {
t.cid = v
}
func (t *Table) GetRecords() []Record {
if t != nil {
return t.records
}
return nil
}
func (t *Table) SetRecords(v []Record) {
t.records = v
}
func (l *TokenLifetime) GetExp() uint64 {
if l != nil {
return l.exp
}
return 0
}
func (l *TokenLifetime) SetExp(v uint64) {
l.exp = v
}
func (l *TokenLifetime) GetNbf() uint64 {
if l != nil {
return l.nbf
}
return 0
}
func (l *TokenLifetime) SetNbf(v uint64) {
l.nbf = v
}
func (l *TokenLifetime) GetIat() uint64 {
if l != nil {
return l.iat
}
return 0
}
func (l *TokenLifetime) SetIat(v uint64) {
l.iat = v
}
func (bt *BearerTokenBody) GetEACL() *Table {
if bt != nil {
return bt.eacl
}
return nil
}
func (bt *BearerTokenBody) SetEACL(v *Table) {
bt.eacl = v
}
func (t *APEOverride) GetTarget() *ape.ChainTarget {
if t == nil {
return nil
}
return t.target
}
func (t *APEOverride) GetChains() []*ape.Chain {
if t == nil {
return nil
}
return t.chains
}
func (t *APEOverride) SetTarget(v *ape.ChainTarget) {
t.target = v
}
func (t *APEOverride) SetChains(v []*ape.Chain) {
t.chains = v
}
func (bt *BearerTokenBody) GetAPEOverride() *APEOverride {
if bt != nil {
return bt.apeOverride
}
return nil
}
func (bt *BearerTokenBody) SetAPEOverride(v *APEOverride) {
bt.apeOverride = v
}
func (bt *BearerTokenBody) GetOwnerID() *refs.OwnerID {
if bt != nil {
return bt.ownerID
}
return nil
}
func (bt *BearerTokenBody) SetOwnerID(v *refs.OwnerID) {
bt.ownerID = v
}
func (bt *BearerTokenBody) GetLifetime() *TokenLifetime {
if bt != nil {
return bt.lifetime
}
return nil
}
func (bt *BearerTokenBody) SetLifetime(v *TokenLifetime) {
bt.lifetime = v
}
func (bt *BearerTokenBody) GetImpersonate() bool {
if bt != nil {
return bt.impersonate
}
return false
}
func (bt *BearerTokenBody) SetImpersonate(v bool) {
bt.impersonate = v
}
func (bt *BearerToken) GetBody() *BearerTokenBody {
if bt != nil {
return bt.body
}
return nil
}
func (bt *BearerToken) SetBody(v *BearerTokenBody) {
bt.body = v
}
func (bt *BearerToken) GetSignature() *refs.Signature {
if bt != nil {
return bt.sig
}
return nil
}
func (bt *BearerToken) SetSignature(v *refs.Signature) {
bt.sig = v
}

132
ape/convert.go Normal file
View file

@ -0,0 +1,132 @@
package ape
import (
"fmt"
ape "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func TargetTypeToGRPCField(typ TargetType) ape.TargetType {
switch typ {
case TargetTypeNamespace:
return ape.TargetType_NAMESPACE
case TargetTypeContainer:
return ape.TargetType_CONTAINER
case TargetTypeUser:
return ape.TargetType_USER
case TargetTypeGroup:
return ape.TargetType_GROUP
default:
return ape.TargetType_UNDEFINED
}
}
func TargetTypeFromGRPCField(typ ape.TargetType) TargetType {
switch typ {
case ape.TargetType_NAMESPACE:
return TargetTypeNamespace
case ape.TargetType_CONTAINER:
return TargetTypeContainer
case ape.TargetType_USER:
return TargetTypeUser
case ape.TargetType_GROUP:
return TargetTypeGroup
default:
return TargetTypeUndefined
}
}
func TargetTypeToGRPC(typ TargetType) ape.TargetType {
return ape.TargetType(typ)
}
func TargetTypeFromGRPC(typ ape.TargetType) TargetType {
return TargetType(typ)
}
func (v2 *ChainTarget) ToGRPCMessage() grpc.Message {
var mgrpc *ape.ChainTarget
if v2 != nil {
mgrpc = new(ape.ChainTarget)
mgrpc.SetType(TargetTypeToGRPC(v2.GetTargetType()))
mgrpc.SetName(v2.GetName())
}
return mgrpc
}
func (v2 *ChainTarget) FromGRPCMessage(m grpc.Message) error {
mgrpc, ok := m.(*ape.ChainTarget)
if !ok {
return message.NewUnexpectedMessageType(m, mgrpc)
}
v2.SetTargetType(TargetTypeFromGRPC(mgrpc.GetType()))
v2.SetName(mgrpc.GetName())
return nil
}
func (v2 *ChainRaw) ToGRPCMessage() grpc.Message {
var mgrpc *ape.Chain_Raw
if v2 != nil {
mgrpc = new(ape.Chain_Raw)
mgrpc.SetRaw(v2.GetRaw())
}
return mgrpc
}
func (v2 *ChainRaw) FromGRPCMessage(m grpc.Message) error {
mgrpc, ok := m.(*ape.Chain_Raw)
if !ok {
return message.NewUnexpectedMessageType(m, mgrpc)
}
v2.SetRaw(mgrpc.GetRaw())
return nil
}
func (v2 *Chain) ToGRPCMessage() grpc.Message {
var mgrpc *ape.Chain
if v2 != nil {
mgrpc = new(ape.Chain)
switch chainKind := v2.GetKind().(type) {
default:
panic(fmt.Sprintf("unsupported chain kind: %T", chainKind))
case *ChainRaw:
mgrpc.SetKind(chainKind.ToGRPCMessage().(*ape.Chain_Raw))
}
}
return mgrpc
}
func (v2 *Chain) FromGRPCMessage(m grpc.Message) error {
mgrpc, ok := m.(*ape.Chain)
if !ok {
return message.NewUnexpectedMessageType(m, mgrpc)
}
switch chainKind := mgrpc.GetKind().(type) {
default:
return fmt.Errorf("unsupported chain kind: %T", chainKind)
case *ape.Chain_Raw:
chainRaw := new(ChainRaw)
if err := chainRaw.FromGRPCMessage(chainKind); err != nil {
return err
}
v2.SetKind(chainRaw)
}
return nil
}

BIN
ape/grpc/types_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,45 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package ape
func DoFuzzProtoChainTarget(data []byte) int {
msg := new(ChainTarget)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONChainTarget(data []byte) int {
msg := new(ChainTarget)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoChain(data []byte) int {
msg := new(Chain)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONChain(data []byte) int {
msg := new(Chain)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,31 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package ape
import (
testing "testing"
)
func FuzzProtoChainTarget(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoChainTarget(data)
})
}
func FuzzJSONChainTarget(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONChainTarget(data)
})
}
func FuzzProtoChain(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoChain(data)
})
}
func FuzzJSONChain(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONChain(data)
})
}

14
ape/json.go Normal file
View file

@ -0,0 +1,14 @@
package ape
import (
ape "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func (t *ChainTarget) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(t)
}
func (t *ChainTarget) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(t, data, new(ape.ChainTarget))
}

92
ape/marshal.go Normal file
View file

@ -0,0 +1,92 @@
package ape
import (
"fmt"
ape "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto"
)
const (
chainTargetTargetTypeField = 1
chainTargetNameField = 2
chainRawField = 1
)
func (t *ChainTarget) StableSize() (size int) {
if t == nil {
return 0
}
size += proto.EnumSize(chainTargetTargetTypeField, int32(t.targeType))
size += proto.StringSize(chainTargetNameField, t.name)
return size
}
func (t *ChainTarget) StableMarshal(buf []byte) []byte {
if t == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, t.StableSize())
}
var offset int
offset += proto.EnumMarshal(chainTargetTargetTypeField, buf[offset:], int32(t.targeType))
proto.StringMarshal(chainTargetNameField, buf[offset:], t.name)
return buf
}
func (t *ChainTarget) Unmarshal(data []byte) error {
return message.Unmarshal(t, data, new(ape.ChainTarget))
}
func (c *Chain) StableSize() (size int) {
if c == nil {
return 0
}
switch v := c.GetKind().(type) {
case *ChainRaw:
if v != nil {
size += proto.BytesSize(chainRawField, v.GetRaw())
}
default:
panic(fmt.Sprintf("unsupported chain kind: %T", v))
}
return size
}
func (c *Chain) StableMarshal(buf []byte) []byte {
if c == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, c.StableSize())
}
var offset int
switch v := c.GetKind().(type) {
case *ChainRaw:
if v != nil {
proto.BytesMarshal(chainRawField, buf[offset:], v.GetRaw())
}
default:
panic(fmt.Sprintf("unsupported chain kind: %T", v))
}
return buf
}
func (c *Chain) Unmarshal(data []byte) error {
return message.Unmarshal(c, data, new(ape.Chain))
}

15
ape/message_test.go Normal file
View file

@ -0,0 +1,15 @@
package ape_test
import (
"testing"
apetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/test"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
messagetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return apetest.GenerateChainTarget(empty) },
)
}

18
ape/string.go Normal file
View file

@ -0,0 +1,18 @@
package ape
import (
apegrpc "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/grpc"
)
func (tt TargetType) String() string {
return TargetTypeToGRPCField(tt).String()
}
func (tt *TargetType) FromString(s string) bool {
i, ok := apegrpc.TargetType_value[s]
if ok {
*tt = TargetType(i)
}
return ok
}

71
ape/test/generate.go Normal file
View file

@ -0,0 +1,71 @@
package test
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
)
func GenerateRawChains(empty bool, n int) []*ape.Chain {
if empty {
return []*ape.Chain{}
}
res := make([]*ape.Chain, n)
for i := range res {
res[i] = GenerateRawChain(empty)
}
return res
}
func GenerateRawChain(empty bool) *ape.Chain {
chRaw := new(ape.ChainRaw)
if empty {
chRaw.SetRaw([]byte("{}"))
} else {
chRaw.SetRaw([]byte(`{
"ID": "",
"Rules": [
{
"Status": "Allow",
"Actions": {
"Inverted": false,
"Names": [
"GetObject"
]
},
"Resources": {
"Inverted": false,
"Names": [
"native:object/*"
]
},
"Any": false,
"Condition": [
{
"Op": "StringEquals",
"Object": "Resource",
"Key": "Department",
"Value": "HR"
}
]
}
],
"MatchType": "DenyPriority"
}`))
}
ch := new(ape.Chain)
ch.SetKind(chRaw)
return ch
}
func GenerateChainTarget(empty bool) *ape.ChainTarget {
m := new(ape.ChainTarget)
if !empty {
m.SetTargetType(ape.TargetTypeContainer)
m.SetName("BzQw5HH3feoxFDD5tCT87Y1726qzgLfxEE7wgtoRzB3R")
}
return m
}

79
ape/types.go Normal file
View file

@ -0,0 +1,79 @@
package ape
type TargetType uint32
const (
TargetTypeUndefined TargetType = iota
TargetTypeNamespace
TargetTypeContainer
TargetTypeUser
TargetTypeGroup
)
type ChainTarget struct {
targeType TargetType
name string
}
func (ct *ChainTarget) SetTargetType(targeType TargetType) {
ct.targeType = targeType
}
func (ct *ChainTarget) SetName(name string) {
ct.name = name
}
func (ct *ChainTarget) GetTargetType() TargetType {
if ct != nil {
return ct.targeType
}
return 0
}
func (ct *ChainTarget) GetName() string {
if ct != nil {
return ct.name
}
return ""
}
type chainKind interface {
isChainKind()
}
type Chain struct {
kind chainKind
}
func (c *Chain) SetKind(kind chainKind) {
c.kind = kind
}
func (c *Chain) GetKind() chainKind {
if c == nil {
return nil
}
return c.kind
}
type ChainRaw struct {
Raw []byte
}
func (*ChainRaw) isChainKind() {}
func (c *ChainRaw) SetRaw(raw []byte) {
c.Raw = raw
}
func (c *ChainRaw) GetRaw() []byte {
if c == nil {
return nil
}
return c.Raw
}

358
apemanager/convert.go Normal file
View file

@ -0,0 +1,358 @@
package apemanager
import (
ape "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
apeGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/grpc"
apemanager "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func (reqBody *AddChainRequestBody) ToGRPCMessage() grpc.Message {
var reqBodygrpc *apemanager.AddChainRequest_Body
if reqBody != nil {
reqBodygrpc = new(apemanager.AddChainRequest_Body)
reqBodygrpc.SetTarget(reqBody.GetTarget().ToGRPCMessage().(*apeGRPC.ChainTarget))
reqBodygrpc.SetChain(reqBody.GetChain().ToGRPCMessage().(*apeGRPC.Chain))
}
return reqBodygrpc
}
func (reqBody *AddChainRequestBody) FromGRPCMessage(m grpc.Message) error {
reqBodygrpc, ok := m.(*apemanager.AddChainRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, reqBodygrpc)
}
if targetgrpc := reqBodygrpc.GetTarget(); targetgrpc != nil {
reqBody.target = new(ape.ChainTarget)
if err := reqBody.target.FromGRPCMessage(targetgrpc); err != nil {
return err
}
}
if chaingrpc := reqBodygrpc.GetChain(); chaingrpc != nil {
reqBody.chain = new(ape.Chain)
if err := reqBody.GetChain().FromGRPCMessage(chaingrpc); err != nil {
return err
}
}
return nil
}
func (req *AddChainRequest) ToGRPCMessage() grpc.Message {
var reqgrpc *apemanager.AddChainRequest
if req != nil {
reqgrpc = new(apemanager.AddChainRequest)
reqgrpc.SetBody(req.GetBody().ToGRPCMessage().(*apemanager.AddChainRequest_Body))
req.RequestHeaders.ToMessage(reqgrpc)
}
return reqgrpc
}
func (req *AddChainRequest) FromGRPCMessage(m grpc.Message) error {
reqgrpc, ok := m.(*apemanager.AddChainRequest)
if !ok {
return message.NewUnexpectedMessageType(m, reqgrpc)
}
if reqBodygrpc := reqgrpc.GetBody(); reqBodygrpc != nil {
req.body = new(AddChainRequestBody)
if err := req.body.FromGRPCMessage(reqBodygrpc); err != nil {
return err
}
}
return req.RequestHeaders.FromMessage(reqgrpc)
}
func (respBody *AddChainResponseBody) ToGRPCMessage() grpc.Message {
var respBodygrpc *apemanager.AddChainResponse_Body
if respBody != nil {
respBodygrpc = new(apemanager.AddChainResponse_Body)
respBodygrpc.SetChainId(respBody.GetChainID())
}
return respBodygrpc
}
func (respBody *AddChainResponseBody) FromGRPCMessage(m grpc.Message) error {
respBodygrpc, ok := m.(*apemanager.AddChainResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, respBodygrpc)
}
respBody.SetChainID(respBodygrpc.GetChainId())
return nil
}
func (resp *AddChainResponse) ToGRPCMessage() grpc.Message {
var respgrpc *apemanager.AddChainResponse
if resp != nil {
respgrpc = new(apemanager.AddChainResponse)
respgrpc.SetBody(resp.body.ToGRPCMessage().(*apemanager.AddChainResponse_Body))
resp.ResponseHeaders.ToMessage(respgrpc)
}
return respgrpc
}
func (resp *AddChainResponse) FromGRPCMessage(m grpc.Message) error {
respgrpc, ok := m.(*apemanager.AddChainResponse)
if !ok {
return message.NewUnexpectedMessageType(m, respgrpc)
}
if respBodygrpc := respgrpc.GetBody(); respBodygrpc != nil {
resp.body = new(AddChainResponseBody)
if err := resp.body.FromGRPCMessage(respBodygrpc); err != nil {
return err
}
}
return resp.ResponseHeaders.FromMessage(respgrpc)
}
func (reqBody *RemoveChainRequestBody) ToGRPCMessage() grpc.Message {
var reqBodygrpc *apemanager.RemoveChainRequest_Body
if reqBody != nil {
reqBodygrpc = new(apemanager.RemoveChainRequest_Body)
reqBodygrpc.SetTarget(reqBody.target.ToGRPCMessage().(*apeGRPC.ChainTarget))
reqBodygrpc.SetChainId(reqBody.GetChainID())
}
return reqBodygrpc
}
func (reqBody *RemoveChainRequestBody) FromGRPCMessage(m grpc.Message) error {
reqBodygrpc, ok := m.(*apemanager.RemoveChainRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, reqBodygrpc)
}
if targetgrpc := reqBodygrpc.GetTarget(); targetgrpc != nil {
reqBody.target = new(ape.ChainTarget)
if err := reqBody.target.FromGRPCMessage(targetgrpc); err != nil {
return err
}
}
reqBody.SetChainID(reqBodygrpc.GetChainId())
return nil
}
func (req *RemoveChainRequest) ToGRPCMessage() grpc.Message {
var reqgrpc *apemanager.RemoveChainRequest
if req != nil {
reqgrpc = new(apemanager.RemoveChainRequest)
reqgrpc.SetBody(req.body.ToGRPCMessage().(*apemanager.RemoveChainRequest_Body))
req.RequestHeaders.ToMessage(reqgrpc)
}
return reqgrpc
}
func (req *RemoveChainRequest) FromGRPCMessage(m grpc.Message) error {
reqgrpc, ok := m.(*apemanager.RemoveChainRequest)
if !ok {
return message.NewUnexpectedMessageType(m, reqgrpc)
}
if reqBodygrpc := reqgrpc.GetBody(); reqBodygrpc != nil {
req.body = new(RemoveChainRequestBody)
if err := req.body.FromGRPCMessage(reqBodygrpc); err != nil {
return err
}
}
return req.RequestHeaders.FromMessage(reqgrpc)
}
func (respBody *RemoveChainResponseBody) ToGRPCMessage() grpc.Message {
var respBodygrpc *apemanager.RemoveChainResponse_Body
if respBody != nil {
respBodygrpc = new(apemanager.RemoveChainResponse_Body)
}
return respBodygrpc
}
func (respBody *RemoveChainResponseBody) FromGRPCMessage(m grpc.Message) error {
respBodygrpc, ok := m.(*apemanager.RemoveChainResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, respBodygrpc)
}
return nil
}
func (resp *RemoveChainResponse) ToGRPCMessage() grpc.Message {
var respgrpc *apemanager.RemoveChainResponse
if resp != nil {
respgrpc = new(apemanager.RemoveChainResponse)
respgrpc.SetBody(resp.body.ToGRPCMessage().(*apemanager.RemoveChainResponse_Body))
resp.ResponseHeaders.ToMessage(respgrpc)
}
return respgrpc
}
func (resp *RemoveChainResponse) FromGRPCMessage(m grpc.Message) error {
respgrpc, ok := m.(*apemanager.RemoveChainResponse)
if !ok {
return message.NewUnexpectedMessageType(m, respgrpc)
}
if respBodygrpc := respgrpc.GetBody(); respBodygrpc != nil {
resp.body = new(RemoveChainResponseBody)
if err := resp.body.FromGRPCMessage(respBodygrpc); err != nil {
return err
}
}
return resp.ResponseHeaders.FromMessage(respgrpc)
}
func (reqBody *ListChainsRequestBody) ToGRPCMessage() grpc.Message {
var reqBodygrpc *apemanager.ListChainsRequest_Body
if reqBody != nil {
reqBodygrpc = new(apemanager.ListChainsRequest_Body)
reqBodygrpc.SetTarget(reqBody.target.ToGRPCMessage().(*apeGRPC.ChainTarget))
}
return reqBodygrpc
}
func (reqBody *ListChainsRequestBody) FromGRPCMessage(m grpc.Message) error {
reqBodygrpc, ok := m.(*apemanager.ListChainsRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, reqBodygrpc)
}
if targetgrpc := reqBodygrpc.GetTarget(); targetgrpc != nil {
reqBody.target = new(ape.ChainTarget)
if err := reqBody.target.FromGRPCMessage(targetgrpc); err != nil {
return err
}
}
return nil
}
func (req *ListChainsRequest) ToGRPCMessage() grpc.Message {
var reqgrpc *apemanager.ListChainsRequest
if req != nil {
reqgrpc = new(apemanager.ListChainsRequest)
reqgrpc.SetBody(req.body.ToGRPCMessage().(*apemanager.ListChainsRequest_Body))
req.RequestHeaders.ToMessage(reqgrpc)
}
return reqgrpc
}
func (req *ListChainsRequest) FromGRPCMessage(m grpc.Message) error {
reqgrpc, ok := m.(*apemanager.ListChainsRequest)
if !ok {
return message.NewUnexpectedMessageType(m, reqgrpc)
}
if reqBodygrpc := reqgrpc.GetBody(); reqBodygrpc != nil {
req.body = new(ListChainsRequestBody)
if err := req.body.FromGRPCMessage(reqBodygrpc); err != nil {
return err
}
}
return req.RequestHeaders.FromMessage(reqgrpc)
}
func (respBody *ListChainsResponseBody) ToGRPCMessage() grpc.Message {
var respBodygrpc *apemanager.ListChainsResponse_Body
if respBody != nil {
respBodygrpc = new(apemanager.ListChainsResponse_Body)
chainsgrpc := make([]apeGRPC.Chain, 0, len(respBody.GetChains()))
for _, chain := range respBody.GetChains() {
chainsgrpc = append(chainsgrpc, *chain.ToGRPCMessage().(*apeGRPC.Chain))
}
respBodygrpc.SetChains(chainsgrpc)
}
return respBodygrpc
}
func (respBody *ListChainsResponseBody) FromGRPCMessage(m grpc.Message) error {
respBodygrpc, ok := m.(*apemanager.ListChainsResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, respBodygrpc)
}
chains := make([]*ape.Chain, 0, len(respBodygrpc.GetChains()))
for _, chaingrpc := range respBodygrpc.GetChains() {
chain := new(ape.Chain)
if err := chain.FromGRPCMessage(&chaingrpc); err != nil {
return err
}
chains = append(chains, chain)
}
respBody.SetChains(chains)
return nil
}
func (resp *ListChainsResponse) ToGRPCMessage() grpc.Message {
var respgrpc *apemanager.ListChainsResponse
if resp != nil {
respgrpc = new(apemanager.ListChainsResponse)
respgrpc.SetBody(resp.body.ToGRPCMessage().(*apemanager.ListChainsResponse_Body))
resp.ResponseHeaders.ToMessage(respgrpc)
}
return respgrpc
}
func (resp *ListChainsResponse) FromGRPCMessage(m grpc.Message) error {
respgrpc, ok := m.(*apemanager.ListChainsResponse)
if !ok {
return message.NewUnexpectedMessageType(m, respgrpc)
}
if respBodygrpc := respgrpc.GetBody(); respBodygrpc != nil {
resp.body = new(ListChainsResponseBody)
if err := resp.body.FromGRPCMessage(respBodygrpc); err != nil {
return err
}
}
return resp.ResponseHeaders.FromMessage(respgrpc)
}

BIN
apemanager/grpc/service_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,121 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package apemanager
func DoFuzzProtoAddChainRequest(data []byte) int {
msg := new(AddChainRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONAddChainRequest(data []byte) int {
msg := new(AddChainRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoAddChainResponse(data []byte) int {
msg := new(AddChainResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONAddChainResponse(data []byte) int {
msg := new(AddChainResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoRemoveChainRequest(data []byte) int {
msg := new(RemoveChainRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONRemoveChainRequest(data []byte) int {
msg := new(RemoveChainRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoRemoveChainResponse(data []byte) int {
msg := new(RemoveChainResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONRemoveChainResponse(data []byte) int {
msg := new(RemoveChainResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoListChainsRequest(data []byte) int {
msg := new(ListChainsRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONListChainsRequest(data []byte) int {
msg := new(ListChainsRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoListChainsResponse(data []byte) int {
msg := new(ListChainsResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONListChainsResponse(data []byte) int {
msg := new(ListChainsResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,71 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package apemanager
import (
testing "testing"
)
func FuzzProtoAddChainRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoAddChainRequest(data)
})
}
func FuzzJSONAddChainRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONAddChainRequest(data)
})
}
func FuzzProtoAddChainResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoAddChainResponse(data)
})
}
func FuzzJSONAddChainResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONAddChainResponse(data)
})
}
func FuzzProtoRemoveChainRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoRemoveChainRequest(data)
})
}
func FuzzJSONRemoveChainRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONRemoveChainRequest(data)
})
}
func FuzzProtoRemoveChainResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoRemoveChainResponse(data)
})
}
func FuzzJSONRemoveChainResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONRemoveChainResponse(data)
})
}
func FuzzProtoListChainsRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoListChainsRequest(data)
})
}
func FuzzJSONListChainsRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONListChainsRequest(data)
})
}
func FuzzProtoListChainsResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoListChainsResponse(data)
})
}
func FuzzJSONListChainsResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONListChainsResponse(data)
})
}

BIN
apemanager/grpc/service_grpc.pb.go generated Normal file

Binary file not shown.

205
apemanager/marshal.go Normal file
View file

@ -0,0 +1,205 @@
package apemanager
import (
apemanager "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto"
)
const (
addChainReqBodyTargetField = 1
addChainReqBodyChainField = 2
addChainRespBodyChainIDField = 1
removeChainReqBodyTargetField = 1
removeChainReqBodyChainField = 2
/*
Fields for RemoveResponseBody are missed since RemoveResponseBody is empty.
*/
listChainsReqBodyTargetField = 1
listChainsRespBodyChainsField = 1
)
func (rb *AddChainRequestBody) StableSize() (size int) {
if rb == nil {
return 0
}
size += proto.NestedStructureSize(addChainReqBodyTargetField, rb.target)
size += proto.NestedStructureSize(addChainReqBodyChainField, rb.chain)
return size
}
func (rb *AddChainRequestBody) StableMarshal(buf []byte) []byte {
if rb == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, rb.StableSize())
}
var offset int
offset += proto.NestedStructureMarshal(addChainReqBodyTargetField, buf[offset:], rb.target)
proto.NestedStructureMarshal(addChainReqBodyChainField, buf[offset:], rb.chain)
return buf
}
func (rb *AddChainRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(rb, data, new(apemanager.AddChainRequest_Body))
}
func (rb *AddChainResponseBody) StableSize() (size int) {
if rb == nil {
return 0
}
size += proto.BytesSize(addChainRespBodyChainIDField, rb.chainID)
return size
}
func (rb *AddChainResponseBody) StableMarshal(buf []byte) []byte {
if rb == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, rb.StableSize())
}
var offset int
proto.BytesMarshal(addChainRespBodyChainIDField, buf[offset:], rb.chainID)
return buf
}
func (rb *AddChainResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(rb, data, new(apemanager.AddChainResponse_Body))
}
func (rb *RemoveChainRequestBody) StableSize() (size int) {
if rb == nil {
return 0
}
size += proto.NestedStructureSize(addChainReqBodyTargetField, rb.target)
size += proto.BytesSize(addChainReqBodyChainField, rb.chainID)
return size
}
func (rb *RemoveChainRequestBody) StableMarshal(buf []byte) []byte {
if rb == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, rb.StableSize())
}
var offset int
offset += proto.NestedStructureMarshal(removeChainReqBodyTargetField, buf[offset:], rb.target)
proto.BytesMarshal(removeChainReqBodyChainField, buf[offset:], rb.chainID)
return buf
}
func (rb *RemoveChainRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(rb, data, new(apemanager.RemoveChainRequest_Body))
}
func (rb *RemoveChainResponseBody) StableSize() (size int) {
if rb == nil {
return 0
}
return size
}
func (rb *RemoveChainResponseBody) StableMarshal(buf []byte) []byte {
if rb == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, rb.StableSize())
}
return buf
}
func (rb *RemoveChainResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(rb, data, new(apemanager.RemoveChainResponse_Body))
}
func (rb *ListChainsRequestBody) StableSize() (size int) {
if rb == nil {
return 0
}
size += proto.NestedStructureSize(listChainsReqBodyTargetField, rb.target)
return size
}
func (rb *ListChainsRequestBody) StableMarshal(buf []byte) []byte {
if rb == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, rb.StableSize())
}
var offset int
proto.NestedStructureMarshal(addChainReqBodyTargetField, buf[offset:], rb.target)
return buf
}
func (rb *ListChainsRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(rb, data, new(apemanager.ListChainsRequest_Body))
}
func (rb *ListChainsResponseBody) StableSize() (size int) {
if rb == nil {
return 0
}
for _, chain := range rb.GetChains() {
size += proto.NestedStructureSize(listChainsRespBodyChainsField, chain)
}
return size
}
func (rb *ListChainsResponseBody) StableMarshal(buf []byte) []byte {
if rb == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, rb.StableSize())
}
var offset int
for _, chain := range rb.GetChains() {
offset += proto.NestedStructureMarshal(listChainsRespBodyChainsField, buf[offset:], chain)
}
return buf
}
func (rb *ListChainsResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(rb, data, new(apemanager.ListChainsResponse_Body))
}

View file

@ -0,0 +1,26 @@
package apemanager_test
import (
"testing"
apemanagertest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager/test"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
messagetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return apemanagertest.GenerateAddChainRequestBody(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateAddChainRequest(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateAddChainResponseBody(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateAddChainResponse(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateRemoveChainRequestBody(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateRemoveChainRequest(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateRemoveChainResponseBody(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateRemoveChainResponse(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateListChainsRequestBody(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateListChainsRequest(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateListChainsResponseBody(empty) },
func(empty bool) message.Message { return apemanagertest.GenerateListChainsResponse(empty) },
)
}

76
apemanager/status.go Normal file
View file

@ -0,0 +1,76 @@
package apemanager
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/status"
statusgrpc "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/status/grpc"
)
// LocalizeFailStatus checks if passed global status.Code is related to ape manager failure and:
//
// then localizes the code and returns true,
// else leaves the code unchanged and returns false.
//
// Arg must be non-nil.
func LocalizeFailStatus(c *status.Code) bool {
return status.LocalizeIfInSection(c, uint32(statusgrpc.Section_SECTION_APE_MANAGER))
}
// GlobalizeFail globalizes local code of ape manager failure.
//
// Arg must be non-nil.
func GlobalizeFail(c *status.Code) {
c.GlobalizeSection(uint32(statusgrpc.Section_SECTION_APE_MANAGER))
}
const (
// StatusAPEManagerAccessDenied is a local status.Code value for
// ACCESS_DENIED ape manager failure.
StatusAPEManagerAccessDenied status.Code = iota
)
const (
// detailAccessDeniedDesc is a StatusAccessDenied detail ID for
// human-readable description.
detailAccessDeniedDesc = iota
)
// WriteAccessDeniedDesc writes human-readable description of StatusAccessDenied
// into status.Status as a detail. The status must not be nil.
//
// Existing details are expected to be ID-unique, otherwise undefined behavior.
func WriteAccessDeniedDesc(st *status.Status, desc string) {
var found bool
st.IterateDetails(func(d *status.Detail) bool {
if d.ID() == detailAccessDeniedDesc {
found = true
d.SetValue([]byte(desc))
}
return found
})
if !found {
var d status.Detail
d.SetID(detailAccessDeniedDesc)
d.SetValue([]byte(desc))
st.AppendDetails(d)
}
}
// ReadAccessDeniedDesc looks up for status detail with human-readable description
// of StatusAccessDenied. Returns empty string if detail is missing.
func ReadAccessDeniedDesc(st status.Status) (desc string) {
st.IterateDetails(func(d *status.Detail) bool {
if d.ID() == detailAccessDeniedDesc {
desc = string(d.Value())
return true
}
return false
})
return
}

30
apemanager/status_test.go Normal file
View file

@ -0,0 +1,30 @@
package apemanager_test
import (
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/status"
statustest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/status/test"
"github.com/stretchr/testify/require"
)
func TestStatusCodes(t *testing.T) {
statustest.TestCodes(t, apemanager.LocalizeFailStatus, apemanager.GlobalizeFail,
apemanager.StatusAPEManagerAccessDenied, 5120,
)
}
func TestAccessDeniedDesc(t *testing.T) {
var st status.Status
require.Empty(t, apemanager.ReadAccessDeniedDesc(st))
const desc = "some description"
apemanager.WriteAccessDeniedDesc(&st, desc)
require.Equal(t, desc, apemanager.ReadAccessDeniedDesc(st))
apemanager.WriteAccessDeniedDesc(&st, desc+"1")
require.Equal(t, desc+"1", apemanager.ReadAccessDeniedDesc(st))
}

143
apemanager/test/generate.go Normal file
View file

@ -0,0 +1,143 @@
package apemanagertest
import (
apetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape/test"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
sessiontest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session/test"
)
func generateChainID(empty bool) []byte {
if empty {
return []byte{}
}
return []byte("616c6c6f774f626a476574436e72")
}
func GenerateAddChainRequestBody(empty bool) *apemanager.AddChainRequestBody {
m := new(apemanager.AddChainRequestBody)
if !empty {
m.SetTarget(apetest.GenerateChainTarget(empty))
m.SetChain(apetest.GenerateRawChain(empty))
}
return m
}
func GenerateAddChainRequest(empty bool) *apemanager.AddChainRequest {
m := new(apemanager.AddChainRequest)
if !empty {
m.SetBody(GenerateAddChainRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
}
return m
}
func GenerateAddChainResponseBody(empty bool) *apemanager.AddChainResponseBody {
m := new(apemanager.AddChainResponseBody)
if !empty {
m.SetChainID(generateChainID(empty))
}
return m
}
func GenerateAddChainResponse(empty bool) *apemanager.AddChainResponse {
m := new(apemanager.AddChainResponse)
if !empty {
m.SetBody(GenerateAddChainResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
}
return m
}
func GenerateRemoveChainRequestBody(empty bool) *apemanager.RemoveChainRequestBody {
m := new(apemanager.RemoveChainRequestBody)
if !empty {
m.SetChainID(generateChainID(empty))
m.SetTarget(apetest.GenerateChainTarget(empty))
}
return m
}
func GenerateRemoveChainRequest(empty bool) *apemanager.RemoveChainRequest {
m := new(apemanager.RemoveChainRequest)
if !empty {
m.SetBody(GenerateRemoveChainRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
}
return m
}
func GenerateRemoveChainResponseBody(_ bool) *apemanager.RemoveChainResponseBody {
return new(apemanager.RemoveChainResponseBody)
}
func GenerateRemoveChainResponse(empty bool) *apemanager.RemoveChainResponse {
m := new(apemanager.RemoveChainResponse)
if !empty {
m.SetBody(GenerateRemoveChainResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
}
return m
}
func GenerateListChainsRequestBody(empty bool) *apemanager.ListChainsRequestBody {
m := new(apemanager.ListChainsRequestBody)
if !empty {
m.SetTarget(apetest.GenerateChainTarget(empty))
}
return m
}
func GenerateListChainsRequest(empty bool) *apemanager.ListChainsRequest {
m := new(apemanager.ListChainsRequest)
if !empty {
m.SetBody(GenerateListChainsRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
}
return m
}
func GenerateListChainsResponseBody(empty bool) *apemanager.ListChainsResponseBody {
m := new(apemanager.ListChainsResponseBody)
if !empty {
m.SetChains(apetest.GenerateRawChains(empty, 10))
}
return m
}
func GenerateListChainsResponse(empty bool) *apemanager.ListChainsResponse {
m := new(apemanager.ListChainsResponse)
if !empty {
m.SetBody(GenerateListChainsResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
}
return m
}

226
apemanager/types.go Normal file
View file

@ -0,0 +1,226 @@
package apemanager
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
)
type AddChainRequest struct {
body *AddChainRequestBody
session.RequestHeaders
}
func (r *AddChainRequest) SetBody(body *AddChainRequestBody) {
r.body = body
}
func (r *AddChainRequest) GetBody() *AddChainRequestBody {
if r == nil {
return nil
}
return r.body
}
type AddChainRequestBody struct {
target *ape.ChainTarget
chain *ape.Chain
}
func (rb *AddChainRequestBody) SetTarget(target *ape.ChainTarget) {
rb.target = target
}
func (rb *AddChainRequestBody) GetTarget() *ape.ChainTarget {
if rb == nil {
return nil
}
return rb.target
}
func (rb *AddChainRequestBody) SetChain(chain *ape.Chain) {
rb.chain = chain
}
func (rb *AddChainRequestBody) GetChain() *ape.Chain {
if rb == nil {
return nil
}
return rb.chain
}
type AddChainResponse struct {
body *AddChainResponseBody
session.ResponseHeaders
}
func (r *AddChainResponse) SetBody(body *AddChainResponseBody) {
r.body = body
}
func (r *AddChainResponse) GetBody() *AddChainResponseBody {
if r == nil {
return nil
}
return r.body
}
type AddChainResponseBody struct {
chainID []byte
}
func (rb *AddChainResponseBody) SetChainID(chainID []byte) {
rb.chainID = chainID
}
func (rb *AddChainResponseBody) GetChainID() []byte {
if rb == nil {
return nil
}
return rb.chainID
}
type RemoveChainRequest struct {
body *RemoveChainRequestBody
session.RequestHeaders
}
func (r *RemoveChainRequest) SetBody(body *RemoveChainRequestBody) {
r.body = body
}
func (r *RemoveChainRequest) GetBody() *RemoveChainRequestBody {
if r == nil {
return nil
}
return r.body
}
type RemoveChainRequestBody struct {
target *ape.ChainTarget
chainID []byte
}
func (rb *RemoveChainRequestBody) SetTarget(target *ape.ChainTarget) {
rb.target = target
}
func (rb *RemoveChainRequestBody) GetTarget() *ape.ChainTarget {
if rb == nil {
return nil
}
return rb.target
}
func (rb *RemoveChainRequestBody) SetChainID(chainID []byte) {
rb.chainID = chainID
}
func (rb *RemoveChainRequestBody) GetChainID() []byte {
if rb == nil {
return nil
}
return rb.chainID
}
type RemoveChainResponse struct {
body *RemoveChainResponseBody
session.ResponseHeaders
}
type RemoveChainResponseBody struct{}
func (r *RemoveChainResponse) SetBody(body *RemoveChainResponseBody) {
r.body = body
}
func (r *RemoveChainResponse) GetBody() *RemoveChainResponseBody {
if r == nil {
return nil
}
return r.body
}
type ListChainsRequest struct {
body *ListChainsRequestBody
session.RequestHeaders
}
func (r *ListChainsRequest) SetBody(body *ListChainsRequestBody) {
r.body = body
}
func (r *ListChainsRequest) GetBody() *ListChainsRequestBody {
if r == nil {
return nil
}
return r.body
}
type ListChainsRequestBody struct {
target *ape.ChainTarget
}
func (rb *ListChainsRequestBody) SetTarget(target *ape.ChainTarget) {
rb.target = target
}
func (rb *ListChainsRequestBody) GetTarget() *ape.ChainTarget {
if rb == nil {
return nil
}
return rb.target
}
type ListChainsResponse struct {
body *ListChainsResponseBody
session.ResponseHeaders
}
func (r *ListChainsResponse) SetBody(body *ListChainsResponseBody) {
r.body = body
}
func (r *ListChainsResponse) GetBody() *ListChainsResponseBody {
if r == nil {
return nil
}
return r.body
}
type ListChainsResponseBody struct {
chains []*ape.Chain
session.RequestHeaders
}
func (r *ListChainsResponseBody) SetChains(chains []*ape.Chain) {
r.chains = chains
}
func (r *ListChainsResponseBody) GetChains() []*ape.Chain {
if r == nil {
return nil
}
return r.chains
}

90
container/attributes.go Normal file
View file

@ -0,0 +1,90 @@
package container
// SysAttributePrefix is a prefix of key to system attribute.
const SysAttributePrefix = "__SYSTEM__"
const (
// SysAttributeName is a string of human-friendly container name registered as the domain in NNS contract.
SysAttributeName = SysAttributePrefix + "NAME"
// SysAttributeZone is a string of zone for container name.
SysAttributeZone = SysAttributePrefix + "ZONE"
// SysAttributeHomomorphicHashing is a container's homomorphic hashing state.
SysAttributeHomomorphicHashing = SysAttributePrefix + "DISABLE_HOMOMORPHIC_HASHING"
)
// SysAttributePrefixNeoFS is a prefix of key to system attribute.
// Deprecated: use SysAttributePrefix.
const SysAttributePrefixNeoFS = "__NEOFS__"
const (
// SysAttributeNameNeoFS is a string of human-friendly container name registered as the domain in NNS contract.
// Deprecated: use SysAttributeName.
SysAttributeNameNeoFS = SysAttributePrefixNeoFS + "NAME"
// SysAttributeZoneNeoFS is a string of zone for container name.
// Deprecated: use SysAttributeZone.
SysAttributeZoneNeoFS = SysAttributePrefixNeoFS + "ZONE"
// SysAttributeHomomorphicHashingNeoFS is a container's homomorphic hashing state.
// Deprecated: use SysAttributeHomomorphicHashing.
SysAttributeHomomorphicHashingNeoFS = SysAttributePrefixNeoFS + "DISABLE_HOMOMORPHIC_HASHING"
)
// SysAttributeZoneDefault is a default value for SysAttributeZone attribute.
const SysAttributeZoneDefault = "container"
const disabledHomomorphicHashingValue = "true"
// HomomorphicHashingState returns container's homomorphic
// hashing state:
// - true if hashing is enabled;
// - false if hashing is disabled.
//
// All container's attributes must be unique, otherwise behavior
// is undefined.
//
// See also SetHomomorphicHashingState.
func (c Container) HomomorphicHashingState() bool {
for i := range c.attr {
if c.attr[i].GetKey() == SysAttributeHomomorphicHashing || c.attr[i].GetKey() == SysAttributeHomomorphicHashingNeoFS {
return c.attr[i].GetValue() != disabledHomomorphicHashingValue
}
}
return true
}
// SetHomomorphicHashingState sets homomorphic hashing state for
// container.
//
// All container's attributes must be unique, otherwise behavior
// is undefined.
//
// See also HomomorphicHashingState.
func (c *Container) SetHomomorphicHashingState(enable bool) {
for i := range c.attr {
if c.attr[i].GetKey() == SysAttributeHomomorphicHashing || c.attr[i].GetKey() == SysAttributeHomomorphicHashingNeoFS {
if enable {
// approach without allocation/waste
// coping works since the attributes
// order is not important
c.attr[i] = c.attr[len(c.attr)-1]
c.attr = c.attr[:len(c.attr)-1]
} else {
c.attr[i].SetValue(disabledHomomorphicHashingValue)
}
return
}
}
if !enable {
attr := Attribute{}
attr.SetKey(SysAttributeHomomorphicHashing)
attr.SetValue(disabledHomomorphicHashingValue)
c.attr = append(c.attr, attr)
}
}

View file

@ -0,0 +1,59 @@
package container_test
import (
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
containertest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container/test"
"github.com/stretchr/testify/require"
)
func TestContainer_HomomorphicHashingDisabled(t *testing.T) {
cnr := containertest.GenerateContainer(false)
t.Run("defaults", func(t *testing.T) {
require.True(t, cnr.HomomorphicHashingState())
})
t.Run("disabled", func(t *testing.T) {
attr := container.Attribute{}
attr.SetKey(container.SysAttributeHomomorphicHashing)
attr.SetValue("NOT_true")
cnr.SetAttributes(append(cnr.GetAttributes(), attr))
require.True(t, cnr.HomomorphicHashingState())
attr.SetValue("true")
cnr.SetAttributes([]container.Attribute{attr})
require.False(t, cnr.HomomorphicHashingState())
})
}
func TestContainer_SetHomomorphicHashingState(t *testing.T) {
cnr := containertest.GenerateContainer(false)
attrs := cnr.GetAttributes()
attrLen := len(attrs)
cnr.SetHomomorphicHashingState(true)
// enabling hashing should not add any new attributes
require.Equal(t, attrLen, len(cnr.GetAttributes()))
require.True(t, cnr.HomomorphicHashingState())
cnr.SetHomomorphicHashingState(false)
// disabling hashing should add exactly one attribute
require.Equal(t, attrLen+1, len(cnr.GetAttributes()))
require.False(t, cnr.HomomorphicHashingState())
cnr.SetHomomorphicHashingState(true)
// enabling hashing should remove 1 attribute if
// hashing was disabled before
require.Equal(t, attrLen, len(cnr.GetAttributes()))
require.True(t, cnr.HomomorphicHashingState())
// hashing operations should not change any other attributes
require.ElementsMatch(t, attrs, cnr.GetAttributes())
}

764
container/convert.go Normal file
View file

@ -0,0 +1,764 @@
package container
import (
container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
netmapGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
refsGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
sessionGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session/grpc"
)
func (a *Attribute) ToGRPCMessage() grpc.Message {
var m *container.Container_Attribute
if a != nil {
m = new(container.Container_Attribute)
m.SetKey(a.key)
m.SetValue(a.val)
}
return m
}
func (a *Attribute) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.Container_Attribute)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
a.key = v.GetKey()
a.val = v.GetValue()
return nil
}
func AttributesToGRPC(xs []Attribute) (res []container.Container_Attribute) {
if xs != nil {
res = make([]container.Container_Attribute, 0, len(xs))
for i := range xs {
res = append(res, *xs[i].ToGRPCMessage().(*container.Container_Attribute))
}
}
return
}
func AttributesFromGRPC(xs []container.Container_Attribute) (res []Attribute, err error) {
if xs != nil {
res = make([]Attribute, len(xs))
for i := range xs {
err = res[i].FromGRPCMessage(&xs[i])
if err != nil {
return
}
}
}
return
}
func (c *Container) ToGRPCMessage() grpc.Message {
var m *container.Container
if c != nil {
m = new(container.Container)
m.SetVersion(c.version.ToGRPCMessage().(*refsGRPC.Version))
m.SetOwnerId(c.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
m.SetPlacementPolicy(c.policy.ToGRPCMessage().(*netmapGRPC.PlacementPolicy))
m.SetAttributes(AttributesToGRPC(c.attr))
m.SetBasicAcl(c.basicACL)
m.SetNonce(c.nonce)
}
return m
}
func (c *Container) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.Container)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
version := v.GetVersion()
if version == nil {
c.version = nil
} else {
if c.version == nil {
c.version = new(refs.Version)
}
err = c.version.FromGRPCMessage(version)
if err != nil {
return err
}
}
ownerID := v.GetOwnerId()
if ownerID == nil {
c.ownerID = nil
} else {
if c.ownerID == nil {
c.ownerID = new(refs.OwnerID)
}
err = c.ownerID.FromGRPCMessage(ownerID)
if err != nil {
return err
}
}
policy := v.GetPlacementPolicy()
if policy == nil {
c.policy = nil
} else {
if c.policy == nil {
c.policy = new(netmap.PlacementPolicy)
}
err = c.policy.FromGRPCMessage(policy)
if err != nil {
return err
}
}
c.attr, err = AttributesFromGRPC(v.GetAttributes())
if err != nil {
return err
}
c.basicACL = v.GetBasicAcl()
c.nonce = v.GetNonce()
return nil
}
func toSignatureRFC6979(s *refs.Signature) *refsGRPC.SignatureRFC6979 {
var res *refsGRPC.SignatureRFC6979
if s != nil {
res = new(refsGRPC.SignatureRFC6979)
res.SetKey(s.GetKey())
res.SetSign(s.GetSign())
}
return res
}
func (r *PutRequestBody) ToGRPCMessage() grpc.Message {
var m *container.PutRequest_Body
if r != nil {
m = new(container.PutRequest_Body)
m.SetContainer(r.cnr.ToGRPCMessage().(*container.Container))
m.SetSignature(toSignatureRFC6979(r.sig))
}
return m
}
func (r *PutRequestBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.PutRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
cnr := v.GetContainer()
if cnr == nil {
r.cnr = nil
} else {
if r.cnr == nil {
r.cnr = new(Container)
}
err = r.cnr.FromGRPCMessage(cnr)
if err != nil {
return err
}
}
sig := v.GetSignature()
if sig == nil {
r.sig = nil
} else {
if r.sig == nil {
r.sig = new(refs.Signature)
}
r.sig.SetKey(sig.GetKey())
r.sig.SetSign(sig.GetSign())
}
return err
}
func (r *PutRequest) ToGRPCMessage() grpc.Message {
var m *container.PutRequest
if r != nil {
m = new(container.PutRequest)
m.SetBody(r.body.ToGRPCMessage().(*container.PutRequest_Body))
r.RequestHeaders.ToMessage(m)
}
return m
}
func (r *PutRequest) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.PutRequest)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
r.body = nil
} else {
if r.body == nil {
r.body = new(PutRequestBody)
}
err = r.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return r.RequestHeaders.FromMessage(v)
}
func (r *PutResponseBody) ToGRPCMessage() grpc.Message {
var m *container.PutResponse_Body
if r != nil {
m = new(container.PutResponse_Body)
m.SetContainerId(r.cid.ToGRPCMessage().(*refsGRPC.ContainerID))
}
return m
}
func (r *PutResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.PutResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
cid := v.GetContainerId()
if cid == nil {
r.cid = nil
} else {
if r.cid == nil {
r.cid = new(refs.ContainerID)
}
err = r.cid.FromGRPCMessage(cid)
}
return err
}
func (r *PutResponse) ToGRPCMessage() grpc.Message {
var m *container.PutResponse
if r != nil {
m = new(container.PutResponse)
m.SetBody(r.body.ToGRPCMessage().(*container.PutResponse_Body))
r.ResponseHeaders.ToMessage(m)
}
return m
}
func (r *PutResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.PutResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
r.body = nil
} else {
if r.body == nil {
r.body = new(PutResponseBody)
}
err = r.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return r.ResponseHeaders.FromMessage(v)
}
func (r *GetRequestBody) ToGRPCMessage() grpc.Message {
var m *container.GetRequest_Body
if r != nil {
m = new(container.GetRequest_Body)
m.SetContainerId(r.cid.ToGRPCMessage().(*refsGRPC.ContainerID))
}
return m
}
func (r *GetRequestBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.GetRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
cid := v.GetContainerId()
if cid == nil {
r.cid = nil
} else {
if r.cid == nil {
r.cid = new(refs.ContainerID)
}
err = r.cid.FromGRPCMessage(cid)
}
return err
}
func (r *GetRequest) ToGRPCMessage() grpc.Message {
var m *container.GetRequest
if r != nil {
m = new(container.GetRequest)
m.SetBody(r.body.ToGRPCMessage().(*container.GetRequest_Body))
r.RequestHeaders.ToMessage(m)
}
return m
}
func (r *GetRequest) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.GetRequest)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
r.body = nil
} else {
if r.body == nil {
r.body = new(GetRequestBody)
}
err = r.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return r.RequestHeaders.FromMessage(v)
}
func (r *GetResponseBody) ToGRPCMessage() grpc.Message {
var m *container.GetResponse_Body
if r != nil {
m = new(container.GetResponse_Body)
m.SetContainer(r.cnr.ToGRPCMessage().(*container.Container))
m.SetSessionToken(r.token.ToGRPCMessage().(*sessionGRPC.SessionToken))
m.SetSignature(toSignatureRFC6979(r.sig))
}
return m
}
func (r *GetResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.GetResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
cnr := v.GetContainer()
if cnr == nil {
r.cnr = nil
} else {
if r.cnr == nil {
r.cnr = new(Container)
}
err = r.cnr.FromGRPCMessage(cnr)
}
sig := v.GetSignature()
if sig == nil {
r.sig = nil
} else {
if r.sig == nil {
r.sig = new(refs.Signature)
}
r.sig.SetKey(sig.GetKey())
r.sig.SetSign(sig.GetSign())
}
token := v.GetSessionToken()
if token == nil {
r.token = nil
} else {
if r.token == nil {
r.token = new(session.Token)
}
err = r.token.FromGRPCMessage(token)
}
return err
}
func (r *GetResponse) ToGRPCMessage() grpc.Message {
var m *container.GetResponse
if r != nil {
m = new(container.GetResponse)
m.SetBody(r.body.ToGRPCMessage().(*container.GetResponse_Body))
r.ResponseHeaders.ToMessage(m)
}
return m
}
func (r *GetResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.GetResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
r.body = nil
} else {
if r.body == nil {
r.body = new(GetResponseBody)
}
err = r.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return r.ResponseHeaders.FromMessage(v)
}
func (r *DeleteRequestBody) ToGRPCMessage() grpc.Message {
var m *container.DeleteRequest_Body
if r != nil {
m = new(container.DeleteRequest_Body)
m.SetContainerId(r.cid.ToGRPCMessage().(*refsGRPC.ContainerID))
m.SetSignature(toSignatureRFC6979(r.sig))
}
return m
}
func (r *DeleteRequestBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.DeleteRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
cid := v.GetContainerId()
if cid == nil {
r.cid = nil
} else {
if r.cid == nil {
r.cid = new(refs.ContainerID)
}
err = r.cid.FromGRPCMessage(cid)
if err != nil {
return err
}
}
sig := v.GetSignature()
if sig == nil {
r.sig = nil
} else {
if r.sig == nil {
r.sig = new(refs.Signature)
}
r.sig.SetKey(sig.GetKey())
r.sig.SetSign(sig.GetSign())
}
return err
}
func (r *DeleteRequest) ToGRPCMessage() grpc.Message {
var m *container.DeleteRequest
if r != nil {
m = new(container.DeleteRequest)
m.SetBody(r.body.ToGRPCMessage().(*container.DeleteRequest_Body))
r.RequestHeaders.ToMessage(m)
}
return m
}
func (r *DeleteRequest) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.DeleteRequest)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
r.body = nil
} else {
if r.body == nil {
r.body = new(DeleteRequestBody)
}
err = r.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return r.RequestHeaders.FromMessage(v)
}
func (r *DeleteResponseBody) ToGRPCMessage() grpc.Message {
var m *container.DeleteResponse_Body
if r != nil {
m = new(container.DeleteResponse_Body)
}
return m
}
func (r *DeleteResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.DeleteResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
return nil
}
func (r *DeleteResponse) ToGRPCMessage() grpc.Message {
var m *container.DeleteResponse
if r != nil {
m = new(container.DeleteResponse)
m.SetBody(r.body.ToGRPCMessage().(*container.DeleteResponse_Body))
r.ResponseHeaders.ToMessage(m)
}
return m
}
func (r *DeleteResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.DeleteResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
r.body = nil
} else {
if r.body == nil {
r.body = new(DeleteResponseBody)
}
err = r.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return r.ResponseHeaders.FromMessage(v)
}
func (r *ListRequestBody) ToGRPCMessage() grpc.Message {
var m *container.ListRequest_Body
if r != nil {
m = new(container.ListRequest_Body)
m.SetOwnerId(r.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
}
return m
}
func (r *ListRequestBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.ListRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
ownerID := v.GetOwnerId()
if ownerID == nil {
r.ownerID = nil
} else {
if r.ownerID == nil {
r.ownerID = new(refs.OwnerID)
}
err = r.ownerID.FromGRPCMessage(ownerID)
}
return err
}
func (r *ListRequest) ToGRPCMessage() grpc.Message {
var m *container.ListRequest
if r != nil {
m = new(container.ListRequest)
m.SetBody(r.body.ToGRPCMessage().(*container.ListRequest_Body))
r.RequestHeaders.ToMessage(m)
}
return m
}
func (r *ListRequest) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.ListRequest)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
r.body = nil
} else {
if r.body == nil {
r.body = new(ListRequestBody)
}
err = r.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return r.RequestHeaders.FromMessage(v)
}
func (r *ListResponseBody) ToGRPCMessage() grpc.Message {
var m *container.ListResponse_Body
if r != nil {
m = new(container.ListResponse_Body)
m.SetContainerIds(refs.ContainerIDsToGRPCMessage(r.cidList))
}
return m
}
func (r *ListResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.ListResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
r.cidList, err = refs.ContainerIDsFromGRPCMessage(v.GetContainerIds())
return err
}
func (r *ListResponse) ToGRPCMessage() grpc.Message {
var m *container.ListResponse
if r != nil {
m = new(container.ListResponse)
m.SetBody(r.body.ToGRPCMessage().(*container.ListResponse_Body))
r.ResponseHeaders.ToMessage(m)
}
return m
}
func (r *ListResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*container.ListResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
r.body = nil
} else {
if r.body == nil {
r.body = new(ListResponseBody)
}
err = r.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return r.ResponseHeaders.FromMessage(v)
}

BIN
container/grpc/service_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,159 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package container
func DoFuzzProtoPutRequest(data []byte) int {
msg := new(PutRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONPutRequest(data []byte) int {
msg := new(PutRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoPutResponse(data []byte) int {
msg := new(PutResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONPutResponse(data []byte) int {
msg := new(PutResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoDeleteRequest(data []byte) int {
msg := new(DeleteRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONDeleteRequest(data []byte) int {
msg := new(DeleteRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoDeleteResponse(data []byte) int {
msg := new(DeleteResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONDeleteResponse(data []byte) int {
msg := new(DeleteResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoGetRequest(data []byte) int {
msg := new(GetRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONGetRequest(data []byte) int {
msg := new(GetRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoGetResponse(data []byte) int {
msg := new(GetResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONGetResponse(data []byte) int {
msg := new(GetResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoListRequest(data []byte) int {
msg := new(ListRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONListRequest(data []byte) int {
msg := new(ListRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoListResponse(data []byte) int {
msg := new(ListResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONListResponse(data []byte) int {
msg := new(ListResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,91 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package container
import (
testing "testing"
)
func FuzzProtoPutRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoPutRequest(data)
})
}
func FuzzJSONPutRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONPutRequest(data)
})
}
func FuzzProtoPutResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoPutResponse(data)
})
}
func FuzzJSONPutResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONPutResponse(data)
})
}
func FuzzProtoDeleteRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoDeleteRequest(data)
})
}
func FuzzJSONDeleteRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONDeleteRequest(data)
})
}
func FuzzProtoDeleteResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoDeleteResponse(data)
})
}
func FuzzJSONDeleteResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONDeleteResponse(data)
})
}
func FuzzProtoGetRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoGetRequest(data)
})
}
func FuzzJSONGetRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONGetRequest(data)
})
}
func FuzzProtoGetResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoGetResponse(data)
})
}
func FuzzJSONGetResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONGetResponse(data)
})
}
func FuzzProtoListRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoListRequest(data)
})
}
func FuzzJSONListRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONListRequest(data)
})
}
func FuzzProtoListResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoListResponse(data)
})
}
func FuzzJSONListResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONListResponse(data)
})
}

BIN
container/grpc/service_grpc.pb.go generated Normal file

Binary file not shown.

BIN
container/grpc/types_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,26 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package container
func DoFuzzProtoContainer(data []byte) int {
msg := new(Container)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONContainer(data []byte) int {
msg := new(Container)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,21 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package container
import (
testing "testing"
)
func FuzzProtoContainer(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoContainer(data)
})
}
func FuzzJSONContainer(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONContainer(data)
})
}

22
container/json.go Normal file
View file

@ -0,0 +1,22 @@
package container
import (
container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func (a *Attribute) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(a)
}
func (a *Attribute) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(a, data, new(container.Container_Attribute))
}
func (c *Container) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(c)
}
func (c *Container) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(c, data, new(container.Container))
}

345
container/marshal.go Normal file
View file

@ -0,0 +1,345 @@
package container
import (
container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
protoutil "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto"
)
const (
attributeKeyField = 1
attributeValueField = 2
containerVersionField = 1
containerOwnerField = 2
containerNonceField = 3
containerBasicACLField = 4
containerAttributesField = 5
containerPlacementField = 6
putReqBodyContainerField = 1
putReqBodySignatureField = 2
putRespBodyIDField = 1
deleteReqBodyIDField = 1
deleteReqBodySignatureField = 2
getReqBodyIDField = 1
getRespBodyContainerField = 1
getRespBodySignatureField = 2
getRespBodyTokenField = 3
listReqBodyOwnerField = 1
listRespBodyIDsField = 1
)
func (a *Attribute) StableMarshal(buf []byte) []byte {
if a == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, a.StableSize())
}
var offset int
offset += protoutil.StringMarshal(attributeKeyField, buf[offset:], a.key)
protoutil.StringMarshal(attributeValueField, buf[offset:], a.val)
return buf
}
func (a *Attribute) StableSize() (size int) {
if a == nil {
return 0
}
size += protoutil.StringSize(attributeKeyField, a.key)
size += protoutil.StringSize(attributeValueField, a.val)
return size
}
func (a *Attribute) Unmarshal(data []byte) error {
return message.Unmarshal(a, data, new(container.Container_Attribute))
}
func (c *Container) StableMarshal(buf []byte) []byte {
if c == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, c.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(containerVersionField, buf[offset:], c.version)
offset += protoutil.NestedStructureMarshal(containerOwnerField, buf[offset:], c.ownerID)
offset += protoutil.BytesMarshal(containerNonceField, buf[offset:], c.nonce)
offset += protoutil.UInt32Marshal(containerBasicACLField, buf[offset:], c.basicACL)
for i := range c.attr {
offset += protoutil.NestedStructureMarshal(containerAttributesField, buf[offset:], &c.attr[i])
}
protoutil.NestedStructureMarshal(containerPlacementField, buf[offset:], c.policy)
return buf
}
func (c *Container) StableSize() (size int) {
if c == nil {
return 0
}
size += protoutil.NestedStructureSize(containerVersionField, c.version)
size += protoutil.NestedStructureSize(containerOwnerField, c.ownerID)
size += protoutil.BytesSize(containerNonceField, c.nonce)
size += protoutil.UInt32Size(containerBasicACLField, c.basicACL)
for i := range c.attr {
size += protoutil.NestedStructureSize(containerAttributesField, &c.attr[i])
}
size += protoutil.NestedStructureSize(containerPlacementField, c.policy)
return size
}
func (c *Container) Unmarshal(data []byte) error {
return message.Unmarshal(c, data, new(container.Container))
}
func (r *PutRequestBody) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(putReqBodyContainerField, buf[offset:], r.cnr)
protoutil.NestedStructureMarshal(putReqBodySignatureField, buf[offset:], r.sig)
return buf
}
func (r *PutRequestBody) StableSize() (size int) {
if r == nil {
return 0
}
size += protoutil.NestedStructureSize(putReqBodyContainerField, r.cnr)
size += protoutil.NestedStructureSize(putReqBodySignatureField, r.sig)
return size
}
func (r *PutRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.PutRequest_Body))
}
func (r *PutResponseBody) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
protoutil.NestedStructureMarshal(putRespBodyIDField, buf, r.cid)
return buf
}
func (r *PutResponseBody) StableSize() (size int) {
if r == nil {
return 0
}
size += protoutil.NestedStructureSize(putRespBodyIDField, r.cid)
return size
}
func (r *PutResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.PutResponse_Body))
}
func (r *DeleteRequestBody) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(deleteReqBodyIDField, buf[offset:], r.cid)
protoutil.NestedStructureMarshal(deleteReqBodySignatureField, buf[offset:], r.sig)
return buf
}
func (r *DeleteRequestBody) StableSize() (size int) {
if r == nil {
return 0
}
size += protoutil.NestedStructureSize(deleteReqBodyIDField, r.cid)
size += protoutil.NestedStructureSize(deleteReqBodySignatureField, r.sig)
return size
}
func (r *DeleteRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.DeleteRequest_Body))
}
func (r *DeleteResponseBody) StableMarshal(_ []byte) []byte {
return nil
}
func (r *DeleteResponseBody) StableSize() (size int) {
return 0
}
func (r *DeleteResponseBody) Unmarshal([]byte) error {
return nil
}
func (r *GetRequestBody) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
protoutil.NestedStructureMarshal(getReqBodyIDField, buf, r.cid)
return buf
}
func (r *GetRequestBody) StableSize() (size int) {
if r == nil {
return 0
}
size += protoutil.NestedStructureSize(getReqBodyIDField, r.cid)
return size
}
func (r *GetRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.GetRequest_Body))
}
func (r *GetResponseBody) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(getRespBodyContainerField, buf, r.cnr)
offset += protoutil.NestedStructureMarshal(getRespBodySignatureField, buf[offset:], r.sig)
protoutil.NestedStructureMarshal(getRespBodyTokenField, buf[offset:], r.token)
return buf
}
func (r *GetResponseBody) StableSize() (size int) {
if r == nil {
return 0
}
size += protoutil.NestedStructureSize(getRespBodyContainerField, r.cnr)
size += protoutil.NestedStructureSize(getRespBodySignatureField, r.sig)
size += protoutil.NestedStructureSize(getRespBodyTokenField, r.token)
return size
}
func (r *GetResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.GetResponse_Body))
}
func (r *ListRequestBody) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
protoutil.NestedStructureMarshal(listReqBodyOwnerField, buf, r.ownerID)
return buf
}
func (r *ListRequestBody) StableSize() (size int) {
if r == nil {
return 0
}
size += protoutil.NestedStructureSize(listReqBodyOwnerField, r.ownerID)
return size
}
func (r *ListRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.ListRequest_Body))
}
func (r *ListResponseBody) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
var offset int
for i := range r.cidList {
offset += protoutil.NestedStructureMarshal(listRespBodyIDsField, buf[offset:], &r.cidList[i])
}
return buf
}
func (r *ListResponseBody) StableSize() (size int) {
if r == nil {
return 0
}
for i := range r.cidList {
size += protoutil.NestedStructureSize(listRespBodyIDsField, &r.cidList[i])
}
return size
}
func (r *ListResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.ListResponse_Body))
}

36
container/message_test.go Normal file
View file

@ -0,0 +1,36 @@
package container_test
import (
"testing"
containertest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container/test"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
messagetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return containertest.GenerateAttribute(empty) },
func(empty bool) message.Message { return containertest.GenerateContainer(empty) },
func(empty bool) message.Message { return containertest.GeneratePutRequestBody(empty) },
func(empty bool) message.Message { return containertest.GeneratePutRequest(empty) },
func(empty bool) message.Message { return containertest.GeneratePutResponseBody(empty) },
func(empty bool) message.Message { return containertest.GeneratePutResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateGetRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateGetRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateGetResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateGetResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateDeleteRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateDeleteRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateDeleteResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateDeleteResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateListRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateListRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateListResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateListResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateGetRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateGetRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateGetResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateGetResponse(empty) },
)
}

33
container/status.go Normal file
View file

@ -0,0 +1,33 @@
package container
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/status"
statusgrpc "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/status/grpc"
)
// LocalizeFailStatus checks if passed global status.Code is related to container failure and:
//
// then localizes the code and returns true,
// else leaves the code unchanged and returns false.
//
// Arg must not be nil.
func LocalizeFailStatus(c *status.Code) bool {
return status.LocalizeIfInSection(c, uint32(statusgrpc.Section_SECTION_CONTAINER))
}
// GlobalizeFail globalizes local code of container failure.
//
// Arg must not be nil.
func GlobalizeFail(c *status.Code) {
c.GlobalizeSection(uint32(statusgrpc.Section_SECTION_CONTAINER))
}
const (
// StatusNotFound is a local status.Code value for
// CONTAINER_NOT_FOUND container failure.
StatusNotFound status.Code = iota
// StatusEACLNotFound is a local status.Code value for
// EACL_NOT_FOUND failure.
StatusEACLNotFound
)

15
container/status_test.go Normal file
View file

@ -0,0 +1,15 @@
package container_test
import (
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
statustest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/status/test"
)
func TestStatusCodes(t *testing.T) {
statustest.TestCodes(t, container.LocalizeFailStatus, container.GlobalizeFail,
container.StatusNotFound, 3072,
container.StatusEACLNotFound, 3073,
)
}

240
container/test/generate.go Normal file
View file

@ -0,0 +1,240 @@
package containertest
import (
"crypto/rand"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/test"
refstest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/test"
sessiontest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session/test"
)
func GenerateAttribute(empty bool) *container.Attribute {
m := new(container.Attribute)
if !empty {
m.SetKey("key")
m.SetValue("val")
}
return m
}
func GenerateAttributes(empty bool) []container.Attribute {
var res []container.Attribute
if !empty {
res = append(res,
*GenerateAttribute(false),
*GenerateAttribute(false),
)
}
return res
}
func GenerateContainer(empty bool) *container.Container {
m := new(container.Container)
if !empty {
nonce := make([]byte, 16)
_, _ = rand.Read(nonce)
m.SetBasicACL(12)
m.SetNonce(nonce)
m.SetOwnerID(refstest.GenerateOwnerID(false))
m.SetAttributes(GenerateAttributes(false))
m.SetPlacementPolicy(netmaptest.GeneratePlacementPolicy(false))
}
m.SetVersion(refstest.GenerateVersion(empty))
return m
}
func GeneratePutRequestBody(empty bool) *container.PutRequestBody {
m := new(container.PutRequestBody)
if !empty {
m.SetContainer(GenerateContainer(false))
}
m.SetSignature(refstest.GenerateSignature(empty))
return m
}
func GeneratePutRequest(empty bool) *container.PutRequest {
m := new(container.PutRequest)
if !empty {
m.SetBody(GeneratePutRequestBody(false))
}
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GeneratePutResponseBody(empty bool) *container.PutResponseBody {
m := new(container.PutResponseBody)
if !empty {
m.SetContainerID(refstest.GenerateContainerID(false))
}
return m
}
func GeneratePutResponse(empty bool) *container.PutResponse {
m := new(container.PutResponse)
if !empty {
m.SetBody(GeneratePutResponseBody(false))
}
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateGetRequestBody(empty bool) *container.GetRequestBody {
m := new(container.GetRequestBody)
if !empty {
m.SetContainerID(refstest.GenerateContainerID(false))
}
return m
}
func GenerateGetRequest(empty bool) *container.GetRequest {
m := new(container.GetRequest)
if !empty {
m.SetBody(GenerateGetRequestBody(false))
}
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateGetResponseBody(empty bool) *container.GetResponseBody {
m := new(container.GetResponseBody)
if !empty {
m.SetContainer(GenerateContainer(false))
}
m.SetSignature(refstest.GenerateSignature(empty))
m.SetSessionToken(sessiontest.GenerateSessionToken(empty))
return m
}
func GenerateGetResponse(empty bool) *container.GetResponse {
m := new(container.GetResponse)
if !empty {
m.SetBody(GenerateGetResponseBody(false))
}
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateDeleteRequestBody(empty bool) *container.DeleteRequestBody {
m := new(container.DeleteRequestBody)
if !empty {
m.SetContainerID(refstest.GenerateContainerID(false))
}
m.SetSignature(refstest.GenerateSignature(empty))
return m
}
func GenerateDeleteRequest(empty bool) *container.DeleteRequest {
m := new(container.DeleteRequest)
if !empty {
m.SetBody(GenerateDeleteRequestBody(false))
}
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateDeleteResponseBody(_ bool) *container.DeleteResponseBody {
m := new(container.DeleteResponseBody)
return m
}
func GenerateDeleteResponse(empty bool) *container.DeleteResponse {
m := new(container.DeleteResponse)
if !empty {
m.SetBody(GenerateDeleteResponseBody(false))
}
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateListRequestBody(empty bool) *container.ListRequestBody {
m := new(container.ListRequestBody)
if !empty {
m.SetOwnerID(refstest.GenerateOwnerID(false))
}
return m
}
func GenerateListRequest(empty bool) *container.ListRequest {
m := new(container.ListRequest)
if !empty {
m.SetBody(GenerateListRequestBody(false))
}
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateListResponseBody(empty bool) *container.ListResponseBody {
m := new(container.ListResponseBody)
if !empty {
m.SetContainerIDs(refstest.GenerateContainerIDs(false))
}
return m
}
func GenerateListResponse(empty bool) *container.ListResponse {
m := new(container.ListResponse)
if !empty {
m.SetBody(GenerateListResponseBody(false))
}
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}

446
container/types.go Normal file
View file

@ -0,0 +1,446 @@
package container
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
)
type Attribute struct {
key, val string
}
type Container struct {
version *refs.Version
ownerID *refs.OwnerID
nonce []byte
basicACL uint32
attr []Attribute
policy *netmap.PlacementPolicy
}
type PutRequestBody struct {
cnr *Container
sig *refs.Signature
}
type PutRequest struct {
body *PutRequestBody
session.RequestHeaders
}
type PutResponseBody struct {
cid *refs.ContainerID
}
type PutResponse struct {
body *PutResponseBody
session.ResponseHeaders
}
type GetRequestBody struct {
cid *refs.ContainerID
}
type GetRequest struct {
body *GetRequestBody
session.RequestHeaders
}
type GetResponseBody struct {
cnr *Container
token *session.Token
sig *refs.Signature
}
type GetResponse struct {
body *GetResponseBody
session.ResponseHeaders
}
type DeleteRequestBody struct {
cid *refs.ContainerID
sig *refs.Signature
}
type DeleteRequest struct {
body *DeleteRequestBody
session.RequestHeaders
}
type DeleteResponseBody struct{}
type DeleteResponse struct {
body *DeleteResponseBody
session.ResponseHeaders
}
type ListRequestBody struct {
ownerID *refs.OwnerID
}
type ListRequest struct {
body *ListRequestBody
session.RequestHeaders
}
type ListResponseBody struct {
cidList []refs.ContainerID
}
type ListResponse struct {
body *ListResponseBody
session.ResponseHeaders
}
func (a *Attribute) GetKey() string {
if a != nil {
return a.key
}
return ""
}
func (a *Attribute) SetKey(v string) {
a.key = v
}
func (a *Attribute) GetValue() string {
if a != nil {
return a.val
}
return ""
}
func (a *Attribute) SetValue(v string) {
a.val = v
}
func (c *Container) GetVersion() *refs.Version {
if c != nil {
return c.version
}
return nil
}
func (c *Container) SetVersion(v *refs.Version) {
c.version = v
}
func (c *Container) GetOwnerID() *refs.OwnerID {
if c != nil {
return c.ownerID
}
return nil
}
func (c *Container) SetOwnerID(v *refs.OwnerID) {
c.ownerID = v
}
func (c *Container) GetNonce() []byte {
if c != nil {
return c.nonce
}
return nil
}
func (c *Container) SetNonce(v []byte) {
c.nonce = v
}
func (c *Container) GetBasicACL() uint32 {
if c != nil {
return c.basicACL
}
return 0
}
func (c *Container) SetBasicACL(v uint32) {
c.basicACL = v
}
func (c *Container) GetAttributes() []Attribute {
if c != nil {
return c.attr
}
return nil
}
func (c *Container) SetAttributes(v []Attribute) {
c.attr = v
}
func (c *Container) GetPlacementPolicy() *netmap.PlacementPolicy {
if c != nil {
return c.policy
}
return nil
}
func (c *Container) SetPlacementPolicy(v *netmap.PlacementPolicy) {
c.policy = v
}
func (r *PutRequestBody) GetContainer() *Container {
if r != nil {
return r.cnr
}
return nil
}
func (r *PutRequestBody) SetContainer(v *Container) {
r.cnr = v
}
func (r *PutRequestBody) GetSignature() *refs.Signature {
if r != nil {
return r.sig
}
return nil
}
func (r *PutRequestBody) SetSignature(v *refs.Signature) {
// TODO: (neofs-api-go#381) avoid this hack (e.g. create refs.SignatureRFC6979 type)
v.SetScheme(0)
r.sig = v
}
func (r *PutRequest) GetBody() *PutRequestBody {
if r != nil {
return r.body
}
return nil
}
func (r *PutRequest) SetBody(v *PutRequestBody) {
r.body = v
}
func (r *PutResponseBody) GetContainerID() *refs.ContainerID {
if r != nil {
return r.cid
}
return nil
}
func (r *PutResponseBody) SetContainerID(v *refs.ContainerID) {
r.cid = v
}
func (r *PutResponse) GetBody() *PutResponseBody {
if r != nil {
return r.body
}
return nil
}
func (r *PutResponse) SetBody(v *PutResponseBody) {
r.body = v
}
func (r *GetRequestBody) GetContainerID() *refs.ContainerID {
if r != nil {
return r.cid
}
return nil
}
func (r *GetRequestBody) SetContainerID(v *refs.ContainerID) {
r.cid = v
}
func (r *GetRequest) GetBody() *GetRequestBody {
if r != nil {
return r.body
}
return nil
}
func (r *GetRequest) SetBody(v *GetRequestBody) {
r.body = v
}
func (r *GetResponseBody) GetContainer() *Container {
if r != nil {
return r.cnr
}
return nil
}
func (r *GetResponseBody) SetContainer(v *Container) {
r.cnr = v
}
// GetSessionToken returns token of the session within which requested
// container was created.
func (r *GetResponseBody) GetSessionToken() *session.Token {
if r != nil {
return r.token
}
return nil
}
// SetSessionToken sets token of the session within which requested
// container was created.
func (r *GetResponseBody) SetSessionToken(v *session.Token) {
r.token = v
}
// GetSignature returns signature of the requested container.
func (r *GetResponseBody) GetSignature() *refs.Signature {
if r != nil {
return r.sig
}
return nil
}
// SetSignature sets signature of the requested container.
func (r *GetResponseBody) SetSignature(v *refs.Signature) {
// TODO: (neofs-api-go#381) avoid this hack (e.g. create refs.SignatureRFC6979 type)
v.SetScheme(0)
r.sig = v
}
func (r *GetResponse) GetBody() *GetResponseBody {
if r != nil {
return r.body
}
return nil
}
func (r *GetResponse) SetBody(v *GetResponseBody) {
r.body = v
}
func (r *DeleteRequestBody) GetContainerID() *refs.ContainerID {
if r != nil {
return r.cid
}
return nil
}
func (r *DeleteRequestBody) SetContainerID(v *refs.ContainerID) {
r.cid = v
}
func (r *DeleteRequestBody) GetSignature() *refs.Signature {
if r != nil {
return r.sig
}
return nil
}
func (r *DeleteRequestBody) SetSignature(v *refs.Signature) {
// TODO: (neofs-api-go#381) avoid this hack (e.g. create refs.SignatureRFC6979 type)
v.SetScheme(0)
r.sig = v
}
func (r *DeleteRequest) GetBody() *DeleteRequestBody {
if r != nil {
return r.body
}
return nil
}
func (r *DeleteRequest) SetBody(v *DeleteRequestBody) {
r.body = v
}
func (r *DeleteResponse) GetBody() *DeleteResponseBody {
if r != nil {
return r.body
}
return nil
}
func (r *DeleteResponse) SetBody(v *DeleteResponseBody) {
r.body = v
}
func (r *ListRequestBody) GetOwnerID() *refs.OwnerID {
if r != nil {
return r.ownerID
}
return nil
}
func (r *ListRequestBody) SetOwnerID(v *refs.OwnerID) {
r.ownerID = v
}
func (r *ListRequest) GetBody() *ListRequestBody {
if r != nil {
return r.body
}
return nil
}
func (r *ListRequest) SetBody(v *ListRequestBody) {
r.body = v
}
func (r *ListResponseBody) GetContainerIDs() []refs.ContainerID {
if r != nil {
return r.cidList
}
return nil
}
func (r *ListResponseBody) SetContainerIDs(v []refs.ContainerID) {
r.cidList = v
}
func (r *ListResponse) GetBody() *ListResponseBody {
if r != nil {
return r.body
}
return nil
}
func (r *ListResponse) SetBody(v *ListResponseBody) {
r.body = v
}

0
docs/.gitkeep Normal file
View file

View file

@ -0,0 +1,45 @@
# Release instructions
## Pre-release checks
These should run successfully:
* `go test ./...`;
* `golangci-lint run ./...`;
* `go fmt ./...` (should not change any files);
* `go mog tidy` (should not change any files);
* `./prepare.sh /path/to/frostfs-api/on/your/machine` (should not change any files).
## Writing changelog
Add an entry to the `CHANGELOG.md` following the style established there. Add an
optional codename(for not patch releases), version and release date in the heading.
Write a paragraph describing the most significant changes done in this release. Add
`Fixed`, `Added`, `Removed` and `Updated` sections with fixed bug, new features and
other changes.
Open Pull Request (must receive at least one approval) and merge this changes.
## Update README
Actualize compatibility table in `README.md` with relevant information.
## Tag a release
Use `vX.Y.Z` tag for releases and `vX.Y.Z-rc.N` for release candidates
following the [semantic versioning](https://semver.org/) standard.
Update your local `master` branch after approved and merged `CHANGELOG.md` changes.
Tag a release (must be signed) and push it:
```
$ git tag -s vX.Y.Z[-rc.N] && git push origin vX.Y.Z[-rc.N]
```
## Make a Github release
Using Github's web interface create a new release based on just created tag
with the same changes from changelog and publish it.
## Close github milestone
Close corresponding vX.Y.Z github milestone.

28
go.mod Normal file
View file

@ -0,0 +1,28 @@
module git.frostfs.info/TrueCloudLab/frostfs-api-go/v2
go 1.22
require (
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0
github.com/VictoriaMetrics/easyproto v0.1.4
github.com/mailru/easyjson v0.7.7
github.com/stretchr/testify v1.8.3
golang.org/x/sync v0.7.0
google.golang.org/grpc v1.66.2
google.golang.org/protobuf v1.34.1
)
require (
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

48
go.sum Normal file
View file

@ -0,0 +1,48 @@
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 h1:FxqFDhQYYgpe41qsIHVOcdzSVCB8JNSfPG7Uk4r2oSk=
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0/go.mod h1:RUIKZATQLJ+TaYQa60X2fTDwfuhMfm8Ar60bQ5fr+vU=
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 h1:M2KR3iBj7WpY3hP10IevfIB9MURr4O9mwVfJ+SjT3HA=
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0/go.mod h1:okpbKfVYf/BpejtfFTfhZqFP+sZ8rsHrP8Rr/jYPNRc=
github.com/VictoriaMetrics/easyproto v0.1.4 h1:r8cNvo8o6sR4QShBXQd1bKw/VVLSQma/V2KhTBPf+Sc=
github.com/VictoriaMetrics/easyproto v0.1.4/go.mod h1:QlGlzaJnDfFd8Lk6Ci/fuLxfTo3/GThPs2KH23mv710=
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/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
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/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
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/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

BIN
lock/grpc/types_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,26 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package lock
func DoFuzzProtoLock(data []byte) int {
msg := new(Lock)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONLock(data []byte) int {
msg := new(Lock)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,21 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package lock
import (
testing "testing"
)
func FuzzProtoLock(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoLock(data)
})
}
func FuzzJSONLock(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONLock(data)
})
}

916
netmap/convert.go Normal file
View file

@ -0,0 +1,916 @@
package netmap
import (
netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
refsGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func (f *Filter) ToGRPCMessage() grpc.Message {
var m *netmap.Filter
if f != nil {
m = new(netmap.Filter)
m.SetKey(f.key)
m.SetValue(f.value)
m.SetName(f.name)
m.SetOp(OperationToGRPCMessage(f.op))
m.SetFilters(FiltersToGRPC(f.filters))
}
return m
}
func (f *Filter) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.Filter)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
f.filters, err = FiltersFromGRPC(v.GetFilters())
if err != nil {
return err
}
f.key = v.GetKey()
f.value = v.GetValue()
f.name = v.GetName()
f.op = OperationFromGRPCMessage(v.GetOp())
return nil
}
func FiltersToGRPC(fs []Filter) (res []netmap.Filter) {
if fs != nil {
res = make([]netmap.Filter, 0, len(fs))
for i := range fs {
res = append(res, *fs[i].ToGRPCMessage().(*netmap.Filter))
}
}
return
}
func FiltersFromGRPC(fs []netmap.Filter) (res []Filter, err error) {
if fs != nil {
res = make([]Filter, len(fs))
for i := range fs {
err = res[i].FromGRPCMessage(&fs[i])
if err != nil {
return
}
}
}
return
}
func (s *Selector) ToGRPCMessage() grpc.Message {
var m *netmap.Selector
if s != nil {
m = new(netmap.Selector)
m.SetName(s.name)
m.SetAttribute(s.attribute)
m.SetFilter(s.filter)
m.SetCount(s.count)
m.SetClause(ClauseToGRPCMessage(s.clause))
}
return m
}
func (s *Selector) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.Selector)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
s.name = v.GetName()
s.attribute = v.GetAttribute()
s.filter = v.GetFilter()
s.count = v.GetCount()
s.clause = ClauseFromGRPCMessage(v.GetClause())
return nil
}
func SelectorsToGRPC(ss []Selector) (res []netmap.Selector) {
if ss != nil {
res = make([]netmap.Selector, 0, len(ss))
for i := range ss {
res = append(res, *ss[i].ToGRPCMessage().(*netmap.Selector))
}
}
return
}
func SelectorsFromGRPC(ss []netmap.Selector) (res []Selector, err error) {
if ss != nil {
res = make([]Selector, len(ss))
for i := range ss {
err = res[i].FromGRPCMessage(&ss[i])
if err != nil {
return
}
}
}
return
}
func (r *Replica) ToGRPCMessage() grpc.Message {
var m *netmap.Replica
if r != nil {
m = new(netmap.Replica)
m.SetSelector(r.selector)
m.SetCount(r.count)
m.EcDataCount = r.ecDataCount
m.EcParityCount = r.ecParityCount
}
return m
}
func (r *Replica) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.Replica)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
r.selector = v.GetSelector()
r.count = v.GetCount()
r.ecDataCount = v.GetEcDataCount()
r.ecParityCount = v.GetEcParityCount()
return nil
}
func ReplicasToGRPC(rs []Replica) (res []netmap.Replica) {
if rs != nil {
res = make([]netmap.Replica, 0, len(rs))
for i := range rs {
res = append(res, *rs[i].ToGRPCMessage().(*netmap.Replica))
}
}
return
}
func ReplicasFromGRPC(rs []netmap.Replica) (res []Replica, err error) {
if rs != nil {
res = make([]Replica, len(rs))
for i := range rs {
err = res[i].FromGRPCMessage(&rs[i])
if err != nil {
return
}
}
}
return
}
func (p *PlacementPolicy) ToGRPCMessage() grpc.Message {
var m *netmap.PlacementPolicy
if p != nil {
m = new(netmap.PlacementPolicy)
m.SetFilters(FiltersToGRPC(p.filters))
m.SetSelectors(SelectorsToGRPC(p.selectors))
m.SetReplicas(ReplicasToGRPC(p.replicas))
m.SetContainerBackupFactor(p.backupFactor)
m.SetUnique(p.unique)
}
return m
}
func (p *PlacementPolicy) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.PlacementPolicy)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
p.filters, err = FiltersFromGRPC(v.GetFilters())
if err != nil {
return err
}
p.selectors, err = SelectorsFromGRPC(v.GetSelectors())
if err != nil {
return err
}
p.replicas, err = ReplicasFromGRPC(v.GetReplicas())
if err != nil {
return err
}
p.backupFactor = v.GetContainerBackupFactor()
p.unique = v.GetUnique()
return nil
}
func ClauseToGRPCMessage(n Clause) netmap.Clause {
return netmap.Clause(n)
}
func ClauseFromGRPCMessage(n netmap.Clause) Clause {
return Clause(n)
}
func OperationToGRPCMessage(n Operation) netmap.Operation {
return netmap.Operation(n)
}
func OperationFromGRPCMessage(n netmap.Operation) Operation {
return Operation(n)
}
func NodeStateToGRPCMessage(n NodeState) netmap.NodeInfo_State {
return netmap.NodeInfo_State(n)
}
func NodeStateFromRPCMessage(n netmap.NodeInfo_State) NodeState {
return NodeState(n)
}
func (a *Attribute) ToGRPCMessage() grpc.Message {
var m *netmap.NodeInfo_Attribute
if a != nil {
m = new(netmap.NodeInfo_Attribute)
m.SetKey(a.key)
m.SetValue(a.value)
m.SetParents(a.parents)
}
return m
}
func (a *Attribute) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NodeInfo_Attribute)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
a.key = v.GetKey()
a.value = v.GetValue()
a.parents = v.GetParents()
return nil
}
func AttributesToGRPC(as []Attribute) (res []netmap.NodeInfo_Attribute) {
if as != nil {
res = make([]netmap.NodeInfo_Attribute, 0, len(as))
for i := range as {
res = append(res, *as[i].ToGRPCMessage().(*netmap.NodeInfo_Attribute))
}
}
return
}
func AttributesFromGRPC(as []netmap.NodeInfo_Attribute) (res []Attribute, err error) {
if as != nil {
res = make([]Attribute, len(as))
for i := range as {
err = res[i].FromGRPCMessage(&as[i])
if err != nil {
return
}
}
}
return
}
func (ni *NodeInfo) ToGRPCMessage() grpc.Message {
var m *netmap.NodeInfo
if ni != nil {
m = new(netmap.NodeInfo)
m.SetPublicKey(ni.publicKey)
m.SetAddresses(ni.addresses)
m.SetState(NodeStateToGRPCMessage(ni.state))
m.SetAttributes(AttributesToGRPC(ni.attributes))
}
return m
}
func (ni *NodeInfo) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NodeInfo)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
ni.attributes, err = AttributesFromGRPC(v.GetAttributes())
if err != nil {
return err
}
ni.publicKey = v.GetPublicKey()
ni.addresses = v.GetAddresses()
ni.state = NodeStateFromRPCMessage(v.GetState())
return nil
}
func (l *LocalNodeInfoRequestBody) ToGRPCMessage() grpc.Message {
var m *netmap.LocalNodeInfoRequest_Body
if l != nil {
m = new(netmap.LocalNodeInfoRequest_Body)
}
return m
}
func (l *LocalNodeInfoRequestBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.LocalNodeInfoRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
return nil
}
func (l *LocalNodeInfoRequest) ToGRPCMessage() grpc.Message {
var m *netmap.LocalNodeInfoRequest
if l != nil {
m = new(netmap.LocalNodeInfoRequest)
m.SetBody(l.body.ToGRPCMessage().(*netmap.LocalNodeInfoRequest_Body))
l.RequestHeaders.ToMessage(m)
}
return m
}
func (l *LocalNodeInfoRequest) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.LocalNodeInfoRequest)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
l.body = nil
} else {
if l.body == nil {
l.body = new(LocalNodeInfoRequestBody)
}
err = l.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return l.RequestHeaders.FromMessage(v)
}
func (l *LocalNodeInfoResponseBody) ToGRPCMessage() grpc.Message {
var m *netmap.LocalNodeInfoResponse_Body
if l != nil {
m = new(netmap.LocalNodeInfoResponse_Body)
m.SetVersion(l.version.ToGRPCMessage().(*refsGRPC.Version))
m.SetNodeInfo(l.nodeInfo.ToGRPCMessage().(*netmap.NodeInfo))
}
return m
}
func (l *LocalNodeInfoResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.LocalNodeInfoResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
version := v.GetVersion()
if version == nil {
l.version = nil
} else {
if l.version == nil {
l.version = new(refs.Version)
}
err = l.version.FromGRPCMessage(version)
if err != nil {
return err
}
}
nodeInfo := v.GetNodeInfo()
if nodeInfo == nil {
l.nodeInfo = nil
} else {
if l.nodeInfo == nil {
l.nodeInfo = new(NodeInfo)
}
err = l.nodeInfo.FromGRPCMessage(nodeInfo)
}
return err
}
func (l *LocalNodeInfoResponse) ToGRPCMessage() grpc.Message {
var m *netmap.LocalNodeInfoResponse
if l != nil {
m = new(netmap.LocalNodeInfoResponse)
m.SetBody(l.body.ToGRPCMessage().(*netmap.LocalNodeInfoResponse_Body))
l.ResponseHeaders.ToMessage(m)
}
return m
}
func (l *LocalNodeInfoResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.LocalNodeInfoResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
l.body = nil
} else {
if l.body == nil {
l.body = new(LocalNodeInfoResponseBody)
}
err = l.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return l.ResponseHeaders.FromMessage(v)
}
func (x *NetworkParameter) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkConfig_Parameter
if x != nil {
m = new(netmap.NetworkConfig_Parameter)
m.SetKey(x.k)
m.SetValue(x.v)
}
return m
}
func (x *NetworkParameter) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkConfig_Parameter)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
x.k = v.GetKey()
x.v = v.GetValue()
return nil
}
func (x *NetworkConfig) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkConfig
if x != nil {
m = new(netmap.NetworkConfig)
var ps []netmap.NetworkConfig_Parameter
if ln := len(x.ps); ln > 0 {
ps = make([]netmap.NetworkConfig_Parameter, 0, ln)
for i := range ln {
ps = append(ps, *x.ps[i].ToGRPCMessage().(*netmap.NetworkConfig_Parameter))
}
}
m.SetParameters(ps)
}
return m
}
func (x *NetworkConfig) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkConfig)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var (
ps []NetworkParameter
psV2 = v.GetParameters()
)
if psV2 != nil {
ln := len(psV2)
ps = make([]NetworkParameter, ln)
for i := range ln {
if err := ps[i].FromGRPCMessage(&psV2[i]); err != nil {
return err
}
}
}
x.ps = ps
return nil
}
func (i *NetworkInfo) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkInfo
if i != nil {
m = new(netmap.NetworkInfo)
m.SetMagicNumber(i.magicNum)
m.SetCurrentEpoch(i.curEpoch)
m.SetMsPerBlock(i.msPerBlock)
m.SetNetworkConfig(i.netCfg.ToGRPCMessage().(*netmap.NetworkConfig))
}
return m
}
func (i *NetworkInfo) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkInfo)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
netCfg := v.GetNetworkConfig()
if netCfg == nil {
i.netCfg = nil
} else {
if i.netCfg == nil {
i.netCfg = new(NetworkConfig)
}
err = i.netCfg.FromGRPCMessage(netCfg)
if err != nil {
return err
}
}
i.magicNum = v.GetMagicNumber()
i.curEpoch = v.GetCurrentEpoch()
i.msPerBlock = v.GetMsPerBlock()
return nil
}
func (l *NetworkInfoRequestBody) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkInfoRequest_Body
if l != nil {
m = new(netmap.NetworkInfoRequest_Body)
}
return m
}
func (l *NetworkInfoRequestBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkInfoRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
return nil
}
func (l *NetworkInfoRequest) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkInfoRequest
if l != nil {
m = new(netmap.NetworkInfoRequest)
m.SetBody(l.body.ToGRPCMessage().(*netmap.NetworkInfoRequest_Body))
l.RequestHeaders.ToMessage(m)
}
return m
}
func (l *NetworkInfoRequest) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkInfoRequest)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
l.body = nil
} else {
if l.body == nil {
l.body = new(NetworkInfoRequestBody)
}
err = l.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return l.RequestHeaders.FromMessage(v)
}
func (i *NetworkInfoResponseBody) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkInfoResponse_Body
if i != nil {
m = new(netmap.NetworkInfoResponse_Body)
m.SetNetworkInfo(i.netInfo.ToGRPCMessage().(*netmap.NetworkInfo))
}
return m
}
func (i *NetworkInfoResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkInfoResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
netInfo := v.GetNetworkInfo()
if netInfo == nil {
i.netInfo = nil
} else {
if i.netInfo == nil {
i.netInfo = new(NetworkInfo)
}
err = i.netInfo.FromGRPCMessage(netInfo)
}
return err
}
func (l *NetworkInfoResponse) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkInfoResponse
if l != nil {
m = new(netmap.NetworkInfoResponse)
m.SetBody(l.body.ToGRPCMessage().(*netmap.NetworkInfoResponse_Body))
l.ResponseHeaders.ToMessage(m)
}
return m
}
func (l *NetworkInfoResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkInfoResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
l.body = nil
} else {
if l.body == nil {
l.body = new(NetworkInfoResponseBody)
}
err = l.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return l.ResponseHeaders.FromMessage(v)
}
func (x *NetMap) ToGRPCMessage() grpc.Message {
var m *netmap.Netmap
if x != nil {
m = new(netmap.Netmap)
m.SetEpoch(x.epoch)
if x.nodes != nil {
nodes := make([]netmap.NodeInfo, len(x.nodes))
for i := range x.nodes {
nodes[i] = *x.nodes[i].ToGRPCMessage().(*netmap.NodeInfo)
}
m.SetNodes(nodes)
}
}
return m
}
func (x *NetMap) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.Netmap)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
nodes := v.GetNodes()
if nodes == nil {
x.nodes = nil
} else {
x.nodes = make([]NodeInfo, len(nodes))
for i := range nodes {
err = x.nodes[i].FromGRPCMessage(&nodes[i])
if err != nil {
return err
}
}
}
x.epoch = v.GetEpoch()
return nil
}
func (x *SnapshotRequestBody) ToGRPCMessage() grpc.Message {
var m *netmap.NetmapSnapshotRequest_Body
if x != nil {
m = new(netmap.NetmapSnapshotRequest_Body)
}
return m
}
func (x *SnapshotRequestBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetmapSnapshotRequest_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
return nil
}
func (x *SnapshotRequest) ToGRPCMessage() grpc.Message {
var m *netmap.NetmapSnapshotRequest
if x != nil {
m = new(netmap.NetmapSnapshotRequest)
m.SetBody(x.body.ToGRPCMessage().(*netmap.NetmapSnapshotRequest_Body))
x.RequestHeaders.ToMessage(m)
}
return m
}
func (x *SnapshotRequest) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetmapSnapshotRequest)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
x.body = nil
} else {
if x.body == nil {
x.body = new(SnapshotRequestBody)
}
err = x.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return x.RequestHeaders.FromMessage(v)
}
func (x *SnapshotResponseBody) ToGRPCMessage() grpc.Message {
var m *netmap.NetmapSnapshotResponse_Body
if x != nil {
m = new(netmap.NetmapSnapshotResponse_Body)
m.SetNetmap(x.netMap.ToGRPCMessage().(*netmap.Netmap))
}
return m
}
func (x *SnapshotResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetmapSnapshotResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
netMap := v.GetNetmap()
if netMap == nil {
x.netMap = nil
} else {
if x.netMap == nil {
x.netMap = new(NetMap)
}
err = x.netMap.FromGRPCMessage(netMap)
}
return err
}
func (x *SnapshotResponse) ToGRPCMessage() grpc.Message {
var m *netmap.NetmapSnapshotResponse
if x != nil {
m = new(netmap.NetmapSnapshotResponse)
m.SetBody(x.body.ToGRPCMessage().(*netmap.NetmapSnapshotResponse_Body))
x.ResponseHeaders.ToMessage(m)
}
return m
}
func (x *SnapshotResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetmapSnapshotResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
x.body = nil
} else {
if x.body == nil {
x.body = new(SnapshotResponseBody)
}
err = x.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return x.ResponseHeaders.FromMessage(v)
}

BIN
netmap/grpc/service_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,121 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package netmap
func DoFuzzProtoLocalNodeInfoRequest(data []byte) int {
msg := new(LocalNodeInfoRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONLocalNodeInfoRequest(data []byte) int {
msg := new(LocalNodeInfoRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoLocalNodeInfoResponse(data []byte) int {
msg := new(LocalNodeInfoResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONLocalNodeInfoResponse(data []byte) int {
msg := new(LocalNodeInfoResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoNetworkInfoRequest(data []byte) int {
msg := new(NetworkInfoRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONNetworkInfoRequest(data []byte) int {
msg := new(NetworkInfoRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoNetworkInfoResponse(data []byte) int {
msg := new(NetworkInfoResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONNetworkInfoResponse(data []byte) int {
msg := new(NetworkInfoResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoNetmapSnapshotRequest(data []byte) int {
msg := new(NetmapSnapshotRequest)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONNetmapSnapshotRequest(data []byte) int {
msg := new(NetmapSnapshotRequest)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoNetmapSnapshotResponse(data []byte) int {
msg := new(NetmapSnapshotResponse)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONNetmapSnapshotResponse(data []byte) int {
msg := new(NetmapSnapshotResponse)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,71 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package netmap
import (
testing "testing"
)
func FuzzProtoLocalNodeInfoRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoLocalNodeInfoRequest(data)
})
}
func FuzzJSONLocalNodeInfoRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONLocalNodeInfoRequest(data)
})
}
func FuzzProtoLocalNodeInfoResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoLocalNodeInfoResponse(data)
})
}
func FuzzJSONLocalNodeInfoResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONLocalNodeInfoResponse(data)
})
}
func FuzzProtoNetworkInfoRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoNetworkInfoRequest(data)
})
}
func FuzzJSONNetworkInfoRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONNetworkInfoRequest(data)
})
}
func FuzzProtoNetworkInfoResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoNetworkInfoResponse(data)
})
}
func FuzzJSONNetworkInfoResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONNetworkInfoResponse(data)
})
}
func FuzzProtoNetmapSnapshotRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoNetmapSnapshotRequest(data)
})
}
func FuzzJSONNetmapSnapshotRequest(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONNetmapSnapshotRequest(data)
})
}
func FuzzProtoNetmapSnapshotResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoNetmapSnapshotResponse(data)
})
}
func FuzzJSONNetmapSnapshotResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONNetmapSnapshotResponse(data)
})
}

BIN
netmap/grpc/service_grpc.pb.go generated Normal file

Binary file not shown.

BIN
netmap/grpc/types_frostfs.pb.go generated Normal file

Binary file not shown.

View file

@ -0,0 +1,159 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package netmap
func DoFuzzProtoFilter(data []byte) int {
msg := new(Filter)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONFilter(data []byte) int {
msg := new(Filter)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoSelector(data []byte) int {
msg := new(Selector)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONSelector(data []byte) int {
msg := new(Selector)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoReplica(data []byte) int {
msg := new(Replica)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONReplica(data []byte) int {
msg := new(Replica)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoPlacementPolicy(data []byte) int {
msg := new(PlacementPolicy)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONPlacementPolicy(data []byte) int {
msg := new(PlacementPolicy)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoNodeInfo(data []byte) int {
msg := new(NodeInfo)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONNodeInfo(data []byte) int {
msg := new(NodeInfo)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoNetmap(data []byte) int {
msg := new(Netmap)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONNetmap(data []byte) int {
msg := new(Netmap)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoNetworkConfig(data []byte) int {
msg := new(NetworkConfig)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONNetworkConfig(data []byte) int {
msg := new(NetworkConfig)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}
func DoFuzzProtoNetworkInfo(data []byte) int {
msg := new(NetworkInfo)
if err := msg.UnmarshalProtobuf(data); err != nil {
return 0
}
_ = msg.MarshalProtobuf(nil)
return 1
}
func DoFuzzJSONNetworkInfo(data []byte) int {
msg := new(NetworkInfo)
if err := msg.UnmarshalJSON(data); err != nil {
return 0
}
_, err := msg.MarshalJSON()
if err != nil {
panic(err)
}
return 1
}

View file

@ -0,0 +1,91 @@
//go:build gofuzz
// +build gofuzz
// Code generated by protoc-gen-go-frostfs. DO NOT EDIT.
package netmap
import (
testing "testing"
)
func FuzzProtoFilter(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoFilter(data)
})
}
func FuzzJSONFilter(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONFilter(data)
})
}
func FuzzProtoSelector(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoSelector(data)
})
}
func FuzzJSONSelector(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONSelector(data)
})
}
func FuzzProtoReplica(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoReplica(data)
})
}
func FuzzJSONReplica(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONReplica(data)
})
}
func FuzzProtoPlacementPolicy(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoPlacementPolicy(data)
})
}
func FuzzJSONPlacementPolicy(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONPlacementPolicy(data)
})
}
func FuzzProtoNodeInfo(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoNodeInfo(data)
})
}
func FuzzJSONNodeInfo(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONNodeInfo(data)
})
}
func FuzzProtoNetmap(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoNetmap(data)
})
}
func FuzzJSONNetmap(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONNetmap(data)
})
}
func FuzzProtoNetworkConfig(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoNetworkConfig(data)
})
}
func FuzzJSONNetworkConfig(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONNetworkConfig(data)
})
}
func FuzzProtoNetworkInfo(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzProtoNetworkInfo(data)
})
}
func FuzzJSONNetworkInfo(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
DoFuzzJSONNetworkInfo(data)
})
}

62
netmap/json.go Normal file
View file

@ -0,0 +1,62 @@
package netmap
import (
netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
)
func (p *PlacementPolicy) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(p)
}
func (p *PlacementPolicy) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(p, data, new(netmap.PlacementPolicy))
}
func (f *Filter) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(f)
}
func (f *Filter) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(f, data, new(netmap.Filter))
}
func (s *Selector) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(s)
}
func (s *Selector) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(s, data, new(netmap.Selector))
}
func (r *Replica) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(r)
}
func (r *Replica) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(r, data, new(netmap.Replica))
}
func (a *Attribute) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(a)
}
func (a *Attribute) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(a, data, new(netmap.NodeInfo_Attribute))
}
func (ni *NodeInfo) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(ni)
}
func (ni *NodeInfo) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(ni, data, new(netmap.NodeInfo))
}
func (i *NetworkInfo) MarshalJSON() ([]byte, error) {
return message.MarshalJSON(i)
}
func (i *NetworkInfo) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(i, data, new(netmap.NetworkInfo))
}

576
netmap/marshal.go Normal file
View file

@ -0,0 +1,576 @@
package netmap
import (
netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
protoutil "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto"
)
const (
nameFilterField = 1
keyFilterField = 2
opFilterField = 3
valueFilterField = 4
filtersFilterField = 5
nameSelectorField = 1
countSelectorField = 2
clauseSelectorField = 3
attributeSelectorField = 4
filterSelectorField = 5
countReplicaField = 1
selectorReplicaField = 2
ecDataCountReplicaField = 3
ecParityCountReplicaField = 4
replicasPolicyField = 1
backupPolicyField = 2
selectorsPolicyField = 3
filtersPolicyField = 4
uniquePolicyField = 5
keyAttributeField = 1
valueAttributeField = 2
parentsAttributeField = 3
keyNodeInfoField = 1
addressNodeInfoField = 2
attributesNodeInfoField = 3
stateNodeInfoField = 4
versionInfoResponseBodyField = 1
nodeInfoResponseBodyField = 2
)
func (f *Filter) StableMarshal(buf []byte) []byte {
if f == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, f.StableSize())
}
var offset int
offset += protoutil.StringMarshal(nameFilterField, buf[offset:], f.name)
offset += protoutil.StringMarshal(keyFilterField, buf[offset:], f.key)
offset += protoutil.EnumMarshal(opFilterField, buf[offset:], int32(f.op))
offset += protoutil.StringMarshal(valueFilterField, buf[offset:], f.value)
for i := range f.filters {
offset += protoutil.NestedStructureMarshal(filtersFilterField, buf[offset:], &f.filters[i])
}
return buf
}
func (f *Filter) StableSize() (size int) {
if f == nil {
return 0
}
size += protoutil.StringSize(nameFilterField, f.name)
size += protoutil.StringSize(keyFilterField, f.key)
size += protoutil.EnumSize(opFilterField, int32(f.op))
size += protoutil.StringSize(valueFilterField, f.value)
for i := range f.filters {
size += protoutil.NestedStructureSize(filtersFilterField, &f.filters[i])
}
return size
}
func (f *Filter) Unmarshal(data []byte) error {
return message.Unmarshal(f, data, new(netmap.Filter))
}
func (s *Selector) StableMarshal(buf []byte) []byte {
if s == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, s.StableSize())
}
var offset int
offset += protoutil.StringMarshal(nameSelectorField, buf[offset:], s.name)
offset += protoutil.UInt32Marshal(countSelectorField, buf[offset:], s.count)
offset += protoutil.EnumMarshal(clauseSelectorField, buf[offset:], int32(s.clause))
offset += protoutil.StringMarshal(attributeSelectorField, buf[offset:], s.attribute)
protoutil.StringMarshal(filterSelectorField, buf[offset:], s.filter)
return buf
}
func (s *Selector) StableSize() (size int) {
if s == nil {
return 0
}
size += protoutil.StringSize(nameSelectorField, s.name)
size += protoutil.UInt32Size(countSelectorField, s.count)
size += protoutil.EnumSize(countSelectorField, int32(s.clause))
size += protoutil.StringSize(attributeSelectorField, s.attribute)
size += protoutil.StringSize(filterSelectorField, s.filter)
return size
}
func (s *Selector) Unmarshal(data []byte) error {
return message.Unmarshal(s, data, new(netmap.Selector))
}
func (r *Replica) StableMarshal(buf []byte) []byte {
if r == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
var offset int
offset += protoutil.UInt32Marshal(countReplicaField, buf[offset:], r.count)
offset += protoutil.StringMarshal(selectorReplicaField, buf[offset:], r.selector)
offset += protoutil.UInt32Marshal(ecDataCountReplicaField, buf[offset:], r.ecDataCount)
protoutil.UInt32Marshal(ecParityCountReplicaField, buf[offset:], r.ecParityCount)
return buf
}
func (r *Replica) StableSize() (size int) {
if r == nil {
return 0
}
size += protoutil.UInt32Size(countReplicaField, r.count)
size += protoutil.StringSize(selectorReplicaField, r.selector)
size += protoutil.UInt32Size(ecDataCountReplicaField, r.ecDataCount)
size += protoutil.UInt32Size(ecParityCountReplicaField, r.ecParityCount)
return size
}
func (r *Replica) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(netmap.Replica))
}
func (p *PlacementPolicy) StableMarshal(buf []byte) []byte {
if p == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, p.StableSize())
}
var offset int
for i := range p.replicas {
offset += protoutil.NestedStructureMarshal(replicasPolicyField, buf[offset:], &p.replicas[i])
}
offset += protoutil.UInt32Marshal(backupPolicyField, buf[offset:], p.backupFactor)
for i := range p.selectors {
offset += protoutil.NestedStructureMarshal(selectorsPolicyField, buf[offset:], &p.selectors[i])
}
for i := range p.filters {
offset += protoutil.NestedStructureMarshal(filtersPolicyField, buf[offset:], &p.filters[i])
}
protoutil.BoolMarshal(uniquePolicyField, buf[offset:], p.unique)
return buf
}
func (p *PlacementPolicy) StableSize() (size int) {
if p == nil {
return 0
}
for i := range p.replicas {
size += protoutil.NestedStructureSize(replicasPolicyField, &p.replicas[i])
}
size += protoutil.UInt32Size(backupPolicyField, p.backupFactor)
for i := range p.selectors {
size += protoutil.NestedStructureSize(selectorsPolicyField, &p.selectors[i])
}
for i := range p.filters {
size += protoutil.NestedStructureSize(filtersPolicyField, &p.filters[i])
}
size += protoutil.BoolSize(uniquePolicyField, p.unique)
return size
}
func (p *PlacementPolicy) Unmarshal(data []byte) error {
return message.Unmarshal(p, data, new(netmap.PlacementPolicy))
}
func (a *Attribute) StableMarshal(buf []byte) []byte {
if a == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, a.StableSize())
}
var offset int
offset += protoutil.StringMarshal(keyAttributeField, buf[offset:], a.key)
offset += protoutil.StringMarshal(valueAttributeField, buf[offset:], a.value)
for i := range a.parents {
offset += protoutil.StringMarshal(parentsAttributeField, buf[offset:], a.parents[i])
}
return buf
}
func (a *Attribute) StableSize() (size int) {
if a == nil {
return 0
}
size += protoutil.StringSize(keyAttributeField, a.key)
size += protoutil.StringSize(valueAttributeField, a.value)
for i := range a.parents {
size += protoutil.StringSize(parentsAttributeField, a.parents[i])
}
return size
}
func (a *Attribute) Unmarshal(data []byte) error {
return message.Unmarshal(a, data, new(netmap.NodeInfo_Attribute))
}
func (ni *NodeInfo) StableMarshal(buf []byte) []byte {
if ni == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, ni.StableSize())
}
var offset int
offset += protoutil.BytesMarshal(keyNodeInfoField, buf[offset:], ni.publicKey)
offset += protoutil.RepeatedStringMarshal(addressNodeInfoField, buf[offset:], ni.addresses)
for i := range ni.attributes {
offset += protoutil.NestedStructureMarshal(attributesNodeInfoField, buf[offset:], &ni.attributes[i])
}
protoutil.EnumMarshal(stateNodeInfoField, buf[offset:], int32(ni.state))
return buf
}
func (ni *NodeInfo) StableSize() (size int) {
if ni == nil {
return 0
}
size += protoutil.BytesSize(keyNodeInfoField, ni.publicKey)
size += protoutil.RepeatedStringSize(addressNodeInfoField, ni.addresses)
for i := range ni.attributes {
size += protoutil.NestedStructureSize(attributesNodeInfoField, &ni.attributes[i])
}
size += protoutil.EnumSize(stateNodeInfoField, int32(ni.state))
return size
}
func (ni *NodeInfo) Unmarshal(data []byte) error {
return message.Unmarshal(ni, data, new(netmap.NodeInfo))
}
func (l *LocalNodeInfoRequestBody) StableMarshal(_ []byte) []byte {
return nil
}
func (l *LocalNodeInfoRequestBody) StableSize() (size int) {
return 0
}
func (l *LocalNodeInfoRequestBody) Unmarshal([]byte) error {
return nil
}
func (l *LocalNodeInfoResponseBody) StableMarshal(buf []byte) []byte {
if l == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, l.StableSize())
}
var offset int
offset += protoutil.NestedStructureMarshal(versionInfoResponseBodyField, buf[offset:], l.version)
protoutil.NestedStructureMarshal(nodeInfoResponseBodyField, buf[offset:], l.nodeInfo)
return buf
}
func (l *LocalNodeInfoResponseBody) StableSize() (size int) {
if l == nil {
return 0
}
size += protoutil.NestedStructureSize(versionInfoResponseBodyField, l.version)
size += protoutil.NestedStructureSize(nodeInfoResponseBodyField, l.nodeInfo)
return size
}
func (l *LocalNodeInfoResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(l, data, new(netmap.LocalNodeInfoResponse_Body))
}
const (
_ = iota
netPrmKeyFNum
netPrmValFNum
)
func (x *NetworkParameter) StableMarshal(buf []byte) []byte {
if x == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
var offset int
offset += protoutil.BytesMarshal(netPrmKeyFNum, buf[offset:], x.k)
protoutil.BytesMarshal(netPrmValFNum, buf[offset:], x.v)
return buf
}
func (x *NetworkParameter) StableSize() (size int) {
if x == nil {
return 0
}
size += protoutil.BytesSize(netPrmKeyFNum, x.k)
size += protoutil.BytesSize(netPrmValFNum, x.v)
return size
}
const (
_ = iota
netCfgPrmsFNum
)
func (x *NetworkConfig) StableMarshal(buf []byte) []byte {
if x == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
var offset int
for i := range x.ps {
offset += protoutil.NestedStructureMarshal(netCfgPrmsFNum, buf[offset:], &x.ps[i])
}
return buf
}
func (x *NetworkConfig) StableSize() (size int) {
if x == nil {
return 0
}
for i := range x.ps {
size += protoutil.NestedStructureSize(netCfgPrmsFNum, &x.ps[i])
}
return size
}
const (
_ = iota
netInfoCurEpochFNum
netInfoMagicNumFNum
netInfoMSPerBlockFNum
netInfoCfgFNum
)
func (i *NetworkInfo) StableMarshal(buf []byte) []byte {
if i == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, i.StableSize())
}
var offset int
offset += protoutil.UInt64Marshal(netInfoCurEpochFNum, buf[offset:], i.curEpoch)
offset += protoutil.UInt64Marshal(netInfoMagicNumFNum, buf[offset:], i.magicNum)
offset += protoutil.Int64Marshal(netInfoMSPerBlockFNum, buf[offset:], i.msPerBlock)
protoutil.NestedStructureMarshal(netInfoCfgFNum, buf[offset:], i.netCfg)
return buf
}
func (i *NetworkInfo) StableSize() (size int) {
if i == nil {
return 0
}
size += protoutil.UInt64Size(netInfoCurEpochFNum, i.curEpoch)
size += protoutil.UInt64Size(netInfoMagicNumFNum, i.magicNum)
size += protoutil.Int64Size(netInfoMSPerBlockFNum, i.msPerBlock)
size += protoutil.NestedStructureSize(netInfoCfgFNum, i.netCfg)
return size
}
func (i *NetworkInfo) Unmarshal(data []byte) error {
return message.Unmarshal(i, data, new(netmap.NetworkInfo))
}
func (l *NetworkInfoRequestBody) StableMarshal(_ []byte) []byte {
return nil
}
func (l *NetworkInfoRequestBody) StableSize() (size int) {
return 0
}
func (l *NetworkInfoRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(l, data, new(netmap.NetworkInfoRequest_Body))
}
const (
_ = iota
netInfoRespBodyNetInfoFNum
)
func (i *NetworkInfoResponseBody) StableMarshal(buf []byte) []byte {
if i == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, i.StableSize())
}
protoutil.NestedStructureMarshal(netInfoRespBodyNetInfoFNum, buf, i.netInfo)
return buf
}
func (i *NetworkInfoResponseBody) StableSize() (size int) {
if i == nil {
return 0
}
size += protoutil.NestedStructureSize(netInfoRespBodyNetInfoFNum, i.netInfo)
return size
}
func (i *NetworkInfoResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(i, data, new(netmap.NetworkInfoResponse_Body))
}
const (
_ = iota
fNumNetMapEpoch
fNumNetMapNodes
)
func (x *NetMap) StableMarshal(buf []byte) []byte {
if x == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
offset := protoutil.UInt64Marshal(fNumNetMapEpoch, buf, x.epoch)
for i := range x.nodes {
offset += protoutil.NestedStructureMarshal(fNumNetMapNodes, buf[offset:], &x.nodes[i])
}
return buf
}
func (x *NetMap) StableSize() (size int) {
if x != nil {
size = protoutil.UInt64Size(fNumNetMapEpoch, x.epoch)
for i := range x.nodes {
size += protoutil.NestedStructureSize(fNumNetMapNodes, &x.nodes[i])
}
}
return
}
func (x *SnapshotRequestBody) StableMarshal([]byte) []byte {
return nil
}
func (x *SnapshotRequestBody) StableSize() int {
return 0
}
const (
_ = iota
fNumSnapshotResponseBodyNetMap
)
func (x *SnapshotResponseBody) StableMarshal(buf []byte) []byte {
if x == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
protoutil.NestedStructureMarshal(fNumSnapshotResponseBodyNetMap, buf, x.netMap)
return buf
}
func (x *SnapshotResponseBody) StableSize() (size int) {
if x != nil {
size = protoutil.NestedStructureSize(fNumSnapshotResponseBodyNetMap, x.netMap)
}
return
}

32
netmap/message_test.go Normal file
View file

@ -0,0 +1,32 @@
package netmap_test
import (
"testing"
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/test"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
messagetest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return netmaptest.GenerateFilter(empty) },
func(empty bool) message.Message { return netmaptest.GenerateSelector(empty) },
func(empty bool) message.Message { return netmaptest.GenerateReplica(empty) },
func(empty bool) message.Message { return netmaptest.GeneratePlacementPolicy(empty) },
func(empty bool) message.Message { return netmaptest.GenerateAttribute(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNodeInfo(empty) },
func(empty bool) message.Message { return netmaptest.GenerateLocalNodeInfoRequest(empty) },
func(empty bool) message.Message { return netmaptest.GenerateLocalNodeInfoResponseBody(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkParameter(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkConfig(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfo(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfoRequest(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfoResponseBody(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetMap(empty) },
func(empty bool) message.Message { return netmaptest.GenerateSnapshotRequestBody(empty) },
func(empty bool) message.Message { return netmaptest.GenerateSnapshotRequest(empty) },
func(empty bool) message.Message { return netmaptest.GenerateSnapshotResponseBody(empty) },
func(empty bool) message.Message { return netmaptest.GenerateSnapshotResponse(empty) },
)
}

68
netmap/string.go Normal file
View file

@ -0,0 +1,68 @@
package netmap
import (
netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
)
// String returns string representation of Clause.
func (x Clause) String() string {
return ClauseToGRPCMessage(x).String()
}
// FromString parses Clause from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *Clause) FromString(s string) bool {
var g netmap.Clause
ok := g.FromString(s)
if ok {
*x = ClauseFromGRPCMessage(g)
}
return ok
}
// String returns string representation of Operation.
func (x Operation) String() string {
return OperationToGRPCMessage(x).String()
}
// FromString parses Operation from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *Operation) FromString(s string) bool {
var g netmap.Operation
ok := g.FromString(s)
if ok {
*x = OperationFromGRPCMessage(g)
}
return ok
}
// String returns string representation of NodeState.
func (x NodeState) String() string {
return NodeStateToGRPCMessage(x).String()
}
// FromString parses NodeState from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *NodeState) FromString(s string) bool {
var g netmap.NodeInfo_State
ok := g.FromString(s)
if ok {
*x = NodeStateFromRPCMessage(g)
}
return ok
}

335
netmap/test/generate.go Normal file
View file

@ -0,0 +1,335 @@
package netmaptest
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
refstest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/test"
sessiontest "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session/test"
)
func GenerateFilter(empty bool) *netmap.Filter {
return generateFilter(empty, true)
}
func generateFilter(empty, withSub bool) *netmap.Filter {
m := new(netmap.Filter)
if !empty {
m.SetKey("filter key")
m.SetValue("filter value")
m.SetName("filter name")
m.SetOp(1)
if withSub {
m.SetFilters([]netmap.Filter{
*generateFilter(empty, false),
*generateFilter(empty, false),
})
}
}
return m
}
func GenerateFilters(empty bool) []netmap.Filter {
var res []netmap.Filter
if !empty {
res = append(res,
*GenerateFilter(false),
*GenerateFilter(false),
)
}
return res
}
func GenerateSelector(empty bool) *netmap.Selector {
m := new(netmap.Selector)
if !empty {
m.SetCount(66)
m.SetAttribute("selector attribute")
m.SetFilter("select filter")
m.SetName("select name")
m.SetClause(1)
}
return m
}
func GenerateSelectors(empty bool) []netmap.Selector {
var res []netmap.Selector
if !empty {
res = append(res,
*GenerateSelector(false),
*GenerateSelector(false),
)
}
return res
}
func GenerateReplica(empty bool) *netmap.Replica {
m := new(netmap.Replica)
if !empty {
m.SetCount(42)
m.SetSelector("replica selector")
}
return m
}
func GenerateEC(empty bool) *netmap.Replica {
m := new(netmap.Replica)
if !empty {
m.SetECDataCount(4)
m.SetECParityCount(2)
}
return m
}
func GenerateReplicas(empty bool) []netmap.Replica {
var res []netmap.Replica
if !empty {
res = append(res,
*GenerateReplica(false),
*GenerateReplica(false),
*GenerateEC(false),
)
}
return res
}
func GeneratePlacementPolicy(empty bool) *netmap.PlacementPolicy {
m := new(netmap.PlacementPolicy)
if !empty {
m.SetContainerBackupFactor(322)
m.SetFilters(GenerateFilters(false))
m.SetSelectors(GenerateSelectors(false))
m.SetReplicas(GenerateReplicas(false))
m.SetUnique(true)
}
return m
}
func GenerateAttribute(empty bool) *netmap.Attribute {
m := new(netmap.Attribute)
if !empty {
m.SetKey("attribute key")
m.SetValue("attribute val")
}
return m
}
func GenerateAttributes(empty bool) []netmap.Attribute {
var res []netmap.Attribute
if !empty {
res = append(res,
*GenerateAttribute(false),
*GenerateAttribute(false),
)
}
return res
}
func GenerateNodeInfo(empty bool) *netmap.NodeInfo {
m := new(netmap.NodeInfo)
if !empty {
m.SetAddresses("node address", "node address 2")
m.SetPublicKey([]byte{1, 2, 3})
m.SetState(33)
m.SetAttributes(GenerateAttributes(empty))
}
return m
}
func GenerateLocalNodeInfoRequestBody(_ bool) *netmap.LocalNodeInfoRequestBody {
m := new(netmap.LocalNodeInfoRequestBody)
return m
}
func GenerateLocalNodeInfoRequest(empty bool) *netmap.LocalNodeInfoRequest {
m := new(netmap.LocalNodeInfoRequest)
if !empty {
m.SetBody(GenerateLocalNodeInfoRequestBody(false))
}
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateLocalNodeInfoResponseBody(empty bool) *netmap.LocalNodeInfoResponseBody {
m := new(netmap.LocalNodeInfoResponseBody)
if !empty {
m.SetNodeInfo(GenerateNodeInfo(false))
}
m.SetVersion(refstest.GenerateVersion(empty))
return m
}
func GenerateLocalNodeInfoResponse(empty bool) *netmap.LocalNodeInfoResponse {
m := new(netmap.LocalNodeInfoResponse)
if !empty {
m.SetBody(GenerateLocalNodeInfoResponseBody(false))
}
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateNetworkParameter(empty bool) *netmap.NetworkParameter {
m := new(netmap.NetworkParameter)
if !empty {
m.SetKey([]byte("key"))
m.SetValue([]byte("value"))
}
return m
}
func GenerateNetworkConfig(empty bool) *netmap.NetworkConfig {
m := new(netmap.NetworkConfig)
if !empty {
m.SetParameters(
*GenerateNetworkParameter(empty),
*GenerateNetworkParameter(empty),
)
}
return m
}
func GenerateNetworkInfo(empty bool) *netmap.NetworkInfo {
m := new(netmap.NetworkInfo)
if !empty {
m.SetMagicNumber(228)
m.SetCurrentEpoch(666)
m.SetMsPerBlock(5678)
m.SetNetworkConfig(GenerateNetworkConfig(empty))
}
return m
}
func GenerateNetworkInfoRequestBody(_ bool) *netmap.NetworkInfoRequestBody {
m := new(netmap.NetworkInfoRequestBody)
return m
}
func GenerateNetworkInfoRequest(empty bool) *netmap.NetworkInfoRequest {
m := new(netmap.NetworkInfoRequest)
if !empty {
m.SetBody(GenerateNetworkInfoRequestBody(false))
}
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateNetworkInfoResponseBody(empty bool) *netmap.NetworkInfoResponseBody {
m := new(netmap.NetworkInfoResponseBody)
if !empty {
m.SetNetworkInfo(GenerateNetworkInfo(false))
}
return m
}
func GenerateNetworkInfoResponse(empty bool) *netmap.NetworkInfoResponse {
m := new(netmap.NetworkInfoResponse)
if !empty {
m.SetBody(GenerateNetworkInfoResponseBody(false))
}
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateNetMap(empty bool) *netmap.NetMap {
m := new(netmap.NetMap)
if !empty {
m.SetEpoch(987)
m.SetNodes([]netmap.NodeInfo{
*GenerateNodeInfo(false),
*GenerateNodeInfo(false),
})
}
return m
}
func GenerateSnapshotRequestBody(_ bool) *netmap.SnapshotRequestBody {
return new(netmap.SnapshotRequestBody)
}
func GenerateSnapshotRequest(empty bool) *netmap.SnapshotRequest {
m := new(netmap.SnapshotRequest)
if !empty {
m.SetBody(GenerateSnapshotRequestBody(false))
}
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateSnapshotResponseBody(empty bool) *netmap.SnapshotResponseBody {
m := new(netmap.SnapshotResponseBody)
if !empty {
m.SetNetMap(GenerateNetMap(false))
}
return m
}
func GenerateSnapshotResponse(empty bool) *netmap.SnapshotResponse {
m := new(netmap.SnapshotResponse)
if !empty {
m.SetBody(GenerateSnapshotResponseBody(false))
}
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}

783
netmap/types.go Normal file
View file

@ -0,0 +1,783 @@
package netmap
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
)
type LocalNodeInfoRequest struct {
body *LocalNodeInfoRequestBody
session.RequestHeaders
}
type LocalNodeInfoResponse struct {
body *LocalNodeInfoResponseBody
session.ResponseHeaders
}
// NetworkInfoRequest is a structure of NetworkInfo request.
type NetworkInfoRequest struct {
body *NetworkInfoRequestBody
session.RequestHeaders
}
// NetworkInfoResponse is a structure of NetworkInfo response.
type NetworkInfoResponse struct {
body *NetworkInfoResponseBody
session.ResponseHeaders
}
type Filter struct {
name string
key string
op Operation
value string
filters []Filter
}
type Selector struct {
name string
count uint32
clause Clause
attribute string
filter string
}
type Replica struct {
count uint32
selector string
ecDataCount uint32
ecParityCount uint32
}
type Operation uint32
type PlacementPolicy struct {
replicas []Replica
backupFactor uint32
selectors []Selector
filters []Filter
unique bool
}
// Attribute of storage node.
type Attribute struct {
key string
value string
parents []string
}
// NodeInfo of storage node.
type NodeInfo struct {
publicKey []byte
addresses []string
attributes []Attribute
state NodeState
}
// NodeState of storage node.
type NodeState uint32
// Clause of placement selector.
type Clause uint32
type LocalNodeInfoRequestBody struct{}
type LocalNodeInfoResponseBody struct {
version *refs.Version
nodeInfo *NodeInfo
}
const (
UnspecifiedState NodeState = iota
Online
Offline
Maintenance
)
const (
UnspecifiedOperation Operation = iota
EQ
NE
GT
GE
LT
LE
OR
AND
NOT
LIKE
)
const (
UnspecifiedClause Clause = iota
Same
Distinct
)
func (f *Filter) GetFilters() []Filter {
if f != nil {
return f.filters
}
return nil
}
func (f *Filter) SetFilters(filters []Filter) {
f.filters = filters
}
func (f *Filter) GetValue() string {
if f != nil {
return f.value
}
return ""
}
func (f *Filter) SetValue(value string) {
f.value = value
}
func (f *Filter) GetOp() Operation {
if f != nil {
return f.op
}
return UnspecifiedOperation
}
func (f *Filter) SetOp(op Operation) {
f.op = op
}
func (f *Filter) GetKey() string {
if f != nil {
return f.key
}
return ""
}
func (f *Filter) SetKey(key string) {
f.key = key
}
func (f *Filter) GetName() string {
if f != nil {
return f.name
}
return ""
}
func (f *Filter) SetName(name string) {
f.name = name
}
func (s *Selector) GetFilter() string {
if s != nil {
return s.filter
}
return ""
}
func (s *Selector) SetFilter(filter string) {
s.filter = filter
}
func (s *Selector) GetAttribute() string {
if s != nil {
return s.attribute
}
return ""
}
func (s *Selector) SetAttribute(attribute string) {
s.attribute = attribute
}
func (s *Selector) GetClause() Clause {
if s != nil {
return s.clause
}
return UnspecifiedClause
}
func (s *Selector) SetClause(clause Clause) {
s.clause = clause
}
func (s *Selector) GetCount() uint32 {
if s != nil {
return s.count
}
return 0
}
func (s *Selector) SetCount(count uint32) {
s.count = count
}
func (s *Selector) GetName() string {
if s != nil {
return s.name
}
return ""
}
func (s *Selector) SetName(name string) {
s.name = name
}
func (r *Replica) GetSelector() string {
if r != nil {
return r.selector
}
return ""
}
func (r *Replica) SetSelector(selector string) {
r.selector = selector
}
func (r *Replica) GetCount() uint32 {
if r != nil {
return r.count
}
return 0
}
func (r *Replica) SetCount(count uint32) {
r.count = count
}
func (r *Replica) GetECDataCount() uint32 {
if r != nil {
return r.ecDataCount
}
return 0
}
func (r *Replica) SetECDataCount(count uint32) {
r.ecDataCount = count
}
func (r *Replica) GetECParityCount() uint32 {
if r != nil {
return r.ecParityCount
}
return 0
}
func (r *Replica) SetECParityCount(count uint32) {
r.ecParityCount = count
}
func (p *PlacementPolicy) GetUnique() bool {
if p != nil {
return p.unique
}
return false
}
func (p *PlacementPolicy) SetUnique(unique bool) {
p.unique = unique
}
func (p *PlacementPolicy) GetFilters() []Filter {
if p != nil {
return p.filters
}
return nil
}
func (p *PlacementPolicy) SetFilters(filters []Filter) {
p.filters = filters
}
func (p *PlacementPolicy) GetSelectors() []Selector {
if p != nil {
return p.selectors
}
return nil
}
func (p *PlacementPolicy) SetSelectors(selectors []Selector) {
p.selectors = selectors
}
func (p *PlacementPolicy) GetContainerBackupFactor() uint32 {
if p != nil {
return p.backupFactor
}
return 0
}
func (p *PlacementPolicy) SetContainerBackupFactor(backupFactor uint32) {
p.backupFactor = backupFactor
}
func (p *PlacementPolicy) GetReplicas() []Replica {
if p == nil {
return nil
}
return p.replicas
}
func (p *PlacementPolicy) SetReplicas(replicas []Replica) {
p.replicas = replicas
}
func (a *Attribute) GetKey() string {
if a != nil {
return a.key
}
return ""
}
func (a *Attribute) SetKey(v string) {
a.key = v
}
func (a *Attribute) GetValue() string {
if a != nil {
return a.value
}
return ""
}
func (a *Attribute) SetValue(v string) {
a.value = v
}
func (a *Attribute) GetParents() []string {
if a != nil {
return a.parents
}
return nil
}
func (a *Attribute) SetParents(parent []string) {
a.parents = parent
}
func (ni *NodeInfo) GetPublicKey() []byte {
if ni != nil {
return ni.publicKey
}
return nil
}
func (ni *NodeInfo) SetPublicKey(v []byte) {
ni.publicKey = v
}
// GetAddress returns node's network address.
//
// Deprecated: use IterateAddresses.
func (ni *NodeInfo) GetAddress() (addr string) {
ni.IterateAddresses(func(s string) bool {
addr = s
return true
})
return
}
// SetAddress sets node's network address.
//
// Deprecated: use SetAddresses.
func (ni *NodeInfo) SetAddress(v string) {
ni.SetAddresses(v)
}
// SetAddresses sets list of network addresses of the node.
func (ni *NodeInfo) SetAddresses(v ...string) {
ni.addresses = v
}
// NumberOfAddresses returns number of network addresses of the node.
func (ni *NodeInfo) NumberOfAddresses() int {
if ni != nil {
return len(ni.addresses)
}
return 0
}
// IterateAddresses iterates over network addresses of the node.
// Breaks iteration on f's true return.
//
// Handler should not be nil.
func (ni *NodeInfo) IterateAddresses(f func(string) bool) {
if ni != nil {
for i := range ni.addresses {
if f(ni.addresses[i]) {
break
}
}
}
}
func (ni *NodeInfo) GetAttributes() []Attribute {
if ni != nil {
return ni.attributes
}
return nil
}
func (ni *NodeInfo) SetAttributes(v []Attribute) {
ni.attributes = v
}
func (ni *NodeInfo) GetState() NodeState {
if ni != nil {
return ni.state
}
return UnspecifiedState
}
func (ni *NodeInfo) SetState(state NodeState) {
ni.state = state
}
func (l *LocalNodeInfoResponseBody) GetVersion() *refs.Version {
if l != nil {
return l.version
}
return nil
}
func (l *LocalNodeInfoResponseBody) SetVersion(version *refs.Version) {
l.version = version
}
func (l *LocalNodeInfoResponseBody) GetNodeInfo() *NodeInfo {
if l != nil {
return l.nodeInfo
}
return nil
}
func (l *LocalNodeInfoResponseBody) SetNodeInfo(nodeInfo *NodeInfo) {
l.nodeInfo = nodeInfo
}
func (l *LocalNodeInfoRequest) GetBody() *LocalNodeInfoRequestBody {
if l != nil {
return l.body
}
return nil
}
func (l *LocalNodeInfoRequest) SetBody(body *LocalNodeInfoRequestBody) {
l.body = body
}
func (l *LocalNodeInfoResponse) GetBody() *LocalNodeInfoResponseBody {
if l != nil {
return l.body
}
return nil
}
func (l *LocalNodeInfoResponse) SetBody(body *LocalNodeInfoResponseBody) {
l.body = body
}
// NetworkParameter represents NeoFS network parameter.
type NetworkParameter struct {
k, v []byte
}
// GetKey returns parameter key.
func (x *NetworkParameter) GetKey() []byte {
if x != nil {
return x.k
}
return nil
}
// SetKey sets parameter key.
func (x *NetworkParameter) SetKey(k []byte) {
x.k = k
}
// GetValue returns parameter value.
func (x *NetworkParameter) GetValue() []byte {
if x != nil {
return x.v
}
return nil
}
// SetValue sets parameter value.
func (x *NetworkParameter) SetValue(v []byte) {
x.v = v
}
// NetworkConfig represents NeoFS network configuration.
type NetworkConfig struct {
ps []NetworkParameter
}
// NumberOfParameters returns number of network parameters.
func (x *NetworkConfig) NumberOfParameters() int {
if x != nil {
return len(x.ps)
}
return 0
}
// IterateParameters iterates over network parameters.
// Breaks iteration on f's true return.
//
// Handler must not be nil.
func (x *NetworkConfig) IterateParameters(f func(*NetworkParameter) bool) {
if x != nil {
for i := range x.ps {
if f(&x.ps[i]) {
break
}
}
}
}
// SetParameters sets list of network parameters.
func (x *NetworkConfig) SetParameters(v ...NetworkParameter) {
x.ps = v
}
// NetworkInfo groups information about
// NeoFS network.
type NetworkInfo struct {
curEpoch, magicNum uint64
msPerBlock int64
netCfg *NetworkConfig
}
// GetCurrentEpoch returns number of the current epoch.
func (i *NetworkInfo) GetCurrentEpoch() uint64 {
if i != nil {
return i.curEpoch
}
return 0
}
// SetCurrentEpoch sets number of the current epoch.
func (i *NetworkInfo) SetCurrentEpoch(epoch uint64) {
i.curEpoch = epoch
}
// GetMagicNumber returns magic number of the sidechain.
func (i *NetworkInfo) GetMagicNumber() uint64 {
if i != nil {
return i.magicNum
}
return 0
}
// SetMagicNumber sets magic number of the sidechain.
func (i *NetworkInfo) SetMagicNumber(magic uint64) {
i.magicNum = magic
}
// GetMsPerBlock returns MillisecondsPerBlock network parameter.
func (i *NetworkInfo) GetMsPerBlock() int64 {
if i != nil {
return i.msPerBlock
}
return 0
}
// SetMsPerBlock sets MillisecondsPerBlock network parameter.
func (i *NetworkInfo) SetMsPerBlock(v int64) {
i.msPerBlock = v
}
// GetNetworkConfig returns NeoFS network configuration.
func (i *NetworkInfo) GetNetworkConfig() *NetworkConfig {
if i != nil {
return i.netCfg
}
return nil
}
// SetNetworkConfig sets NeoFS network configuration.
func (i *NetworkInfo) SetNetworkConfig(v *NetworkConfig) {
i.netCfg = v
}
// NetworkInfoRequestBody is a structure of NetworkInfo request body.
type NetworkInfoRequestBody struct{}
// NetworkInfoResponseBody is a structure of NetworkInfo response body.
type NetworkInfoResponseBody struct {
netInfo *NetworkInfo
}
// GetNetworkInfo returns information about the NeoFS network.
func (i *NetworkInfoResponseBody) GetNetworkInfo() *NetworkInfo {
if i != nil {
return i.netInfo
}
return nil
}
// SetNetworkInfo sets information about the NeoFS network.
func (i *NetworkInfoResponseBody) SetNetworkInfo(netInfo *NetworkInfo) {
i.netInfo = netInfo
}
func (l *NetworkInfoRequest) GetBody() *NetworkInfoRequestBody {
if l != nil {
return l.body
}
return nil
}
func (l *NetworkInfoRequest) SetBody(body *NetworkInfoRequestBody) {
l.body = body
}
func (l *NetworkInfoResponse) GetBody() *NetworkInfoResponseBody {
if l != nil {
return l.body
}
return nil
}
func (l *NetworkInfoResponse) SetBody(body *NetworkInfoResponseBody) {
l.body = body
}
// NetMap represents structure of NeoFS network map.
type NetMap struct {
epoch uint64
nodes []NodeInfo
}
// Epoch returns revision number of the NetMap.
func (x *NetMap) Epoch() uint64 {
if x != nil {
return x.epoch
}
return 0
}
// SetEpoch sets revision number of the NetMap.
func (x *NetMap) SetEpoch(v uint64) {
x.epoch = v
}
// Nodes returns nodes presented in the NetMap.
func (x *NetMap) Nodes() []NodeInfo {
if x != nil {
return x.nodes
}
return nil
}
// SetNodes sets nodes presented in the NetMap.
func (x *NetMap) SetNodes(v []NodeInfo) {
x.nodes = v
}
// SnapshotRequestBody represents structure of Snapshot request body.
type SnapshotRequestBody struct{}
// SnapshotRequest represents structure of Snapshot request.
type SnapshotRequest struct {
body *SnapshotRequestBody
session.RequestHeaders
}
func (x *SnapshotRequest) GetBody() *SnapshotRequestBody {
if x != nil {
return x.body
}
return nil
}
func (x *SnapshotRequest) SetBody(body *SnapshotRequestBody) {
x.body = body
}
// SnapshotResponseBody represents structure of Snapshot response body.
type SnapshotResponseBody struct {
netMap *NetMap
}
// NetMap returns current NetMap.
func (x *SnapshotResponseBody) NetMap() *NetMap {
if x != nil {
return x.netMap
}
return nil
}
// SetNetMap sets current NetMap.
func (x *SnapshotResponseBody) SetNetMap(netMap *NetMap) {
x.netMap = netMap
}
// SnapshotResponse represents structure of Snapshot response.
type SnapshotResponse struct {
body *SnapshotResponseBody
session.ResponseHeaders
}
func (x *SnapshotResponse) GetBody() *SnapshotResponseBody {
if x != nil {
return x.body
}
return nil
}
func (x *SnapshotResponse) SetBody(body *SnapshotResponseBody) {
x.body = body
}

Some files were not shown because too many files have changed in this diff Show more