Add initial API generation bits (#20)

* Add initial API generation bits

* Revert accidental changes to oplog
pull/22/head
Jeff Mitchell 6 years ago committed by GitHub
parent 7f03246c6f
commit 2926cc1000
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,44 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-05-03 14:33:51.4620286 -0400 EDT m=+0.042201401
package api
import (
"encoding/json"
"github.com/fatih/structs"
"github.com/hashicorp/watchtower/api/internal/strutil"
)
type Error struct {
defaultFields []string
// The HTTP Status code applicable to this error
Status *int64 `json:"status,omitempty"`
// An application-specific error string
Code *string `json:"code,omitempty"`
// A human readable explanation specific to this occurrence of the error
Message *string `json:"message,omitempty"`
// Additional metadata regarding the error. Depending on the error
// different fields will be populated.
Details *ErrorDetails `json:"details,omitempty"`
}
func (s *Error) SetDefault(key string) {
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
}
func (s *Error) UnsetDefault(key string) {
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
}
func (s Error) MarshalJSON() ([]byte, error) {
m := structs.Map(s)
if m == nil {
m = make(map[string]interface{})
}
for _, k := range s.defaultFields {
m[k] = nil
}
return json.Marshal(m)
}

@ -0,0 +1,38 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-05-03 14:33:51.462308 -0400 EDT m=+0.042480801
package api
import (
"encoding/json"
"github.com/fatih/structs"
"github.com/hashicorp/watchtower/api/internal/strutil"
)
type ErrorDetails struct {
defaultFields []string
TraceId *string `json:"trace_id,omitempty"`
RequestId *string `json:"request_id,omitempty"`
RequestFields []string `json:"request_fields,omitempty"`
}
func (s *ErrorDetails) SetDefault(key string) {
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
}
func (s *ErrorDetails) UnsetDefault(key string) {
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
}
func (s ErrorDetails) MarshalJSON() ([]byte, error) {
m := structs.Map(s)
if m == nil {
m = make(map[string]interface{})
}
for _, k := range s.defaultFields {
m[k] = nil
}
return json.Marshal(m)
}

@ -0,0 +1,42 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-05-03 14:33:51.4628286 -0400 EDT m=+0.043001401
package hosts
import (
"fmt"
"github.com/mitchellh/mapstructure"
)
type AwsEc2HostCatalog struct {
*HostCatalog
// The AWS regions from which this catalog will retrieve the EC2 instances.
Regions []string `json:"regions,omitempty"`
// The access key used for authenticating with AWS when retrieving EC2 instance details.
AccessKey *string `json:"access_key,omitempty"`
// Input only.
SecretKey *string `json:"secret_key,omitempty"`
// This value will never be returned in a response.
Rotate *bool `json:"rotate,omitempty"`
}
func (s HostCatalog) AsAwsEc2HostCatalog() (*AwsEc2HostCatalog, error) {
out := &AwsEc2HostCatalog{
HostCatalog: &s,
}
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: out,
TagName: "json",
})
if err != nil {
return nil, fmt.Errorf("error creating map decoder: %w", err)
}
if err := decoder.Decode(s.Attributes); err != nil {
return nil, fmt.Errorf("error decoding attributes map: %w", err)
}
return out, nil
}

@ -0,0 +1,53 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-05-03 14:33:51.4624224 -0400 EDT m=+0.042595201
package hosts
import (
"encoding/json"
"time"
"github.com/fatih/structs"
"github.com/hashicorp/watchtower/api/internal/strutil"
)
type Host struct {
defaultFields []string
// Canonical path of the resource from the API's base URI
// Output only.
Path *string `json:"path,omitempty"`
// The type of the resource, to help differentiate schemas
Type *string `json:"type,omitempty"`
// Friendly name, if set
FriendlyName *string `json:"friendly_name,omitempty"`
// The time this host was created
// Ouput only.
CreatedTime time.Time `json:"created_time,omitempty"`
// The time this host was last updated
// Output only.
UpdatedTime time.Time `json:"updated_time,omitempty"`
// Whether the host is disabled
Disabled *bool `json:"disabled,omitempty"`
// The address (DNS or IP name) used to reach the host
Address *string `json:"address,omitempty"`
}
func (s *Host) SetDefault(key string) {
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
}
func (s *Host) UnsetDefault(key string) {
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
}
func (s Host) MarshalJSON() ([]byte, error) {
m := structs.Map(s)
if m == nil {
m = make(map[string]interface{})
}
for _, k := range s.defaultFields {
m[k] = nil
}
return json.Marshal(m)
}

@ -0,0 +1,54 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-05-03 14:33:51.4626029 -0400 EDT m=+0.042775701
package hosts
import (
"encoding/json"
"time"
"github.com/fatih/structs"
"github.com/hashicorp/watchtower/api/internal/strutil"
)
type HostCatalog struct {
defaultFields []string
// Canonical path of the resource from the API's base URI
// Output only.
Path *string `json:"path,omitempty"`
// The type of the resource, to help differentiate schemas
Type *string `json:"type,omitempty"`
// Friendly name, if set
FriendlyName *string `json:"friendly_name,omitempty"`
// The time this host was created
// Output only.
CreatedTime time.Time `json:"created_time,omitempty"`
// The time this host was last updated
// Output only.
UpdatedTime time.Time `json:"updated_time,omitempty"`
// Whether the catalog is disabled
Disabled *bool `json:"disabled,omitempty"`
// Attributes specific to the catalog type
Attributes map[string]interface {
} `json:"attributes,omitempty"`
}
func (s *HostCatalog) SetDefault(key string) {
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
}
func (s *HostCatalog) UnsetDefault(key string) {
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
}
func (s HostCatalog) MarshalJSON() ([]byte, error) {
m := structs.Map(s)
if m == nil {
m = make(map[string]interface{})
}
for _, k := range s.defaultFields {
m[k] = nil
}
return json.Marshal(m)
}

@ -0,0 +1,59 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-05-03 14:33:51.4625345 -0400 EDT m=+0.042707301
package hosts
import (
"encoding/json"
"time"
"github.com/fatih/structs"
"github.com/hashicorp/watchtower/api/internal/strutil"
)
type HostSet struct {
defaultFields []string
// Canonical path of the resource from the API's base URI
// Output only.
Path *string `json:"path,omitempty"`
// The type of the resource, to help differentiate schemas
Type *string `json:"type,omitempty"`
// Friendly name, if set
FriendlyName *string `json:"friendly_name,omitempty"`
// The time this host was created
// Output only.
CreatedTime time.Time `json:"created_time,omitempty"`
// The time this host was last updated
// Output only.
UpdatedTime time.Time `json:"updated_time,omitempty"`
// Whether the host set is disabled
Disabled *bool `json:"disabled,omitempty"`
// The total count of hosts in this host set
// Output only.
Size *int64 `json:"size,omitempty"`
// A list of hosts in this host set
// TODO: Figure out if this should be in the basic HostSet view and what
// view to use on the Hosts.
// Output only.
Hosts []*Host `json:"hosts,omitempty"`
}
func (s *HostSet) SetDefault(key string) {
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
}
func (s *HostSet) UnsetDefault(key string) {
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
}
func (s HostSet) MarshalJSON() ([]byte, error) {
m := structs.Map(s)
if m == nil {
m = make(map[string]interface{})
}
for _, k := range s.defaultFields {
m[k] = nil
}
return json.Marshal(m)
}

@ -0,0 +1,33 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-05-03 14:33:51.4627143 -0400 EDT m=+0.042887101
package hosts
import (
"fmt"
"github.com/mitchellh/mapstructure"
)
type StaticHostCatalog struct {
*HostCatalog
}
func (s HostCatalog) AsStaticHostCatalog() (*StaticHostCatalog, error) {
out := &StaticHostCatalog{
HostCatalog: &s,
}
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: out,
TagName: "json",
})
if err != nil {
return nil, fmt.Errorf("error creating map decoder: %w", err)
}
if err := decoder.Decode(s.Attributes); err != nil {
return nil, fmt.Errorf("error decoding attributes map: %w", err)
}
return out, nil
}

@ -0,0 +1,488 @@
package main
// +build genapi
import (
"bufio"
"bytes"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"text/template"
"time"
)
type templateType int
const (
templateTypeResource templateType = iota
templateTypeDetail
)
type generateInfo struct {
inFile string
inName string
outFile string
outName string
outPkg string
structFields string
parentName string
detailName string
templateType templateType
}
var (
regex = regexp.MustCompile(`(json:".*")`)
inputStructs = []*generateInfo{
{
os.Getenv("APIGEN_BASEPATH") + "/internal/gen/controller/api/error.pb.go",
"Error",
os.Getenv("APIGEN_BASEPATH") + "/api/error.go",
"Error",
"api",
"",
"",
"",
templateTypeResource,
},
{
os.Getenv("APIGEN_BASEPATH") + "/internal/gen/controller/api/error.pb.go",
"ErrorDetails",
os.Getenv("APIGEN_BASEPATH") + "/api/error_details.go",
"ErrorDetails",
"api",
"",
"",
"",
templateTypeResource,
},
{
os.Getenv("APIGEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host.pb.go",
"Host",
os.Getenv("APIGEN_BASEPATH") + "/api/hosts/host.go",
"Host",
"hosts",
"",
"",
"",
templateTypeResource,
},
{
os.Getenv("APIGEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_set.pb.go",
"HostSet",
os.Getenv("APIGEN_BASEPATH") + "/api/hosts/host_set.go",
"HostSet",
"hosts",
"",
"",
"",
templateTypeResource,
},
{
os.Getenv("APIGEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
"HostCatalog",
os.Getenv("APIGEN_BASEPATH") + "/api/hosts/host_catalog.go",
"HostCatalog",
"hosts",
"",
"",
"",
templateTypeResource,
},
{
os.Getenv("APIGEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
"StaticHostCatalogDetails",
os.Getenv("APIGEN_BASEPATH") + "/api/hosts/static_host_catalog.go",
"StaticHostCatalogDetails",
"hosts",
"",
"HostCatalog",
"StaticHostCatalog",
templateTypeDetail,
},
{
os.Getenv("APIGEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
"AwsEc2HostCatalogDetails",
os.Getenv("APIGEN_BASEPATH") + "/api/hosts/awsec2_host_catalog.go",
"AwsEc2HostCatalogDetails",
"hosts",
"",
"HostCatalog",
"AwsEc2HostCatalog",
templateTypeDetail,
},
}
)
type visitFn func(node ast.Node)
func (fn visitFn) Visit(node ast.Node) ast.Visitor {
fn(node)
return fn
}
func main() {
createStructs()
createUtilFuncs()
}
func createStructs() {
for _, inputStruct := range inputStructs {
inFile, err := filepath.Abs(inputStruct.inFile)
if err != nil {
fmt.Printf("error opening file %q: %v\n", inputStruct.inFile, err)
os.Exit(1)
}
fset := token.NewFileSet()
inAst, err := parser.ParseFile(fset, inFile, nil, parser.ParseComments)
if err != nil {
fmt.Printf("error parsing %s: %v\n", inFile, err)
os.Exit(1)
}
ast.Walk(visitFn(func(n ast.Node) {
spec, ok := n.(*ast.TypeSpec)
if !ok {
return
}
if spec.Name == nil {
return
}
if spec.Name.Name != inputStruct.inName {
return
}
spec.Name.Name = inputStruct.outName
st, ok := spec.Type.(*ast.StructType)
if !ok {
fmt.Printf("expected struct type for identifier, got %t\n", spec.Type)
os.Exit(1)
return
}
if st.Fields.List == nil {
fmt.Printf("no fields found in %q\n", inputStruct.inName)
os.Exit(1)
return
}
// Tee up unexported field deletion
var elideList []int
{
defer func() {
var cutCount int
// Remove unexported proto stuff
for _, val := range elideList {
loc := val - cutCount
st.Fields.List = append(st.Fields.List[:loc], st.Fields.List[loc+1:]...)
cutCount++
}
// Add default fields if a base resource
if inputStruct.templateType == templateTypeResource {
st.Fields.List = append([]*ast.Field{{
Names: []*ast.Ident{
{
Name: "defaultFields",
Obj: &ast.Object{
Kind: ast.Var,
Name: "defaultFields",
},
},
},
Type: &ast.ArrayType{
Elt: &ast.Ident{
Name: "string",
},
},
}}, st.Fields.List...)
}
}()
}
for i, field := range st.Fields.List {
if !field.Names[0].IsExported() {
elideList = append(elideList, i)
continue
}
// Anything that isn't a basic type we expect to be a star
// expression with a selector; that is, a wrapper value, timestamp
// value, etc.
//
// TODO: this isn't necessarily a good assumption, which means we
// might get failures with other types. This is an internal tools
// only; we can revisit as needed!
var selectorExpr *ast.SelectorExpr
switch typ := field.Type.(type) {
case *ast.Ident:
typ.Name = "*" + typ.Name
goto TAGMODIFY
case *ast.ArrayType:
goto TAGMODIFY
case *ast.StarExpr:
switch nextTyp := typ.X.(type) {
case *ast.Ident:
// Already a pointer, don't do anything
goto TAGMODIFY
case *ast.SelectorExpr:
selectorExpr = nextTyp
}
case *ast.SelectorExpr:
selectorExpr = typ
}
switch {
case selectorExpr != nil:
xident, ok := selectorExpr.X.(*ast.Ident)
if !ok {
fmt.Printf("unexpected non-ident type in selector\n")
os.Exit(1)
}
switch xident.Name {
case "wrappers":
switch selectorExpr.Sel.Name {
case "StringValue":
st.Fields.List[i] = &ast.Field{
Names: field.Names,
Type: &ast.Ident{
Name: "*string",
},
Tag: field.Tag,
}
case "BoolValue":
st.Fields.List[i] = &ast.Field{
Names: field.Names,
Type: &ast.Ident{
Name: "*bool",
},
Tag: field.Tag,
}
case "Int64Value":
st.Fields.List[i] = &ast.Field{
Names: field.Names,
Type: &ast.Ident{
Name: "*int64",
},
Tag: field.Tag,
}
default:
fmt.Printf("unhandled wrappers selector sel name %q\n", selectorExpr.Sel.Name)
os.Exit(1)
}
case "timestamp":
switch selectorExpr.Sel.Name {
case "Timestamp":
st.Fields.List[i] = &ast.Field{
Names: field.Names,
Type: &ast.Ident{
Name: "time.Time",
},
Tag: field.Tag,
}
default:
fmt.Printf("unhandled timestamp selector sel name %q\n", selectorExpr.Sel.Name)
os.Exit(1)
}
case "_struct":
switch selectorExpr.Sel.Name {
case "Struct":
st.Fields.List[i] = &ast.Field{
Names: field.Names,
Type: &ast.MapType{
Key: &ast.Ident{
Name: "string",
},
Value: &ast.InterfaceType{
Methods: &ast.FieldList{},
},
},
Tag: field.Tag,
}
default:
fmt.Printf("unhandled timestamp selector sel name %q\n", selectorExpr.Sel.Name)
os.Exit(1)
}
default:
fmt.Printf("unhandled xident name %q\n", xident.Name)
os.Exit(1)
}
default:
fmt.Println("unhandled non-ident, non-selector case")
os.Exit(1)
}
TAGMODIFY:
st.Fields.List[i].Tag.Value = "`" + regex.FindString(st.Fields.List[i].Tag.Value) + "`"
}
}), inAst)
buf := new(bytes.Buffer)
if err := format.Node(buf, fset, inAst); err != nil {
fmt.Printf("error formatting new code: %v\n", err)
os.Exit(1)
}
// We have to manually cut out the lines we don't want because comments
// won't be preserved otherwise. See the note about lossy comments in
// https://arslan.io/2017/09/14/the-ultimate-guide-to-writing-a-go-tool/
scanner := bufio.NewScanner(bytes.NewBufferString(buf.String()))
var inType bool
var outBuf []string
for scanner.Scan() {
if !inType {
if strings.HasPrefix(scanner.Text(), "type "+inputStruct.outName+" struct") {
inType = true
// Don't add this line, we'll do it in the template
continue
}
} else {
if scanner.Text() == "}" {
// We've reached the end of the type
break
}
}
if inType {
outBuf = append(outBuf, scanner.Text())
}
}
inputStruct.structFields = strings.Join(outBuf, "\n")
}
}
func createUtilFuncs() {
for _, inputStruct := range inputStructs {
outBuf := new(bytes.Buffer)
switch inputStruct.templateType {
case templateTypeResource:
utilFuncsTemplate.Execute(outBuf, struct {
Timestamp time.Time
Name string
Package string
StructFields string
}{
Timestamp: time.Now(),
Name: inputStruct.outName,
Package: inputStruct.outPkg,
StructFields: inputStruct.structFields,
})
case templateTypeDetail:
detailTemplate.Execute(outBuf, struct {
Timestamp time.Time
Package string
StructFields string
ParentName string
DetailName string
}{
Timestamp: time.Now(),
Package: inputStruct.outPkg,
StructFields: inputStruct.structFields,
ParentName: inputStruct.parentName,
DetailName: inputStruct.detailName,
})
}
outFile, err := filepath.Abs(inputStruct.outFile)
if err != nil {
fmt.Printf("error opening file %q: %v\n", inputStruct.outFile, err)
os.Exit(1)
}
if err := ioutil.WriteFile(outFile, outBuf.Bytes(), 0644); err != nil {
fmt.Printf("error writing file %q: %v\n", outFile, err)
os.Exit(1)
}
}
}
var utilFuncsTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// {{ .Timestamp }}
package {{ .Package }}
import (
"encoding/json"
"github.com/fatih/structs"
"github.com/hashicorp/watchtower/api/internal/strutil"
)
type {{ .Name }} struct {
{{ .StructFields }}
}
func (s *{{ .Name }}) SetDefault(key string) {
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
}
func (s *{{ .Name }}) UnsetDefault(key string) {
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
}
func (s {{ .Name }}) MarshalJSON() ([]byte, error) {
m := structs.Map(s)
if m == nil {
m = make(map[string]interface{})
}
for _, k := range s.defaultFields {
m[k] = nil
}
return json.Marshal(m)
}
`))
// TODO: Figure out the right way to write out the specific fields
var detailTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// {{ .Timestamp }}
package {{ .Package }}
import (
"fmt"
"github.com/mitchellh/mapstructure"
)
type {{ .DetailName }} struct {
*{{ .ParentName }}
{{ .StructFields }}
}
func (s {{ .ParentName }}) As{{ .DetailName }}() (*{{ .DetailName }}, error) {
out := &{{ .DetailName }}{
{{ .ParentName }}: &s,
}
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: out,
TagName: "json",
})
if err != nil {
return nil, fmt.Errorf("error creating map decoder: %w", err)
}
if err := decoder.Decode(s.Attributes); err != nil {
return nil, fmt.Errorf("error decoding attributes map: %w", err)
}
return out, nil
}
`))

@ -0,0 +1,7 @@
package main
// +build genapi
//go:generate go run genapi.go
//go:generate goimports -w ../../hosts
//go:generate goimports -w ../..

@ -0,0 +1,34 @@
package tests
import (
"testing"
"time"
"github.com/hashicorp/watchtower/api"
"github.com/hashicorp/watchtower/api/hosts"
"github.com/stretchr/testify/assert"
)
func TestDetailTemplating(t *testing.T) {
lt := time.Now()
c := hosts.HostCatalog{
Path: api.String("path"),
CreatedTime: lt,
Attributes: map[string]interface{}{
"regions": []string{"a", "b"},
"access_key": "access",
"secret_key": "secret",
"rotate": true,
},
}
ac, err := c.AsAwsEc2HostCatalog()
assert.NoError(t, err)
assert.Equal(t, &hosts.AwsEc2HostCatalog{
HostCatalog: &c,
Regions: []string{"a", "b"},
AccessKey: api.String("access"),
SecretKey: api.String("secret"),
Rotate: api.Bool(true),
}, ac)
}

@ -0,0 +1,19 @@
package api
func Bool(in bool) *bool {
ret := new(bool)
*ret = in
return ret
}
func String(in string) *string {
ret := new(string)
*ret = in
return ret
}
func Int(in int64) *int64 {
ret := new(int64)
*ret = in
return ret
}

@ -6,6 +6,7 @@ require (
github.com/armon/go-metrics v0.3.3
github.com/bufbuild/buf v0.11.0
github.com/fatih/color v1.9.0
github.com/fatih/structs v1.1.0
github.com/favadi/protoc-go-inject-tag v1.0.0
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
github.com/go-openapi/runtime v0.19.15 // indirect

@ -8,6 +8,7 @@ package api
import (
proto "github.com/golang/protobuf/proto"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@ -30,9 +31,9 @@ type ErrorDetails struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
TraceId string `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"`
RequestId string `protobuf:"bytes,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
RequestFields []string `protobuf:"bytes,3,rep,name=request_fields,json=requestFields,proto3" json:"request_fields,omitempty"`
TraceId *wrappers.StringValue `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"`
RequestId *wrappers.StringValue `protobuf:"bytes,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
RequestFields []string `protobuf:"bytes,3,rep,name=request_fields,json=requestFields,proto3" json:"request_fields,omitempty"`
}
func (x *ErrorDetails) Reset() {
@ -67,18 +68,18 @@ func (*ErrorDetails) Descriptor() ([]byte, []int) {
return file_controller_api_v1_error_proto_rawDescGZIP(), []int{0}
}
func (x *ErrorDetails) GetTraceId() string {
func (x *ErrorDetails) GetTraceId() *wrappers.StringValue {
if x != nil {
return x.TraceId
}
return ""
return nil
}
func (x *ErrorDetails) GetRequestId() string {
func (x *ErrorDetails) GetRequestId() *wrappers.StringValue {
if x != nil {
return x.RequestId
}
return ""
return nil
}
func (x *ErrorDetails) GetRequestFields() []string {
@ -94,13 +95,14 @@ type Error struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The HTTP Status code applicable to this error.
Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
// An application-specific error string.
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
// A human readable explanation specific to this occurrence of the error.
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
// Additional metadata regarding the error. Depending on the error different fields will be populated.
// The HTTP Status code applicable to this error
Status *wrappers.Int64Value `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
// An application-specific error string
Code *wrappers.StringValue `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
// A human readable explanation specific to this occurrence of the error
Message *wrappers.StringValue `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
// Additional metadata regarding the error. Depending on the error
// different fields will be populated.
Details *ErrorDetails `protobuf:"bytes,4,opt,name=details,proto3" json:"details,omitempty"`
}
@ -136,25 +138,25 @@ func (*Error) Descriptor() ([]byte, []int) {
return file_controller_api_v1_error_proto_rawDescGZIP(), []int{1}
}
func (x *Error) GetStatus() int32 {
func (x *Error) GetStatus() *wrappers.Int64Value {
if x != nil {
return x.Status
}
return 0
return nil
}
func (x *Error) GetCode() string {
func (x *Error) GetCode() *wrappers.StringValue {
if x != nil {
return x.Code
}
return ""
return nil
}
func (x *Error) GetMessage() string {
func (x *Error) GetMessage() *wrappers.StringValue {
if x != nil {
return x.Message
}
return ""
return nil
}
func (x *Error) GetDetails() *ErrorDetails {
@ -170,27 +172,38 @@ var file_controller_api_v1_error_proto_rawDesc = []byte{
0x0a, 0x1d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x76, 0x31, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x11, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x22, 0x6f, 0x0a, 0x0c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69,
0x6c, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a,
0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e,
0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03,
0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x69, 0x65,
0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x16, 0x0a,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65,
0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x41,
0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65,
0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70,
0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x76, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0xab, 0x01, 0x0a, 0x0c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x0a,
0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09,
0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x09, 0x52, 0x0d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73,
0x22, 0xe1, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74,
0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74,
0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64,
0x65, 0x12, 0x36, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x74,
0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45,
0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x07, 0x64, 0x65, 0x74,
0x61, 0x69, 0x6c, 0x73, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74,
0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f,
0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -207,16 +220,23 @@ func file_controller_api_v1_error_proto_rawDescGZIP() []byte {
var file_controller_api_v1_error_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_controller_api_v1_error_proto_goTypes = []interface{}{
(*ErrorDetails)(nil), // 0: controller.api.v1.ErrorDetails
(*Error)(nil), // 1: controller.api.v1.Error
(*ErrorDetails)(nil), // 0: controller.api.v1.ErrorDetails
(*Error)(nil), // 1: controller.api.v1.Error
(*wrappers.StringValue)(nil), // 2: google.protobuf.StringValue
(*wrappers.Int64Value)(nil), // 3: google.protobuf.Int64Value
}
var file_controller_api_v1_error_proto_depIdxs = []int32{
0, // 0: controller.api.v1.Error.details:type_name -> controller.api.v1.ErrorDetails
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
2, // 0: controller.api.v1.ErrorDetails.trace_id:type_name -> google.protobuf.StringValue
2, // 1: controller.api.v1.ErrorDetails.request_id:type_name -> google.protobuf.StringValue
3, // 2: controller.api.v1.Error.status:type_name -> google.protobuf.Int64Value
2, // 3: controller.api.v1.Error.code:type_name -> google.protobuf.StringValue
2, // 4: controller.api.v1.Error.message:type_name -> google.protobuf.StringValue
0, // 5: controller.api.v1.Error.details:type_name -> controller.api.v1.ErrorDetails
6, // [6:6] is the sub-list for method output_type
6, // [6:6] is the sub-list for method input_type
6, // [6:6] is the sub-list for extension type_name
6, // [6:6] is the sub-list for extension extendee
0, // [0:6] is the sub-list for field type_name
}
func init() { file_controller_api_v1_error_proto_init() }

@ -665,8 +665,9 @@ type AddToHostSetRequest struct {
ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"`
HostCatalogId string `protobuf:"bytes,3,opt,name=host_catalog_id,json=hostCatalogId,proto3" json:"host_catalog_id,omitempty"`
Id string `protobuf:"bytes,4,opt,name=id,proto3" json:"id,omitempty"`
// A list of host IDss which will be added to this host set. Each host referenced here must be a child of the
// same host catalog that this host set is a child of.
// A list of host IDs which will be added to this host set. Each host
// referenced here must be a child of the same host catalog that this host
// set is a child of.
HostIds []string `protobuf:"bytes,5,rep,name=host_ids,json=hostIds,proto3" json:"host_ids,omitempty"`
}
@ -785,7 +786,8 @@ type RemoveFromHostSetRequest struct {
HostCatalogId string `protobuf:"bytes,3,opt,name=host_catalog_id,json=hostCatalogId,proto3" json:"host_catalog_id,omitempty"`
// This host set's id.
Id string `protobuf:"bytes,4,opt,name=id,proto3" json:"id,omitempty"`
// A list of host IDs which should not be in the host set when this request returns.
// A list of host IDs which should not be in the host set when this request
// returns.
HostIds []string `protobuf:"bytes,5,rep,name=host_ids,json=hostIds,proto3" json:"host_ids,omitempty"`
}

@ -155,8 +155,9 @@ message AddToHostSetRequest {
string host_catalog_id = 3;
string id = 4;
// A list of host IDs which will be added to this host set. Each host referenced here must be a child of the
// same host catalog that this host set is a child of.
// A list of host IDs which will be added to this host set. Each host
// referenced here must be a child of the same host catalog that this host
// set is a child of.
repeated string host_ids = 5;
}
@ -170,7 +171,8 @@ message RemoveFromHostSetRequest {
// This host set's id.
string id = 4;
// A list of host IDs which should not be in the host set when this request returns.
// A list of host IDs which should not be in the host set when this request
// returns.
repeated string host_ids = 5;
}

@ -4,20 +4,23 @@ package controller.api.v1;
option go_package = "github.com/hashicorp/watchtower/internal/gen/controller/api;api";
import "google/protobuf/wrappers.proto";
message ErrorDetails {
string trace_id = 1;
string request_id = 2;
repeated string request_fields = 3;
google.protobuf.StringValue trace_id = 1;
google.protobuf.StringValue request_id = 2;
repeated string request_fields = 3;
}
// Error is returned by the JSON API when an error occurs.
message Error {
// The HTTP Status code applicable to this error.
int32 status = 1;
// An application-specific error string.
string code = 2;
// A human readable explanation specific to this occurrence of the error.
string message = 3;
// Additional metadata regarding the error. Depending on the error different fields will be populated.
ErrorDetails details = 4;
// The HTTP Status code applicable to this error
google.protobuf.Int64Value status = 1;
// An application-specific error string
google.protobuf.StringValue code = 2;
// A human readable explanation specific to this occurrence of the error
google.protobuf.StringValue message = 3;
// Additional metadata regarding the error. Depending on the error
// different fields will be populated.
ErrorDetails details = 4;
}

Loading…
Cancel
Save