Add initial API generation bits (#20)
* Add initial API generation bits * Revert accidental changes to oplog
This commit is contained in:
1 parent
7f03246c6f
commit
2926cc1000
16 files changed
+965
-66
No files matched your search
@@ -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)
|
||||
}
|
||||
+19
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user