mirror of https://github.com/etcd-io/protodoc.git
initial commit
This commit is contained in:
commit
be6aa82c50
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
language: go
|
||||
|
||||
sudo: false
|
||||
|
||||
go:
|
||||
- 1.6.1
|
||||
|
||||
script:
|
||||
- ./test
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
# How to Contribute
|
||||
|
||||
CoreOS projects are [Apache 2.0 licensed](LICENSE) and accept contributions via
|
||||
GitHub pull requests. This document outlines some of the conventions on
|
||||
development workflow, commit message formatting, contact points and other
|
||||
resources to make it easier to get your contribution accepted.
|
||||
|
||||
# Certificate of Origin
|
||||
|
||||
By contributing to this project you agree to the Developer Certificate of
|
||||
Origin (DCO). This document was created by the Linux Kernel community and is a
|
||||
simple statement that you, as a contributor, have the legal right to make the
|
||||
contribution. See the [DCO](DCO) file for details.
|
||||
|
||||
# Email and Chat
|
||||
|
||||
The project currently uses the general CoreOS email list and IRC channel:
|
||||
- Email: [coreos-dev](https://groups.google.com/forum/#!forum/coreos-dev)
|
||||
- IRC: #[coreos](irc://irc.freenode.org:6667/#coreos) IRC channel on freenode.org
|
||||
|
||||
Please avoid emailing maintainers found in the MAINTAINERS file directly. They
|
||||
are very busy and read the mailing lists.
|
||||
|
||||
## Getting Started
|
||||
|
||||
- Fork the repository on GitHub
|
||||
- Read the [README](README.md) for build and test instructions
|
||||
- Play with the project, submit bugs, submit patches!
|
||||
|
||||
## Contribution Flow
|
||||
|
||||
This is a rough outline of what a contributor's workflow looks like:
|
||||
|
||||
- Create a topic branch from where you want to base your work (usually master).
|
||||
- Make commits of logical units.
|
||||
- Make sure your commit messages are in the proper format (see below).
|
||||
- Push your changes to a topic branch in your fork of the repository.
|
||||
- Make sure the tests pass, and add any new tests as appropriate.
|
||||
- Submit a pull request to the original repository.
|
||||
|
||||
Thanks for your contributions!
|
||||
|
||||
### Coding Style
|
||||
|
||||
CoreOS projects written in Go follow a set of style guidelines that we've documented
|
||||
[here](https://github.com/coreos/docs/tree/master/golang). Please follow them when
|
||||
working on your contributions.
|
||||
|
||||
### Format of the Commit Message
|
||||
|
||||
We follow a rough convention for commit messages that is designed to answer two
|
||||
questions: what changed and why. The subject line should feature the what and
|
||||
the body of the commit should describe the why.
|
||||
|
||||
```
|
||||
scripts: add the test-cluster command
|
||||
|
||||
this uses tmux to setup a test cluster that you can easily kill and
|
||||
start for debugging.
|
||||
|
||||
Fixes #38
|
||||
```
|
||||
|
||||
The format can be described more formally as follows:
|
||||
|
||||
```
|
||||
<subsystem>: <what changed>
|
||||
<BLANK LINE>
|
||||
<why this change was made>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The first line is the subject and should be no longer than 70 characters, the
|
||||
second line is always blank, and other lines should be wrapped at 80 characters.
|
||||
This allows the message to be easier to read on GitHub as well as in various
|
||||
git tools.
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
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.
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
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.
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
CoreOS Project
|
||||
Copyright 2015 CoreOS, Inc
|
||||
|
||||
This product includes software developed at CoreOS, Inc.
|
||||
(http://www.coreos.com/).
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
prodoc generates Protocol Buffer documentation.
|
||||
|
||||
Note that parser only understands the minimum syntax
|
||||
of Protocol Buffer (just enough to generate documentation).
|
||||
|
||||
For full featured parser, please check out https://github.com/golang/protobuf.
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Package parse parses Protocol Buffers.
|
||||
package parse
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package parse
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Markdown saves 'Proto' to markdown documentation.
|
||||
// lopts are a slice of language options (C++, Java, Python, Go, Ruby, C#).
|
||||
func (p *Proto) Markdown(title, fpath string, lopts ...string) error {
|
||||
p.Sort()
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
buf.WriteString(fmt.Sprintf("### %s\n\n\n", title))
|
||||
|
||||
for _, msg := range p.Messages {
|
||||
buf.WriteString(fmt.Sprintf("##### message `%s`\n\n", msg.Name))
|
||||
if msg.Description != "" {
|
||||
buf.WriteString(msg.Description)
|
||||
buf.WriteString("\n\n")
|
||||
}
|
||||
hd1 := "| Field | Description | Type |"
|
||||
hd2 := "| ----- | ----------- | ---- |"
|
||||
for _, lopt := range lopts {
|
||||
hd1 += fmt.Sprintf(" %s |", lopt)
|
||||
ds := strings.Repeat("-", len(lopt))
|
||||
if len(ds) < 3 {
|
||||
ds = "---"
|
||||
}
|
||||
hd2 += fmt.Sprintf(" %s |", ds)
|
||||
}
|
||||
buf.WriteString(hd1 + "\n")
|
||||
buf.WriteString(hd2 + "\n")
|
||||
for _, elem := range msg.Fields {
|
||||
ts := elem.ProtoType.String()
|
||||
if elem.UserDefinedProtoType != "" {
|
||||
ts = elem.UserDefinedProtoType
|
||||
}
|
||||
if elem.Repeated {
|
||||
ts = "[]" + ts
|
||||
}
|
||||
line := fmt.Sprintf("| %s | %s | %s |", elem.Name, elem.Description, ts)
|
||||
for _, lopt := range lopts {
|
||||
if elem.UserDefinedProtoType != "" {
|
||||
line += " |"
|
||||
continue
|
||||
}
|
||||
formatSt := " %s |"
|
||||
if elem.Repeated {
|
||||
formatSt = " []%s |"
|
||||
}
|
||||
switch lopt {
|
||||
case "C++":
|
||||
line += fmt.Sprintf(formatSt, elem.ProtoType.Cpp())
|
||||
case "Java":
|
||||
line += fmt.Sprintf(formatSt, elem.ProtoType.Java())
|
||||
case "Python":
|
||||
line += fmt.Sprintf(formatSt, elem.ProtoType.Python())
|
||||
case "Go":
|
||||
line += fmt.Sprintf(formatSt, elem.ProtoType.Go())
|
||||
case "Ruby":
|
||||
line += fmt.Sprintf(formatSt, elem.ProtoType.Ruby())
|
||||
case "C#":
|
||||
line += fmt.Sprintf(formatSt, elem.ProtoType.Csharp())
|
||||
default:
|
||||
return fmt.Errorf("%q is unknown (must be C++, Java, Python, Go, Ruby, C#)", lopt)
|
||||
}
|
||||
}
|
||||
buf.WriteString(line + "\n")
|
||||
}
|
||||
buf.WriteString("\n\n<br>\n\n")
|
||||
}
|
||||
|
||||
for _, svs := range p.Services {
|
||||
buf.WriteString(fmt.Sprintf("##### service `%s`\n\n", svs.Name))
|
||||
if svs.Description != "" {
|
||||
buf.WriteString(svs.Description)
|
||||
buf.WriteString("\n\n")
|
||||
}
|
||||
hd1 := "| Method | Request Type | Response Type | Description |"
|
||||
hd2 := "| ------ | ------------ | ------------- | ----------- |"
|
||||
buf.WriteString(hd1 + "\n")
|
||||
buf.WriteString(hd2 + "\n")
|
||||
|
||||
for _, elem := range svs.Methods {
|
||||
line := fmt.Sprintf("| %s | `%s` | `%s` | %s |", elem.Name, elem.RequestType, elem.ResponseType, elem.Description)
|
||||
buf.WriteString(line + "\n")
|
||||
}
|
||||
buf.WriteString("\n\n<br>\n\n")
|
||||
}
|
||||
|
||||
return toFile(buf.String(), fpath)
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package parse
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestMarkdown(t *testing.T) {
|
||||
proto, err := ReadDir("testdata")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := proto.Markdown("etcdserverpb", "testdata/README.md", "Go", "Java", "Python", "C++"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package parse
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func readLines(r io.Reader) ([]string, error) {
|
||||
var (
|
||||
lines []string
|
||||
scanner = bufio.NewScanner(r)
|
||||
)
|
||||
for scanner.Scan() {
|
||||
// remove indents
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if len(line) > 0 {
|
||||
if strings.HasPrefix(line, "//") {
|
||||
lines = append(lines, line)
|
||||
continue
|
||||
}
|
||||
|
||||
// remove semi-colon line-separator
|
||||
sl := strings.Split(line, ";")
|
||||
for _, txt := range sl {
|
||||
if len(txt) > 0 {
|
||||
if strings.HasPrefix(txt, "optional ") { // proto2
|
||||
txt = strings.Replace(txt, "optional ", "", 1)
|
||||
}
|
||||
lines = append(lines, txt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return lines, nil
|
||||
}
|
||||
|
||||
type parseMode int
|
||||
|
||||
const (
|
||||
reading parseMode = iota
|
||||
parsingMessage
|
||||
parsingService
|
||||
parsingRPC
|
||||
)
|
||||
|
||||
func ReadDir(targetDir string) (*Proto, error) {
|
||||
rm, err := walkDirExt(targetDir, ".proto")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var lines []string
|
||||
for _, fpath := range rm {
|
||||
f, err := os.OpenFile(fpath, os.O_RDONLY, 0444)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ls, err := readLines(f)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
lines = append(lines, ls...)
|
||||
|
||||
f.Close()
|
||||
}
|
||||
|
||||
var (
|
||||
rp = Proto{
|
||||
Messages: []ProtoMessage{},
|
||||
Services: []ProtoService{},
|
||||
}
|
||||
mode = reading
|
||||
|
||||
comments []string
|
||||
protoMessage = ProtoMessage{}
|
||||
protoService = ProtoService{}
|
||||
)
|
||||
|
||||
skippingEnum := false
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "//") {
|
||||
ls := strings.Replace(line, "//", "", 1)
|
||||
comments = append(comments, strings.TrimSpace(ls))
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(line, "enum ") {
|
||||
skippingEnum = true
|
||||
continue
|
||||
}
|
||||
if skippingEnum {
|
||||
if strings.HasSuffix(line, "}") { // end of enum
|
||||
skippingEnum = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
switch mode {
|
||||
case reading:
|
||||
for j, elem := range strings.Fields(line) {
|
||||
switch j {
|
||||
case 0:
|
||||
switch elem {
|
||||
case "message":
|
||||
mode = parsingMessage
|
||||
|
||||
case "service":
|
||||
mode = parsingService
|
||||
}
|
||||
|
||||
case 1: // proto message/service name
|
||||
switch mode {
|
||||
case parsingMessage: // message Name
|
||||
protoMessage.Name = strings.Replace(elem, "{", "", -1)
|
||||
protoMessage.Description = strings.Join(comments, " ")
|
||||
comments = []string{} // reset
|
||||
protoMessage.Fields = []ProtoField{} // reset
|
||||
|
||||
case parsingService: // service Name
|
||||
protoService.Name = strings.Replace(elem, "{", "", -1)
|
||||
protoService.Description = strings.Join(comments, " ")
|
||||
comments = []string{} // reset
|
||||
protoService.Methods = []ProtoMethod{} // reset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case parsingMessage:
|
||||
if strings.HasSuffix(line, "}") { // closing of message
|
||||
rp.Messages = append(rp.Messages, protoMessage)
|
||||
protoMessage = ProtoMessage{}
|
||||
comments = []string{}
|
||||
mode = reading
|
||||
continue
|
||||
}
|
||||
|
||||
protoField := ProtoField{}
|
||||
tl := line
|
||||
if strings.HasPrefix(tl, "repeated") {
|
||||
protoField.Repeated = true
|
||||
tl = strings.Replace(tl, "repeated ", "", -1)
|
||||
}
|
||||
fds := strings.Fields(tl)
|
||||
tp, err := ToProtoType(fds[0])
|
||||
if err != nil {
|
||||
protoField.ProtoType = 0
|
||||
protoField.UserDefinedProtoType = fds[0]
|
||||
} else {
|
||||
protoField.ProtoType = tp
|
||||
protoField.UserDefinedProtoType = ""
|
||||
}
|
||||
|
||||
protoField.Name = fds[1]
|
||||
protoField.Description = strings.Join(comments, " ")
|
||||
protoMessage.Fields = append(protoMessage.Fields, protoField)
|
||||
comments = []string{}
|
||||
|
||||
case parsingService:
|
||||
// parse 'rpc Watch(stream WatchRequest) returns (stream WatchResponse) {}'
|
||||
if strings.HasPrefix(line, "rpc ") {
|
||||
lt := strings.Replace(line, "rpc ", "", 1)
|
||||
lt = strings.Replace(lt, ")", "", -1)
|
||||
lt = strings.Replace(lt, " {}", "", 1)
|
||||
fsigs := strings.Split(lt, " returns ")
|
||||
|
||||
ft := strings.Split(fsigs[0], "(") // split 'Watch(stream WatchRequest'
|
||||
f1 := ft[0]
|
||||
|
||||
ft = strings.Fields(ft[1])
|
||||
f2 := ft[len(ft)-1]
|
||||
|
||||
ft = strings.Fields(strings.Replace(fsigs[1], "(", "", 1)) // split '(stream WatchResponse'
|
||||
f3 := ft[len(ft)-1]
|
||||
|
||||
protoMethod := ProtoMethod{} // reset
|
||||
protoMethod.Name = f1
|
||||
protoMethod.RequestType = f2
|
||||
protoMethod.ResponseType = f3
|
||||
protoMethod.Description = strings.Join(comments, " ")
|
||||
protoService.Methods = append(protoService.Methods, protoMethod)
|
||||
comments = []string{}
|
||||
} else if !strings.HasSuffix(line, "{}") && strings.HasSuffix(line, "}") { // closing of service
|
||||
rp.Services = append(rp.Services, protoService)
|
||||
protoService = ProtoService{}
|
||||
comments = []string{}
|
||||
mode = reading
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &rp, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package parse
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestReadDir(t *testing.T) {
|
||||
proto, err := ReadDir("testdata")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
proto.Sort()
|
||||
|
||||
if proto.Messages[51].Name != "MemberListRequest" {
|
||||
t.Fatalf("expected 'MemberListRequest', got %+v", proto.Messages[51])
|
||||
}
|
||||
if proto.Messages[52].Name != "MemberListResponse" {
|
||||
t.Fatalf("expected 'MemberListResponse', got %+v", proto.Messages[52])
|
||||
}
|
||||
if proto.Messages[52].Fields[0].Name != "header" {
|
||||
t.Fatalf("expected 'header', got %+v", proto.Messages[52])
|
||||
}
|
||||
if proto.Messages[52].Fields[0].UserDefinedProtoType != "ResponseHeader" {
|
||||
t.Fatalf("expected 'ResponseHeader', got %+v", proto.Messages[52])
|
||||
}
|
||||
|
||||
if proto.Messages[75].Name != "WatchResponse" {
|
||||
t.Fatalf("expected 'WatchResponse', got %+v", proto.Messages[75])
|
||||
}
|
||||
if proto.Messages[75].Fields[0].Name != "header" {
|
||||
t.Fatalf("expected 'header', got %+v", proto.Messages[75])
|
||||
}
|
||||
if proto.Messages[75].Fields[1].ProtoType != Int64 {
|
||||
t.Fatalf("expected 'Int64', got %+v", proto.Messages[75])
|
||||
}
|
||||
if proto.Messages[75].Fields[1].Name != "watch_id" {
|
||||
t.Fatalf("expected 'watch_id', got %+v", proto.Messages[75])
|
||||
}
|
||||
if proto.Messages[75].Fields[0].UserDefinedProtoType != "ResponseHeader" {
|
||||
t.Fatalf("expected 'ResponseHeader', got %+v", proto.Messages[75])
|
||||
}
|
||||
|
||||
if len(proto.Services[3].Methods) != 3 {
|
||||
t.Fatalf("expected 3 methods, got %+v", proto.Services[3].Methods)
|
||||
}
|
||||
if proto.Services[3].Methods[0].Name != "LeaseGrant" {
|
||||
t.Fatalf("expected 'LeaseGrant', got %+v", proto.Services[3].Methods[0])
|
||||
}
|
||||
if proto.Services[3].Methods[1].Name != "LeaseRevoke" {
|
||||
t.Fatalf("expected 'LeaseRevoke', got %+v", proto.Services[3].Methods[1])
|
||||
}
|
||||
if proto.Services[3].Methods[2].Name != "LeaseKeepAlive" {
|
||||
t.Fatalf("expected 'LeaseKeepAlive', got %+v", proto.Services[3].Methods[2])
|
||||
}
|
||||
|
||||
if proto.Services[5].Name != "Watch" {
|
||||
t.Fatalf("expected 'Watch', got %+v", proto.Services[5])
|
||||
}
|
||||
if proto.Services[5].Methods[0].Name != "Watch" {
|
||||
t.Fatalf("expected 'Watch', got %+v", proto.Services[5])
|
||||
}
|
||||
if proto.Services[5].Methods[0].RequestType != "WatchRequest" {
|
||||
t.Fatalf("expected 'WatchRequest', got %+v", proto.Services[5])
|
||||
}
|
||||
if proto.Services[5].Methods[0].ResponseType != "WatchResponse" {
|
||||
t.Fatalf("expected 'WatchRequest', got %+v", proto.Services[5])
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package parse
|
||||
|
||||
import "sort"
|
||||
|
||||
// Proto represents sets of 'ProtoMessage' and 'ProtoService'.
|
||||
type Proto struct {
|
||||
Messages []ProtoMessage
|
||||
Services []ProtoService
|
||||
}
|
||||
|
||||
type messages []ProtoMessage
|
||||
|
||||
func (s messages) Len() int { return len(s) }
|
||||
func (s messages) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s messages) Less(i, j int) bool { return s[i].Name < s[j].Name }
|
||||
|
||||
type services []ProtoService
|
||||
|
||||
func (s services) Len() int { return len(s) }
|
||||
func (s services) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s services) Less(i, j int) bool { return s[i].Name < s[j].Name }
|
||||
|
||||
func (p *Proto) Sort() {
|
||||
sort.Sort(messages(p.Messages))
|
||||
sort.Sort(services(p.Services))
|
||||
}
|
||||
|
||||
// ProtoMessage represents the 'message' type in Protocol Buffer.
|
||||
// (https://developers.google.com/protocol-buffers/docs/proto3#simple)
|
||||
type ProtoMessage struct {
|
||||
Name string
|
||||
Description string
|
||||
Fields []ProtoField
|
||||
}
|
||||
|
||||
// ProtoField represent member fields in ProtoMessage.
|
||||
type ProtoField struct {
|
||||
Name string
|
||||
Description string
|
||||
Repeated bool
|
||||
ProtoType ProtoType
|
||||
UserDefinedProtoType string
|
||||
}
|
||||
|
||||
// ProtoService represents the 'service' type in Protocol Buffer.
|
||||
// (https://developers.google.com/protocol-buffers/docs/proto3#services)
|
||||
type ProtoService struct {
|
||||
Name string
|
||||
Description string
|
||||
Methods []ProtoMethod
|
||||
}
|
||||
|
||||
// ProtoMethod represents methods in ProtoService.
|
||||
type ProtoMethod struct {
|
||||
Name string
|
||||
Description string
|
||||
RequestType string
|
||||
ResponseType string
|
||||
}
|
||||
|
|
@ -0,0 +1,863 @@
|
|||
### etcdserverpb
|
||||
|
||||
|
||||
##### message `AlarmMember`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| memberID | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| alarm | | AlarmType | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AlarmRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| action | | AlarmAction | | | | |
|
||||
| memberID | MemberID is the member raising the alarm request | uint64 | uint64 | long | int/long | uint64 |
|
||||
| alarm | | AlarmType | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AlarmResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| alarms | | []AlarmMember | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthDisableRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthDisableResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthEnableRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthEnableResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleAddRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| name | | string | string | String | str/unicode | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleAddResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleDeleteRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleDeleteResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleGetRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleGetResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleGrantRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| name | | string | string | String | str/unicode | string |
|
||||
| perm | | authpb.Permission | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleGrantResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleRevokeRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthRoleRevokeResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserAddRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| name | | string | string | String | str/unicode | string |
|
||||
| password | | string | string | String | str/unicode | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserAddResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserChangePasswordRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| name | | string | string | String | str/unicode | string |
|
||||
| password | | string | string | String | str/unicode | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserChangePasswordResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserDeleteRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| name | | string | string | String | str/unicode | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserDeleteResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserGetRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserGetResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserGrantRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| user | | string | string | String | str/unicode | string |
|
||||
| role | | string | string | String | str/unicode | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserGrantResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserRevokeRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthUserRevokeResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthenticateRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `AuthenticateResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `CompactionRequest`
|
||||
|
||||
Compaction compacts the kv store upto a given revision. All superseded keys with a revision less than the compaction revision will be removed.
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| revision | | int64 | int64 | long | int/long | int64 |
|
||||
| physical | physical is set so the RPC will wait until the compaction is physically applied to the local database such that compacted entries are totally removed from the backing store. | bool | bool | boolean | boolean | bool |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `CompactionResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `Compare`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| result | | CompareResult | | | | |
|
||||
| target | | CompareTarget | | | | |
|
||||
| key | key path | bytes | []byte | ByteString | str | string |
|
||||
| target_union | | oneof | | | | |
|
||||
| version | version of the given key | int64 | int64 | long | int/long | int64 |
|
||||
| create_revision | create revision of the given key | int64 | int64 | long | int/long | int64 |
|
||||
| mod_revision | last modified revision of the given key | int64 | int64 | long | int/long | int64 |
|
||||
| value | value of the given key | bytes | []byte | ByteString | str | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `DefragmentRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `DefragmentResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `DeleteRangeRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| key | if the range_end is not given, the request deletes the key. | bytes | []byte | ByteString | str | string |
|
||||
| range_end | if the range_end is given, it deletes the keys in range [key, range_end). | bytes | []byte | ByteString | str | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `DeleteRangeResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| deleted | Deleted is the number of keys that got deleted. | int64 | int64 | long | int/long | int64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `EmptyResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `HashRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `HashResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| hash | | uint32 | uint32 | int | int/long | uint32 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `InternalRaftRequest`
|
||||
|
||||
An InternalRaftRequest is the union of all requests which can be sent via raft.
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| ID | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| v2 | | Request | | | | |
|
||||
| range | | RangeRequest | | | | |
|
||||
| put | | PutRequest | | | | |
|
||||
| delete_range | | DeleteRangeRequest | | | | |
|
||||
| txn | | TxnRequest | | | | |
|
||||
| compaction | | CompactionRequest | | | | |
|
||||
| lease_grant | | LeaseGrantRequest | | | | |
|
||||
| lease_revoke | | LeaseRevokeRequest | | | | |
|
||||
| auth_enable | | AuthEnableRequest | | | | |
|
||||
| auth_user_add | | AuthUserAddRequest | | | | |
|
||||
| auth_user_delete | | AuthUserDeleteRequest | | | | |
|
||||
| auth_user_change_password | | AuthUserChangePasswordRequest | | | | |
|
||||
| auth_user_grant | | AuthUserGrantRequest | | | | |
|
||||
| auth_role_add | | AuthRoleAddRequest | | | | |
|
||||
| auth_role_grant | | AuthRoleGrantRequest | | | | |
|
||||
| alarm | | AlarmRequest | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `LeaseGrantRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| TTL | advisory ttl in seconds | int64 | int64 | long | int/long | int64 |
|
||||
| ID | requested ID to create; 0 lets lessor choose | int64 | int64 | long | int/long | int64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `LeaseGrantResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| ID | | int64 | int64 | long | int/long | int64 |
|
||||
| TTL | server decided ttl in second | int64 | int64 | long | int/long | int64 |
|
||||
| error | | string | string | String | str/unicode | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `LeaseKeepAliveRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| ID | | int64 | int64 | long | int/long | int64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `LeaseKeepAliveResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| ID | | int64 | int64 | long | int/long | int64 |
|
||||
| TTL | | int64 | int64 | long | int/long | int64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `LeaseRevokeRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| ID | | int64 | int64 | long | int/long | int64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `LeaseRevokeResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `Member`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| ID | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| name | If the member is not started, name will be an empty string. | string | string | String | str/unicode | string |
|
||||
| peerURLs | | []string | []string | []String | []str/unicode | []string |
|
||||
| clientURLs | If the member is not started, client_URLs will be an zero length string array. | []string | []string | []String | []str/unicode | []string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `MemberAddRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| peerURLs | | []string | []string | []String | []str/unicode | []string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `MemberAddResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| member | | Member | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `MemberListRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `MemberListResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| members | | []Member | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `MemberRemoveRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| ID | | uint64 | uint64 | long | int/long | uint64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `MemberRemoveResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `MemberUpdateRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| ID | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| peerURLs | | []string | []string | []String | []str/unicode | []string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `MemberUpdateResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `Metadata`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| NodeID | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| ClusterID | | uint64 | uint64 | long | int/long | uint64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `PutRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| key | | bytes | []byte | ByteString | str | string |
|
||||
| value | | bytes | []byte | ByteString | str | string |
|
||||
| lease | | int64 | int64 | long | int/long | int64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `PutResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `RangeRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| key | if the range_end is not given, the request returns the key. | bytes | []byte | ByteString | str | string |
|
||||
| range_end | if the range_end is given, it gets the keys in range [key, range_end) if range_end is nonempty, otherwise it returns all keys >= key. | bytes | []byte | ByteString | str | string |
|
||||
| limit | limit the number of keys returned. | int64 | int64 | long | int/long | int64 |
|
||||
| revision | range over the store at the given revision. if revision is less or equal to zero, range over the newest store. if the revision has been compacted, ErrCompaction will be returned in response. | int64 | int64 | long | int/long | int64 |
|
||||
| sort_order | sort_order is the requested order for returned the results | SortOrder | | | | |
|
||||
| sort_target | sort_target is the kv field to use for sorting | SortTarget | | | | |
|
||||
| serializable | range request is linearizable by default. Linearizable requests has a higher latency and lower throughput than serializable request. To reduce latency, serializable can be set. If serializable is set, range request will be serializable, but not linearizable with other requests. Serializable range can be served locally without waiting for other nodes in the cluster. | bool | bool | boolean | boolean | bool |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `RangeResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| kvs | | []storagepb.KeyValue | | | | |
|
||||
| more | more indicates if there are more keys to return in the requested range. | bool | bool | boolean | boolean | bool |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `Request`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| ID | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| Method | | string | string | String | str/unicode | string |
|
||||
| Path | | string | string | String | str/unicode | string |
|
||||
| Val | | string | string | String | str/unicode | string |
|
||||
| Dir | | bool | bool | boolean | boolean | bool |
|
||||
| PrevValue | | string | string | String | str/unicode | string |
|
||||
| PrevIndex | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| PrevExist | | bool | bool | boolean | boolean | bool |
|
||||
| Expiration | | int64 | int64 | long | int/long | int64 |
|
||||
| Wait | | bool | bool | boolean | boolean | bool |
|
||||
| Since | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| Recursive | | bool | bool | boolean | boolean | bool |
|
||||
| Sorted | | bool | bool | boolean | boolean | bool |
|
||||
| Quorum | | bool | bool | boolean | boolean | bool |
|
||||
| Time | | int64 | int64 | long | int/long | int64 |
|
||||
| Stream | | bool | bool | boolean | boolean | bool |
|
||||
| Refresh | | bool | bool | boolean | boolean | bool |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `RequestUnion`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| request | | oneof | | | | |
|
||||
| request_range | | RangeRequest | | | | |
|
||||
| request_put | | PutRequest | | | | |
|
||||
| request_delete_range | | DeleteRangeRequest | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `ResponseHeader`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| cluster_id | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| member_id | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| revision | revision of the store when the request was applied. | int64 | int64 | long | int/long | int64 |
|
||||
| raft_term | term of raft when the request was applied. | uint64 | uint64 | long | int/long | uint64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `ResponseUnion`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| response | | oneof | | | | |
|
||||
| response_range | | RangeResponse | | | | |
|
||||
| response_put | | PutResponse | | | | |
|
||||
| response_delete_range | | DeleteRangeResponse | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `SnapshotRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `SnapshotResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | header has the current store information. The first header in the snapshot stream indicates the point in time of the snapshot. | ResponseHeader | | | | |
|
||||
| remaining_bytes | remaining_bytes is the number of blob bytes to be sent after this message | uint64 | uint64 | long | int/long | uint64 |
|
||||
| blob | blob has the next chunk of the snapshot in the snapshot stream. | bytes | []byte | ByteString | str | string |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `StatusRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `StatusResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| version | | string | string | String | str/unicode | string |
|
||||
| dbSize | | int64 | int64 | long | int/long | int64 |
|
||||
| leader | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| raftIndex | | uint64 | uint64 | long | int/long | uint64 |
|
||||
| raftTerm | | uint64 | uint64 | long | int/long | uint64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `TxnRequest`
|
||||
|
||||
If the comparisons succeed, then the success requests will be processed in order, and the response will contain their respective responses in order. If the comparisons fail, then the failure requests will be processed in order, and the response will contain their respective responses in order. From google paxosdb paper: Our implementation hinges around a powerful primitive which we call MultiOp. All other database operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically and consists of three components: 1. A list of tests called guard. Each test in guard checks a single entry in the database. It may check for the absence or presence of a value, or compare with a given value. Two different tests in the guard may apply to the same or different entries in the database. All tests in the guard are applied and MultiOp returns the results. If all tests are true, MultiOp executes t op (see item 2 below), otherwise it executes f op (see item 3 below). 2. A list of database operations called t op. Each operation in the list is either an insert, delete, or lookup operation, and applies to a single database entry. Two different operations in the list may apply to the same or different entries in the database. These operations are executed if guard evaluates to true. 3. A list of database operations called f op. Like t op, but executed if guard evaluates to false.
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| compare | | []Compare | | | | |
|
||||
| success | | []RequestUnion | | | | |
|
||||
| failure | | []RequestUnion | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `TxnResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| succeeded | | bool | bool | boolean | boolean | bool |
|
||||
| responses | | []ResponseUnion | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `WatchCancelRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| watch_id | | int64 | int64 | long | int/long | int64 |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `WatchCreateRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| key | the key to be watched | bytes | []byte | ByteString | str | string |
|
||||
| range_end | if the range_end is given, keys in [key, range_end) are watched NOTE: only range_end == prefixEnd(key) is accepted now | bytes | []byte | ByteString | str | string |
|
||||
| start_revision | start_revision is an optional revision (including) to watch from. No start_revision is "now". | int64 | int64 | long | int/long | int64 |
|
||||
| progress_notify | if progress_notify is set, etcd server sends WatchResponse with empty events to the created watcher when there are no recent events. It is useful when clients want always to be able to recover a disconnected watcher from a recent known revision. etcdsever can decide how long it should send a notification based on current load. | bool | bool | boolean | boolean | bool |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `WatchRequest`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| request_union | | oneof | | | | |
|
||||
| create_request | | WatchCreateRequest | | | | |
|
||||
| cancel_request | | WatchCancelRequest | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### message `WatchResponse`
|
||||
|
||||
| Field | Description | Type | Go | Java | Python | C++ |
|
||||
| ----- | ----------- | ---- | --- | ---- | ------ | --- |
|
||||
| header | | ResponseHeader | | | | |
|
||||
| watch_id | watch_id is the ID of the watching the response sent to. | int64 | int64 | long | int/long | int64 |
|
||||
| created | If the response is for a create watch request, created is set to true. Client should record the watch_id and prepare for receiving events for that watching from the same stream. All events sent to the created watching will attach with the same watch_id. | bool | bool | boolean | boolean | bool |
|
||||
| canceled | If the response is for a cancel watch request, cancel is set to true. No further events will be sent to the canceled watching. | bool | bool | boolean | boolean | bool |
|
||||
| compact_revision | CompactRevision is set to the minimum index if a watching tries to watch at a compacted index. This happens when creating a watching at a compacted revision or the watching cannot catch up with the progress of the KV. Client should treat the watching as canceled and should not try to create any watching with same start_revision again. | int64 | int64 | long | int/long | int64 |
|
||||
| events | | []storagepb.Event | | | | |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### service `Auth`
|
||||
|
||||
| Method | Request Type | Response Type | Description |
|
||||
| ------ | ------------ | ------------- | ----------- |
|
||||
| AuthEnable | `AuthEnableRequest` | `AuthEnableResponse` | AuthEnable enables authentication. |
|
||||
| AuthDisable | `AuthDisableRequest` | `AuthDisableResponse` | AuthDisable disables authentication. |
|
||||
| Authenticate | `AuthenticateRequest` | `AuthenticateResponse` | Authenticate processes authenticate request. |
|
||||
| UserAdd | `AuthUserAddRequest` | `AuthUserAddResponse` | UserAdd adds a new user. |
|
||||
| UserGet | `AuthUserGetRequest` | `AuthUserGetResponse` | UserGet gets a detailed information of a user or lists entire users. |
|
||||
| UserDelete | `AuthUserDeleteRequest` | `AuthUserDeleteResponse` | UserDelete deletes a specified user. |
|
||||
| UserChangePassword | `AuthUserChangePasswordRequest` | `AuthUserChangePasswordResponse` | UserChangePassword changes password of a specified user. |
|
||||
| UserGrant | `AuthUserGrantRequest` | `AuthUserGrantResponse` | UserGrant grants a role to a specified user. |
|
||||
| UserRevoke | `AuthUserRevokeRequest` | `AuthUserRevokeResponse` | UserRevoke revokes a role of specified user. |
|
||||
| RoleAdd | `AuthRoleAddRequest` | `AuthRoleAddResponse` | RoleAdd adds a new role. |
|
||||
| RoleGet | `AuthRoleGetRequest` | `AuthRoleGetResponse` | RoleGet gets a detailed information of a role or lists entire roles. |
|
||||
| RoleDelete | `AuthRoleDeleteRequest` | `AuthRoleDeleteResponse` | RoleDelete deletes a specified role. |
|
||||
| RoleGrant | `AuthRoleGrantRequest` | `AuthRoleGrantResponse` | RoleGrant grants a permission of a specified key or range to a specified role. |
|
||||
| RoleRevoke | `AuthRoleRevokeRequest` | `AuthRoleRevokeResponse` | RoleRevoke revokes a key or range permission of a specified role. |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### service `Cluster`
|
||||
|
||||
| Method | Request Type | Response Type | Description |
|
||||
| ------ | ------------ | ------------- | ----------- |
|
||||
| MemberAdd | `MemberAddRequest` | `MemberAddResponse` | MemberAdd adds a member into the cluster. |
|
||||
| MemberRemove | `MemberRemoveRequest` | `MemberRemoveResponse` | MemberRemove removes an existing member from the cluster. |
|
||||
| MemberUpdate | `MemberUpdateRequest` | `MemberUpdateResponse` | MemberUpdate updates the member configuration. |
|
||||
| MemberList | `MemberListRequest` | `MemberListResponse` | MemberList lists all the members in the cluster. |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### service `KV`
|
||||
|
||||
| Method | Request Type | Response Type | Description |
|
||||
| ------ | ------------ | ------------- | ----------- |
|
||||
| Range | `RangeRequest` | `RangeResponse` | Range gets the keys in the range from the store. |
|
||||
| Put | `PutRequest` | `PutResponse` | Put puts the given key into the store. A put request increases the revision of the store, and generates one event in the event history. |
|
||||
| DeleteRange | `DeleteRangeRequest` | `DeleteRangeResponse` | Delete deletes the given range from the store. A delete request increase the revision of the store, and generates one event in the event history. |
|
||||
| Txn | `TxnRequest` | `TxnResponse` | Txn processes all the requests in one transaction. A txn request increases the revision of the store, and generates events with the same revision in the event history. It is not allowed to modify the same key several times within one txn. |
|
||||
| Compact | `CompactionRequest` | `CompactionResponse` | Compact compacts the event history in etcd. User should compact the event history periodically, or it will grow infinitely. |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### service `Lease`
|
||||
|
||||
| Method | Request Type | Response Type | Description |
|
||||
| ------ | ------------ | ------------- | ----------- |
|
||||
| LeaseGrant | `LeaseGrantRequest` | `LeaseGrantResponse` | LeaseGrant creates a lease. A lease has a TTL. The lease will expire if the server does not receive a keepAlive within TTL from the lease holder. All keys attached to the lease will be expired and deleted if the lease expires. The key expiration generates an event in event history. |
|
||||
| LeaseRevoke | `LeaseRevokeRequest` | `LeaseRevokeResponse` | LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted. |
|
||||
| LeaseKeepAlive | `LeaseKeepAliveRequest` | `LeaseKeepAliveResponse` | KeepAlive keeps the lease alive. |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### service `Maintenance`
|
||||
|
||||
| Method | Request Type | Response Type | Description |
|
||||
| ------ | ------------ | ------------- | ----------- |
|
||||
| Alarm | `AlarmRequest` | `AlarmResponse` | Alarm activates, deactivates, and queries alarms regarding cluster health. |
|
||||
| Status | `StatusRequest` | `StatusResponse` | Status gets the status of the member. |
|
||||
| Defragment | `DefragmentRequest` | `DefragmentResponse` | |
|
||||
| Hash | `HashRequest` | `HashResponse` | Hash returns the hash of the local KV state for consistency checking purpose. This is designed for testing; do not use this in production when there are ongoing transactions. |
|
||||
| Snapshot | `SnapshotRequest` | `SnapshotResponse` | Snapshot sends a snapshot of the entire backend |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
##### service `Watch`
|
||||
|
||||
| Method | Request Type | Response Type | Description |
|
||||
| ------ | ------------ | ------------- | ----------- |
|
||||
| Watch | `WatchRequest` | `WatchResponse` | Watch watches the events happening or happened. Both input and output are stream. One watch rpc can watch for multiple keys or prefixs and get a stream of events. The whole events history can be watched unless compacted. |
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
syntax = "proto2";
|
||||
package etcdserverpb;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
|
||||
option (gogoproto.marshaler_all) = true;
|
||||
option (gogoproto.sizer_all) = true;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
option (gogoproto.goproto_getters_all) = false;
|
||||
|
||||
message Request {
|
||||
optional uint64 ID = 1 [(gogoproto.nullable) = false];
|
||||
optional string Method = 2 [(gogoproto.nullable) = false];
|
||||
optional string Path = 3 [(gogoproto.nullable) = false];
|
||||
optional string Val = 4 [(gogoproto.nullable) = false];
|
||||
optional bool Dir = 5 [(gogoproto.nullable) = false];
|
||||
optional string PrevValue = 6 [(gogoproto.nullable) = false];
|
||||
optional uint64 PrevIndex = 7 [(gogoproto.nullable) = false];
|
||||
optional bool PrevExist = 8 [(gogoproto.nullable) = true];
|
||||
optional int64 Expiration = 9 [(gogoproto.nullable) = false];
|
||||
optional bool Wait = 10 [(gogoproto.nullable) = false];
|
||||
optional uint64 Since = 11 [(gogoproto.nullable) = false];
|
||||
optional bool Recursive = 12 [(gogoproto.nullable) = false];
|
||||
optional bool Sorted = 13 [(gogoproto.nullable) = false];
|
||||
optional bool Quorum = 14 [(gogoproto.nullable) = false];
|
||||
optional int64 Time = 15 [(gogoproto.nullable) = false];
|
||||
optional bool Stream = 16 [(gogoproto.nullable) = false];
|
||||
optional bool Refresh = 17 [(gogoproto.nullable) = true];
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
optional uint64 NodeID = 1 [(gogoproto.nullable) = false];
|
||||
optional uint64 ClusterID = 2 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
syntax = "proto3";
|
||||
package etcdserverpb;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "etcdserver.proto";
|
||||
import "rpc.proto";
|
||||
|
||||
option (gogoproto.marshaler_all) = true;
|
||||
option (gogoproto.sizer_all) = true;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
option (gogoproto.goproto_getters_all) = false;
|
||||
|
||||
// An InternalRaftRequest is the union of all requests which can be
|
||||
// sent via raft.
|
||||
message InternalRaftRequest {
|
||||
uint64 ID = 1;
|
||||
Request v2 = 2;
|
||||
|
||||
RangeRequest range = 3;
|
||||
PutRequest put = 4;
|
||||
DeleteRangeRequest delete_range = 5;
|
||||
TxnRequest txn = 6;
|
||||
CompactionRequest compaction = 7;
|
||||
|
||||
LeaseGrantRequest lease_grant = 8;
|
||||
LeaseRevokeRequest lease_revoke = 9;
|
||||
|
||||
AuthEnableRequest auth_enable = 10;
|
||||
AuthUserAddRequest auth_user_add = 11;
|
||||
AuthUserDeleteRequest auth_user_delete = 12;
|
||||
AuthUserChangePasswordRequest auth_user_change_password = 13;
|
||||
AuthUserGrantRequest auth_user_grant = 14;
|
||||
AuthRoleAddRequest auth_role_add = 15;
|
||||
AuthRoleGrantRequest auth_role_grant = 16;
|
||||
|
||||
AlarmRequest alarm = 17;
|
||||
}
|
||||
|
||||
message EmptyResponse {
|
||||
}
|
||||
|
|
@ -0,0 +1,610 @@
|
|||
syntax = "proto3";
|
||||
package etcdserverpb;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "etcd/storage/storagepb/kv.proto";
|
||||
import "etcd/auth/authpb/auth.proto";
|
||||
|
||||
option (gogoproto.marshaler_all) = true;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
|
||||
service KV {
|
||||
// Range gets the keys in the range from the store.
|
||||
rpc Range(RangeRequest) returns (RangeResponse) {}
|
||||
|
||||
// Put puts the given key into the store.
|
||||
// A put request increases the revision of the store,
|
||||
// and generates one event in the event history.
|
||||
rpc Put(PutRequest) returns (PutResponse) {}
|
||||
|
||||
// Delete deletes the given range from the store.
|
||||
// A delete request increase the revision of the store,
|
||||
// and generates one event in the event history.
|
||||
rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse) {}
|
||||
|
||||
// Txn processes all the requests in one transaction.
|
||||
// A txn request increases the revision of the store,
|
||||
// and generates events with the same revision in the event history.
|
||||
// It is not allowed to modify the same key several times within one txn.
|
||||
rpc Txn(TxnRequest) returns (TxnResponse) {}
|
||||
|
||||
// Compact compacts the event history in etcd. User should compact the
|
||||
// event history periodically, or it will grow infinitely.
|
||||
rpc Compact(CompactionRequest) returns (CompactionResponse) {}
|
||||
}
|
||||
|
||||
service Watch {
|
||||
// Watch watches the events happening or happened. Both input and output
|
||||
// are stream. One watch rpc can watch for multiple keys or prefixs and
|
||||
// get a stream of events. The whole events history can be watched unless
|
||||
// compacted.
|
||||
rpc Watch(stream WatchRequest) returns (stream WatchResponse) {}
|
||||
}
|
||||
|
||||
service Lease {
|
||||
// LeaseGrant creates a lease. A lease has a TTL. The lease will expire if the
|
||||
// server does not receive a keepAlive within TTL from the lease holder.
|
||||
// All keys attached to the lease will be expired and deleted if the lease expires.
|
||||
// The key expiration generates an event in event history.
|
||||
rpc LeaseGrant(LeaseGrantRequest) returns (LeaseGrantResponse) {}
|
||||
|
||||
// LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted.
|
||||
rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) {}
|
||||
|
||||
// KeepAlive keeps the lease alive.
|
||||
rpc LeaseKeepAlive(stream LeaseKeepAliveRequest) returns (stream LeaseKeepAliveResponse) {}
|
||||
|
||||
// TODO(xiangli) List all existing Leases?
|
||||
// TODO(xiangli) Get details information (expirations, leased keys, etc.) of a lease?
|
||||
}
|
||||
|
||||
service Cluster {
|
||||
// MemberAdd adds a member into the cluster.
|
||||
rpc MemberAdd(MemberAddRequest) returns (MemberAddResponse) {}
|
||||
|
||||
// MemberRemove removes an existing member from the cluster.
|
||||
rpc MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse) {}
|
||||
|
||||
// MemberUpdate updates the member configuration.
|
||||
rpc MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse) {}
|
||||
|
||||
// MemberList lists all the members in the cluster.
|
||||
rpc MemberList(MemberListRequest) returns (MemberListResponse) {}
|
||||
}
|
||||
|
||||
service Maintenance {
|
||||
// Alarm activates, deactivates, and queries alarms regarding cluster health.
|
||||
rpc Alarm(AlarmRequest) returns (AlarmResponse) {}
|
||||
|
||||
// Status gets the status of the member.
|
||||
rpc Status(StatusRequest) returns (StatusResponse) {}
|
||||
|
||||
rpc Defragment(DefragmentRequest) returns (DefragmentResponse) {}
|
||||
|
||||
// Hash returns the hash of the local KV state for consistency checking purpose.
|
||||
// This is designed for testing; do not use this in production when there
|
||||
// are ongoing transactions.
|
||||
rpc Hash(HashRequest) returns (HashResponse) {}
|
||||
|
||||
// Snapshot sends a snapshot of the entire backend
|
||||
rpc Snapshot(SnapshotRequest) returns (stream SnapshotResponse) {}
|
||||
}
|
||||
|
||||
service Auth {
|
||||
// AuthEnable enables authentication.
|
||||
rpc AuthEnable(AuthEnableRequest) returns (AuthEnableResponse) {}
|
||||
|
||||
// AuthDisable disables authentication.
|
||||
rpc AuthDisable(AuthDisableRequest) returns (AuthDisableResponse) {}
|
||||
|
||||
// Authenticate processes authenticate request.
|
||||
rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {}
|
||||
|
||||
// UserAdd adds a new user.
|
||||
rpc UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse) {}
|
||||
|
||||
// UserGet gets a detailed information of a user or lists entire users.
|
||||
rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) {}
|
||||
|
||||
// UserDelete deletes a specified user.
|
||||
rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) {}
|
||||
|
||||
// UserChangePassword changes password of a specified user.
|
||||
rpc UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse) {}
|
||||
|
||||
// UserGrant grants a role to a specified user.
|
||||
rpc UserGrant(AuthUserGrantRequest) returns (AuthUserGrantResponse) {}
|
||||
|
||||
// UserRevoke revokes a role of specified user.
|
||||
rpc UserRevoke(AuthUserRevokeRequest) returns (AuthUserRevokeResponse) {}
|
||||
|
||||
// RoleAdd adds a new role.
|
||||
rpc RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse) {}
|
||||
|
||||
// RoleGet gets a detailed information of a role or lists entire roles.
|
||||
rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) {}
|
||||
|
||||
// RoleDelete deletes a specified role.
|
||||
rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) {}
|
||||
|
||||
// RoleGrant grants a permission of a specified key or range to a specified role.
|
||||
rpc RoleGrant(AuthRoleGrantRequest) returns (AuthRoleGrantResponse) {}
|
||||
|
||||
// RoleRevoke revokes a key or range permission of a specified role.
|
||||
rpc RoleRevoke(AuthRoleRevokeRequest) returns (AuthRoleRevokeResponse) {}
|
||||
}
|
||||
|
||||
message ResponseHeader {
|
||||
uint64 cluster_id = 1;
|
||||
uint64 member_id = 2;
|
||||
// revision of the store when the request was applied.
|
||||
int64 revision = 3;
|
||||
// term of raft when the request was applied.
|
||||
uint64 raft_term = 4;
|
||||
}
|
||||
|
||||
message RangeRequest {
|
||||
enum SortOrder {
|
||||
NONE = 0; // default, no sorting
|
||||
ASCEND = 1; // lowest target value first
|
||||
DESCEND = 2; // highest target value first
|
||||
}
|
||||
enum SortTarget {
|
||||
KEY = 0;
|
||||
VERSION = 1;
|
||||
CREATE = 2;
|
||||
MOD = 3;
|
||||
VALUE = 4;
|
||||
}
|
||||
|
||||
// if the range_end is not given, the request returns the key.
|
||||
bytes key = 1;
|
||||
// if the range_end is given, it gets the keys in range [key, range_end)
|
||||
// if range_end is nonempty, otherwise it returns all keys >= key.
|
||||
bytes range_end = 2;
|
||||
// limit the number of keys returned.
|
||||
int64 limit = 3;
|
||||
// range over the store at the given revision.
|
||||
// if revision is less or equal to zero, range over the newest store.
|
||||
// if the revision has been compacted, ErrCompaction will be returned in
|
||||
// response.
|
||||
int64 revision = 4;
|
||||
|
||||
// sort_order is the requested order for returned the results
|
||||
SortOrder sort_order = 5;
|
||||
|
||||
// sort_target is the kv field to use for sorting
|
||||
SortTarget sort_target = 6;
|
||||
|
||||
// range request is linearizable by default. Linearizable requests has a higher
|
||||
// latency and lower throughput than serializable request.
|
||||
// To reduce latency, serializable can be set. If serializable is set, range request
|
||||
// will be serializable, but not linearizable with other requests.
|
||||
// Serializable range can be served locally without waiting for other nodes in the cluster.
|
||||
bool serializable = 7;
|
||||
}
|
||||
|
||||
message RangeResponse {
|
||||
ResponseHeader header = 1;
|
||||
repeated storagepb.KeyValue kvs = 2;
|
||||
// more indicates if there are more keys to return in the requested range.
|
||||
bool more = 3;
|
||||
}
|
||||
|
||||
message PutRequest {
|
||||
bytes key = 1;
|
||||
bytes value = 2;
|
||||
int64 lease = 3;
|
||||
}
|
||||
|
||||
message PutResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message DeleteRangeRequest {
|
||||
// if the range_end is not given, the request deletes the key.
|
||||
bytes key = 1;
|
||||
// if the range_end is given, it deletes the keys in range [key, range_end).
|
||||
bytes range_end = 2;
|
||||
}
|
||||
|
||||
message DeleteRangeResponse {
|
||||
ResponseHeader header = 1;
|
||||
// Deleted is the number of keys that got deleted.
|
||||
int64 deleted = 2;
|
||||
}
|
||||
|
||||
message RequestUnion {
|
||||
oneof request {
|
||||
RangeRequest request_range = 1;
|
||||
PutRequest request_put = 2;
|
||||
DeleteRangeRequest request_delete_range = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message ResponseUnion {
|
||||
oneof response {
|
||||
RangeResponse response_range = 1;
|
||||
PutResponse response_put = 2;
|
||||
DeleteRangeResponse response_delete_range = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message Compare {
|
||||
enum CompareResult {
|
||||
EQUAL = 0;
|
||||
GREATER = 1;
|
||||
LESS = 2;
|
||||
}
|
||||
enum CompareTarget {
|
||||
VERSION = 0;
|
||||
CREATE = 1;
|
||||
MOD = 2;
|
||||
VALUE= 3;
|
||||
}
|
||||
CompareResult result = 1;
|
||||
CompareTarget target = 2;
|
||||
// key path
|
||||
bytes key = 3;
|
||||
oneof target_union {
|
||||
// version of the given key
|
||||
int64 version = 4;
|
||||
// create revision of the given key
|
||||
int64 create_revision = 5;
|
||||
// last modified revision of the given key
|
||||
int64 mod_revision = 6;
|
||||
// value of the given key
|
||||
bytes value = 7;
|
||||
}
|
||||
}
|
||||
|
||||
// If the comparisons succeed, then the success requests will be processed in order,
|
||||
// and the response will contain their respective responses in order.
|
||||
// If the comparisons fail, then the failure requests will be processed in order,
|
||||
// and the response will contain their respective responses in order.
|
||||
|
||||
// From google paxosdb paper:
|
||||
// Our implementation hinges around a powerful primitive which we call MultiOp. All other database
|
||||
// operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically
|
||||
// and consists of three components:
|
||||
// 1. A list of tests called guard. Each test in guard checks a single entry in the database. It may check
|
||||
// for the absence or presence of a value, or compare with a given value. Two different tests in the guard
|
||||
// may apply to the same or different entries in the database. All tests in the guard are applied and
|
||||
// MultiOp returns the results. If all tests are true, MultiOp executes t op (see item 2 below), otherwise
|
||||
// it executes f op (see item 3 below).
|
||||
// 2. A list of database operations called t op. Each operation in the list is either an insert, delete, or
|
||||
// lookup operation, and applies to a single database entry. Two different operations in the list may apply
|
||||
// to the same or different entries in the database. These operations are executed
|
||||
// if guard evaluates to
|
||||
// true.
|
||||
// 3. A list of database operations called f op. Like t op, but executed if guard evaluates to false.
|
||||
message TxnRequest {
|
||||
repeated Compare compare = 1;
|
||||
repeated RequestUnion success = 2;
|
||||
repeated RequestUnion failure = 3;
|
||||
}
|
||||
|
||||
message TxnResponse {
|
||||
ResponseHeader header = 1;
|
||||
bool succeeded = 2;
|
||||
repeated ResponseUnion responses = 3;
|
||||
}
|
||||
|
||||
// Compaction compacts the kv store upto a given revision. All superseded keys
|
||||
// with a revision less than the compaction revision will be removed.
|
||||
message CompactionRequest {
|
||||
int64 revision = 1;
|
||||
// physical is set so the RPC will wait until the compaction is physically
|
||||
// applied to the local database such that compacted entries are totally
|
||||
// removed from the backing store.
|
||||
bool physical = 2;
|
||||
}
|
||||
|
||||
message CompactionResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message HashRequest {
|
||||
}
|
||||
|
||||
message HashResponse {
|
||||
ResponseHeader header = 1;
|
||||
uint32 hash = 2;
|
||||
}
|
||||
|
||||
message SnapshotRequest {
|
||||
}
|
||||
|
||||
message SnapshotResponse {
|
||||
// header has the current store information. The first header in the snapshot
|
||||
// stream indicates the point in time of the snapshot.
|
||||
ResponseHeader header = 1;
|
||||
|
||||
// remaining_bytes is the number of blob bytes to be sent after this message
|
||||
uint64 remaining_bytes = 2;
|
||||
|
||||
// blob has the next chunk of the snapshot in the snapshot stream.
|
||||
bytes blob = 3;
|
||||
}
|
||||
|
||||
message WatchRequest {
|
||||
oneof request_union {
|
||||
WatchCreateRequest create_request = 1;
|
||||
WatchCancelRequest cancel_request = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message WatchCreateRequest {
|
||||
// the key to be watched
|
||||
bytes key = 1;
|
||||
// if the range_end is given, keys in [key, range_end) are watched
|
||||
// NOTE: only range_end == prefixEnd(key) is accepted now
|
||||
bytes range_end = 2;
|
||||
// start_revision is an optional revision (including) to watch from. No start_revision is "now".
|
||||
int64 start_revision = 3;
|
||||
// if progress_notify is set, etcd server sends WatchResponse with empty events to the
|
||||
// created watcher when there are no recent events. It is useful when clients want always to be
|
||||
// able to recover a disconnected watcher from a recent known revision.
|
||||
// etcdsever can decide how long it should send a notification based on current load.
|
||||
bool progress_notify = 4;
|
||||
}
|
||||
|
||||
message WatchCancelRequest {
|
||||
int64 watch_id = 1;
|
||||
}
|
||||
|
||||
message WatchResponse {
|
||||
ResponseHeader header = 1;
|
||||
// watch_id is the ID of the watching the response sent to.
|
||||
int64 watch_id = 2;
|
||||
// If the response is for a create watch request, created is set to true.
|
||||
// Client should record the watch_id and prepare for receiving events for
|
||||
// that watching from the same stream.
|
||||
// All events sent to the created watching will attach with the same watch_id.
|
||||
bool created = 3;
|
||||
// If the response is for a cancel watch request, cancel is set to true.
|
||||
// No further events will be sent to the canceled watching.
|
||||
bool canceled = 4;
|
||||
// CompactRevision is set to the minimum index if a watching tries to watch
|
||||
// at a compacted index.
|
||||
//
|
||||
// This happens when creating a watching at a compacted revision or the watching cannot
|
||||
// catch up with the progress of the KV.
|
||||
//
|
||||
// Client should treat the watching as canceled and should not try to create any
|
||||
// watching with same start_revision again.
|
||||
int64 compact_revision = 5;
|
||||
|
||||
repeated storagepb.Event events = 11;
|
||||
}
|
||||
|
||||
message LeaseGrantRequest {
|
||||
// advisory ttl in seconds
|
||||
int64 TTL = 1;
|
||||
// requested ID to create; 0 lets lessor choose
|
||||
int64 ID = 2;
|
||||
}
|
||||
|
||||
message LeaseGrantResponse {
|
||||
ResponseHeader header = 1;
|
||||
int64 ID = 2;
|
||||
// server decided ttl in second
|
||||
int64 TTL = 3;
|
||||
string error = 4;
|
||||
}
|
||||
|
||||
message LeaseRevokeRequest {
|
||||
int64 ID = 1;
|
||||
}
|
||||
|
||||
message LeaseRevokeResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message LeaseKeepAliveRequest {
|
||||
int64 ID = 1;
|
||||
}
|
||||
|
||||
message LeaseKeepAliveResponse {
|
||||
ResponseHeader header = 1;
|
||||
int64 ID = 2;
|
||||
int64 TTL = 3;
|
||||
}
|
||||
|
||||
message Member {
|
||||
uint64 ID = 1;
|
||||
// If the member is not started, name will be an empty string.
|
||||
string name = 2;
|
||||
repeated string peerURLs = 3;
|
||||
// If the member is not started, client_URLs will be an zero length
|
||||
// string array.
|
||||
repeated string clientURLs = 4;
|
||||
}
|
||||
|
||||
message MemberAddRequest {
|
||||
repeated string peerURLs = 1;
|
||||
}
|
||||
|
||||
message MemberAddResponse {
|
||||
ResponseHeader header = 1;
|
||||
Member member = 2;
|
||||
}
|
||||
|
||||
message MemberRemoveRequest {
|
||||
uint64 ID = 1;
|
||||
}
|
||||
|
||||
message MemberRemoveResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message MemberUpdateRequest {
|
||||
uint64 ID = 1;
|
||||
repeated string peerURLs = 2;
|
||||
}
|
||||
|
||||
message MemberUpdateResponse{
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message MemberListRequest {
|
||||
}
|
||||
|
||||
message MemberListResponse {
|
||||
ResponseHeader header = 1;
|
||||
repeated Member members = 2;
|
||||
}
|
||||
|
||||
message DefragmentRequest {
|
||||
}
|
||||
|
||||
message DefragmentResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
enum AlarmType {
|
||||
NONE = 0; // default, used to query if any alarm is active
|
||||
NOSPACE = 1;
|
||||
}
|
||||
|
||||
message AlarmRequest {
|
||||
enum AlarmAction {
|
||||
GET = 0;
|
||||
ACTIVATE = 1;
|
||||
DEACTIVATE = 2;
|
||||
}
|
||||
AlarmAction action = 1;
|
||||
// MemberID is the member raising the alarm request
|
||||
uint64 memberID = 2;
|
||||
AlarmType alarm = 3;
|
||||
}
|
||||
|
||||
message AlarmMember {
|
||||
uint64 memberID = 1;
|
||||
AlarmType alarm = 2;
|
||||
}
|
||||
|
||||
message AlarmResponse {
|
||||
ResponseHeader header = 1;
|
||||
repeated AlarmMember alarms = 2;
|
||||
}
|
||||
|
||||
message StatusRequest {
|
||||
}
|
||||
|
||||
message StatusResponse {
|
||||
ResponseHeader header = 1;
|
||||
string version = 2;
|
||||
int64 dbSize = 3;
|
||||
uint64 leader = 4;
|
||||
uint64 raftIndex = 5;
|
||||
uint64 raftTerm = 6;
|
||||
}
|
||||
|
||||
message AuthEnableRequest {
|
||||
}
|
||||
|
||||
message AuthDisableRequest {
|
||||
}
|
||||
|
||||
message AuthenticateRequest {
|
||||
}
|
||||
|
||||
message AuthUserAddRequest {
|
||||
string name = 1;
|
||||
string password = 2;
|
||||
}
|
||||
|
||||
message AuthUserGetRequest {
|
||||
}
|
||||
|
||||
message AuthUserDeleteRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message AuthUserChangePasswordRequest {
|
||||
string name = 1;
|
||||
string password = 2;
|
||||
}
|
||||
|
||||
message AuthUserGrantRequest {
|
||||
string user = 1;
|
||||
string role = 2;
|
||||
}
|
||||
|
||||
message AuthUserRevokeRequest {
|
||||
}
|
||||
|
||||
message AuthRoleAddRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message AuthRoleGetRequest {
|
||||
}
|
||||
|
||||
message AuthRoleDeleteRequest {
|
||||
}
|
||||
|
||||
message AuthRoleGrantRequest {
|
||||
string name = 1;
|
||||
authpb.Permission perm = 2;
|
||||
}
|
||||
|
||||
message AuthRoleRevokeRequest {
|
||||
}
|
||||
|
||||
message AuthEnableResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthDisableResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthenticateResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthUserAddResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthUserGetResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthUserDeleteResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthUserChangePasswordResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthUserGrantResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthUserRevokeResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthRoleAddResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthRoleGetResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthRoleDeleteResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthRoleGrantResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
||||
message AuthRoleRevokeResponse {
|
||||
ResponseHeader header = 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package parse
|
||||
|
||||
import "fmt"
|
||||
|
||||
// https://developers.google.com/protocol-buffers/docs/proto3#scalar
|
||||
type (
|
||||
ProtoType int
|
||||
ProtoTypeCpp int
|
||||
ProtoTypeJava int
|
||||
ProtoTypePython int
|
||||
ProtoTypeGo int
|
||||
ProtoTypeRuby int
|
||||
ProtoTypeCsharp int
|
||||
)
|
||||
|
||||
const (
|
||||
Double ProtoType = iota
|
||||
Float
|
||||
Int32
|
||||
Int64
|
||||
Uint32
|
||||
Uint64
|
||||
Sint32
|
||||
Sint64
|
||||
Fixed32
|
||||
Fixed64
|
||||
Sfixed32
|
||||
Sfixed64
|
||||
Bool
|
||||
String
|
||||
Bytes
|
||||
)
|
||||
|
||||
var (
|
||||
ProtoTypes = [...]string{
|
||||
"double",
|
||||
"float",
|
||||
"int32",
|
||||
"int64",
|
||||
"uint32",
|
||||
"uint64",
|
||||
"sint32",
|
||||
"sint64",
|
||||
"fixed32",
|
||||
"fixed64",
|
||||
"sfixed32",
|
||||
"sfixed64",
|
||||
"bool",
|
||||
"string",
|
||||
"bytes",
|
||||
}
|
||||
|
||||
protoTypesMap = map[string]ProtoType{
|
||||
"double": Double,
|
||||
"float": Float,
|
||||
"int32": Int32,
|
||||
"int64": Int64,
|
||||
"uint32": Uint32,
|
||||
"uint64": Uint64,
|
||||
"sint32": Sint32,
|
||||
"sint64": Sint64,
|
||||
"fixed32": Fixed32,
|
||||
"fixed64": Fixed64,
|
||||
"sfixed32": Sfixed32,
|
||||
"sfixed64": Sfixed64,
|
||||
"bool": Bool,
|
||||
"string": String,
|
||||
"bytes": Bytes,
|
||||
}
|
||||
|
||||
ToCpp = map[ProtoType]string{
|
||||
Double: "double",
|
||||
Float: "float",
|
||||
Int32: "int32",
|
||||
Int64: "int64",
|
||||
Uint32: "uint32",
|
||||
Uint64: "uint64",
|
||||
Sint32: "int32",
|
||||
Sint64: "int64",
|
||||
Fixed32: "uint32",
|
||||
Fixed64: "uint64",
|
||||
Sfixed32: "int32",
|
||||
Sfixed64: "int64",
|
||||
Bool: "bool",
|
||||
String: "string",
|
||||
Bytes: "string",
|
||||
}
|
||||
|
||||
ToJava = map[ProtoType]string{
|
||||
Double: "double",
|
||||
Float: "float",
|
||||
Int32: "int",
|
||||
Int64: "long",
|
||||
Uint32: "int",
|
||||
Uint64: "long",
|
||||
Sint32: "int",
|
||||
Sint64: "long",
|
||||
Fixed32: "int",
|
||||
Fixed64: "long",
|
||||
Sfixed32: "int32",
|
||||
Sfixed64: "int64",
|
||||
Bool: "boolean",
|
||||
String: "String",
|
||||
Bytes: "ByteString",
|
||||
}
|
||||
|
||||
ToPython = map[ProtoType]string{
|
||||
Double: "float",
|
||||
Float: "float",
|
||||
Int32: "int",
|
||||
Int64: "int/long",
|
||||
Uint32: "int/long",
|
||||
Uint64: "int/long",
|
||||
Sint32: "int",
|
||||
Sint64: "int/long",
|
||||
Fixed32: "int",
|
||||
Fixed64: "int/long",
|
||||
Sfixed32: "int",
|
||||
Sfixed64: "int/long",
|
||||
Bool: "boolean",
|
||||
String: "str/unicode",
|
||||
Bytes: "str",
|
||||
}
|
||||
|
||||
ToGo = map[ProtoType]string{
|
||||
Double: "float64",
|
||||
Float: "float32",
|
||||
Int32: "int32",
|
||||
Int64: "int64",
|
||||
Uint32: "uint32",
|
||||
Uint64: "uint64",
|
||||
Sint32: "int32",
|
||||
Sint64: "int64",
|
||||
Fixed32: "uint32",
|
||||
Fixed64: "uint64",
|
||||
Sfixed32: "int32",
|
||||
Sfixed64: "int64",
|
||||
Bool: "bool",
|
||||
String: "string",
|
||||
Bytes: "[]byte",
|
||||
}
|
||||
|
||||
ToRuby = map[ProtoType]string{
|
||||
Double: "Float",
|
||||
Float: "Float",
|
||||
Int32: "Fixnum or Bignum (as required)",
|
||||
Int64: "Bignum",
|
||||
Uint32: "Fixnum or Bignum (as required)",
|
||||
Uint64: "Bignum",
|
||||
Sint32: "Fixnum or Bignum (as required)",
|
||||
Sint64: "Bignum",
|
||||
Fixed32: "Fixnum or Bignum (as required)",
|
||||
Fixed64: "Bignum",
|
||||
Sfixed32: "Fixnum or Bignum (as required)",
|
||||
Sfixed64: "Bignum",
|
||||
Bool: "TrueClass/FalseClass",
|
||||
String: "String (UTF-8)",
|
||||
Bytes: "String (ASCII-8BIT)",
|
||||
}
|
||||
|
||||
ToCsharp = map[ProtoType]string{
|
||||
Double: "double",
|
||||
Float: "float",
|
||||
Int32: "int",
|
||||
Int64: "long",
|
||||
Uint32: "uint",
|
||||
Uint64: "ulong",
|
||||
Sint32: "int",
|
||||
Sint64: "long",
|
||||
Fixed32: "uint",
|
||||
Fixed64: "ulong",
|
||||
Sfixed32: "int",
|
||||
Sfixed64: "long",
|
||||
Bool: "bool",
|
||||
String: "string",
|
||||
Bytes: "ByteString",
|
||||
}
|
||||
)
|
||||
|
||||
// ToProtoType parses string to return 'ProtoType'.
|
||||
func ToProtoType(s string) (ProtoType, error) {
|
||||
v, ok := protoTypesMap[s]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("%q is not defined", s)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (t ProtoType) String() string {
|
||||
return ProtoTypes[t]
|
||||
}
|
||||
|
||||
func (t ProtoType) Cpp() string {
|
||||
return ToCpp[t]
|
||||
}
|
||||
|
||||
func (t ProtoType) Java() string {
|
||||
return ToJava[t]
|
||||
}
|
||||
|
||||
func (t ProtoType) Python() string {
|
||||
return ToPython[t]
|
||||
}
|
||||
|
||||
func (t ProtoType) Go() string {
|
||||
return ToGo[t]
|
||||
}
|
||||
|
||||
func (t ProtoType) Ruby() string {
|
||||
return ToRuby[t]
|
||||
}
|
||||
|
||||
func (t ProtoType) Csharp() string {
|
||||
return ToCsharp[t]
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package parse
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestTypes(t *testing.T) {
|
||||
tt, err := ToProtoType("sint32")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if tt != Sint32 {
|
||||
t.Fatalf("unexpected %v", tt)
|
||||
}
|
||||
if tt.Go() != "int32" {
|
||||
t.Fatalf("unexpected %s", tt.Go())
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package parse
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// walkDirExt returns all FileInfos with specific extension.
|
||||
// Make sure to prefix the extension name with dot.
|
||||
// For example, to find all go files, pass ".go".
|
||||
func walkDirExt(targetDir, ext string) (map[os.FileInfo]string, error) {
|
||||
rmap := make(map[os.FileInfo]string)
|
||||
visit := func(path string, f os.FileInfo, err error) error {
|
||||
if f != nil {
|
||||
if !f.IsDir() {
|
||||
if filepath.Ext(path) == ext {
|
||||
if !filepath.HasPrefix(path, ".") && !strings.Contains(path, "/.") {
|
||||
if _, ok := rmap[f]; !ok {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
thepath := filepath.Join(wd, strings.Replace(path, wd, "", -1))
|
||||
rmap[f] = thepath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := filepath.Walk(targetDir, visit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rmap, nil
|
||||
}
|
||||
|
||||
func toFile(txt, fpath string) error {
|
||||
f, err := os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
f, err = os.Create(fpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := f.WriteString(txt); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
TEST=./...;
|
||||
FMT="*.go"
|
||||
|
||||
echo "Running tests...";
|
||||
go test -v -cover -cpu 1,2,4 $TEST;
|
||||
go test -v -cover -cpu 1,2,4 -race $TEST;
|
||||
|
||||
echo "Checking gofmt..."
|
||||
fmtRes=$(gofmt -l -s $FMT)
|
||||
if [ -n "${fmtRes}" ]; then
|
||||
echo -e "gofmt checking failed:\n${fmtRes}"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
echo "Checking govet..."
|
||||
vetRes=$(go vet $TEST)
|
||||
if [ -n "${vetRes}" ]; then
|
||||
echo -e "govet checking failed:\n${vetRes}"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
echo "Success";
|
||||
|
||||
Loading…
Reference in New Issue