mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
Schema Generator script (#215)
* Initial commit for schema generator script * vendor discovery api * respond to comments * Don't fail on formatting errors * respond to comments * update tests with latest changes
This commit is contained in:
parent
6199652159
commit
7faec27fba
311
scripts/schemagen.go
Normal file
311
scripts/schemagen.go
Normal file
@ -0,0 +1,311 @@
|
||||
// Generates an initial version of a schema for a new resource type.
|
||||
//
|
||||
// This script draws heavily from https://github.com/radeksimko/terraform-gen,
|
||||
// but uses GCP's discovery API instead of the struct definition to generate
|
||||
// the schemas.
|
||||
//
|
||||
// This is not meant to be a definitive source of truth for resource schemas,
|
||||
// just a starting point. It has some notable deficiencies, such as:
|
||||
// * No way to differentiate between fields that are/are not updateable.
|
||||
// * Required/Optional/Computed are set based on keywords in the description.
|
||||
//
|
||||
// Usage requires credentials. Obtain via gcloud:
|
||||
//
|
||||
// gcloud auth application-default login
|
||||
//
|
||||
// Usage example (from root dir):
|
||||
//
|
||||
// go run ./scripts/schemagen.go -api pubsub -resource Subscription -version v1
|
||||
//
|
||||
// This will output a file in the directory from which the script is run named `gen_resource_[api]_[resource].go`.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/google"
|
||||
"google.golang.org/api/discovery/v1"
|
||||
)
|
||||
|
||||
func main() {
|
||||
api := flag.String("api", "", "api to query")
|
||||
resource := flag.String("resource", "", "resource to generate")
|
||||
version := flag.String("version", "v1", "api version to query")
|
||||
flag.Parse()
|
||||
|
||||
if *api == "" || *resource == "" {
|
||||
flag.PrintDefaults()
|
||||
log.Fatal("usage: go run schemagen.go -api $API -resource $RESOURCE -version $VERSION")
|
||||
}
|
||||
|
||||
// Discovery API doesn't need authentication
|
||||
client, err := google.DefaultClient(oauth2.NoContext, []string{}...)
|
||||
if err != nil {
|
||||
log.Fatal(fmt.Errorf("Error creating client: %v", err))
|
||||
}
|
||||
|
||||
discoveryService, err := discovery.New(client)
|
||||
if err != nil {
|
||||
log.Fatal(fmt.Errorf("Error creating service: %v", err))
|
||||
}
|
||||
|
||||
resp, err := discoveryService.Apis.GetRest(*api, *version).Fields("schemas").Do()
|
||||
if err != nil {
|
||||
log.Fatal(fmt.Errorf("Error reading API: %v", err))
|
||||
}
|
||||
|
||||
fileName := fmt.Sprintf("gen_resource_%s_%s.go", *api, underscore(*resource))
|
||||
f, err := os.Create(fileName)
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
required, optional, computed := generateFields(resp.Schemas, *resource)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = googleTemplate.Execute(buf, struct {
|
||||
TypeName string
|
||||
ReqFields map[string]string
|
||||
OptFields map[string]string
|
||||
ComFields map[string]string
|
||||
}{
|
||||
// Capitalize the first letter of the api name, then concatenate the resource name onto it.
|
||||
// e.g. compute, instance -> ComputeInstance
|
||||
TypeName: strings.ToUpper((*api)[0:1]) + (*api)[1:] + *resource,
|
||||
ReqFields: required,
|
||||
OptFields: optional,
|
||||
ComFields: computed,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmtd, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
log.Printf("Formatting error: %s", err)
|
||||
}
|
||||
|
||||
if _, err := f.Write(fmtd); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func generateFields(jsonSchemas map[string]discovery.JsonSchema, property string) (required, optional, computed map[string]string) {
|
||||
required = make(map[string]string, 0)
|
||||
optional = make(map[string]string, 0)
|
||||
computed = make(map[string]string, 0)
|
||||
|
||||
for k, v := range jsonSchemas[property].Properties {
|
||||
content, err := generateField(jsonSchemas, k, v, false)
|
||||
if err != nil {
|
||||
log.Printf("ERROR: %s", err)
|
||||
} else {
|
||||
if strings.Contains(content, "Required:") {
|
||||
required[underscore(k)] = content
|
||||
} else if strings.Contains(content, "Optional:") {
|
||||
optional[underscore(k)] = content
|
||||
} else if strings.Contains(content, "Computed:") {
|
||||
computed[underscore(k)] = content
|
||||
} else {
|
||||
log.Println("ERROR: Found property that is neither required, optional, nor computed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func generateField(jsonSchemas map[string]discovery.JsonSchema, field string, v discovery.JsonSchema, isNested bool) (string, error) {
|
||||
s := &schema.Schema{
|
||||
Description: v.Description,
|
||||
}
|
||||
if field != "" {
|
||||
setProperties(v, s)
|
||||
}
|
||||
|
||||
// JSON field types: https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1
|
||||
switch v.Type {
|
||||
case "integer":
|
||||
s.Type = schema.TypeInt
|
||||
case "number":
|
||||
s.Type = schema.TypeFloat
|
||||
case "string":
|
||||
s.Type = schema.TypeString
|
||||
case "boolean":
|
||||
s.Type = schema.TypeBool
|
||||
case "array":
|
||||
s.Type = schema.TypeList
|
||||
elem, err := generateField(jsonSchemas, "", *v.Items, true)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unable to generate Elem for %q: %s", field, err)
|
||||
}
|
||||
s.Elem = elem
|
||||
case "object":
|
||||
s.Type = schema.TypeMap
|
||||
case "":
|
||||
s.Type = schema.TypeList
|
||||
s.MaxItems = 1
|
||||
|
||||
elem := "&schema.Resource{\nSchema: map[string]*schema.Schema{\n"
|
||||
required, optional, computed := generateFields(jsonSchemas, v.Ref)
|
||||
elem += generateNestedElem(required)
|
||||
elem += generateNestedElem(optional)
|
||||
elem += generateNestedElem(computed)
|
||||
elem += "},\n}"
|
||||
|
||||
if isNested {
|
||||
return elem, nil
|
||||
}
|
||||
s.Elem = elem
|
||||
default:
|
||||
return "", fmt.Errorf("Unable to process: %s %s", field, v.Type)
|
||||
}
|
||||
|
||||
return schemaCode(s, isNested)
|
||||
}
|
||||
|
||||
func setProperties(v discovery.JsonSchema, s *schema.Schema) {
|
||||
if v.ReadOnly || strings.HasPrefix(v.Description, "Output-only") || strings.HasPrefix(v.Description, "[Output Only]") {
|
||||
s.Computed = true
|
||||
} else {
|
||||
if v.Required || strings.HasPrefix(v.Description, "Required") {
|
||||
s.Required = true
|
||||
} else {
|
||||
s.Optional = true
|
||||
}
|
||||
}
|
||||
|
||||
s.ForceNew = true
|
||||
}
|
||||
|
||||
func generateNestedElem(fields map[string]string) (elem string) {
|
||||
fieldNames := []string{}
|
||||
for k, _ := range fields {
|
||||
fieldNames = append(fieldNames, k)
|
||||
}
|
||||
sort.Strings(fieldNames)
|
||||
for _, k := range fieldNames {
|
||||
elem += fmt.Sprintf("%q: %s,\n", k, fields[k])
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func schemaCode(s *schema.Schema, isNested bool) (string, error) {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
err := schemaTemplate.Execute(buf, struct {
|
||||
Schema *schema.Schema
|
||||
IsNested bool
|
||||
}{
|
||||
Schema: s,
|
||||
IsNested: isNested,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// go version of https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case,
|
||||
// with some extra logic around ending in 's' to handle the "externalIPs" case.
|
||||
func underscore(name string) string {
|
||||
endsInS := strings.HasSuffix(name, "s")
|
||||
if endsInS {
|
||||
name = strings.TrimSuffix(name, "s")
|
||||
}
|
||||
firstCap := regexp.MustCompile("(.)([A-Z][a-z]+)").ReplaceAllString(name, "${1}_${2}")
|
||||
allCap := regexp.MustCompile("([a-z0-9])([A-Z])").ReplaceAllString(firstCap, "${1}_${2}")
|
||||
if endsInS {
|
||||
allCap = allCap + "s"
|
||||
}
|
||||
return strings.ToLower(allCap)
|
||||
}
|
||||
|
||||
var schemaTemplate = template.Must(template.New("schema").Parse(`{{if .IsNested}}&schema.Schema{{end}}{{"{"}}{{if not .IsNested}}
|
||||
{{end}}Type: schema.{{.Schema.Type}},{{if ne .Schema.Description ""}}
|
||||
Description: {{printf "%q" .Schema.Description}},{{end}}{{if .Schema.Required}}
|
||||
Required: {{.Schema.Required}},{{end}}{{if .Schema.Optional}}
|
||||
Optional: {{.Schema.Optional}},{{end}}{{if .Schema.ForceNew}}
|
||||
ForceNew: {{.Schema.ForceNew}},{{end}}{{if .Schema.Computed}}
|
||||
Computed: {{.Schema.Computed}},{{end}}{{if gt .Schema.MaxItems 0}}
|
||||
MaxItems: {{.Schema.MaxItems}},{{end}}{{if .Schema.Elem}}
|
||||
Elem: {{.Schema.Elem}},{{end}}{{if not .IsNested}}
|
||||
{{end}}{{"}"}}`))
|
||||
|
||||
var googleTemplate = template.Must(template.New("google").Parse(`package google
|
||||
|
||||
import(
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resource{{.TypeName}}() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resource{{.TypeName}}Create,
|
||||
Read: resource{{.TypeName}}Read,
|
||||
Update: resource{{.TypeName}}Update,
|
||||
Delete: resource{{.TypeName}}Delete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{ {{range $name, $schema := .ReqFields}}
|
||||
"{{ $name }}": {{ $schema }},
|
||||
{{end}}{{range $name, $schema := .OptFields}}
|
||||
"{{ $name }}": {{ $schema }},
|
||||
{{end}}{{range $name, $schema := .ComFields}}
|
||||
"{{ $name }}": {{ $schema }},
|
||||
{{end}}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resource{{.TypeName}}Create(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func resource{{.TypeName}}Read(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func resource{{.TypeName}}Update(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func resource{{.TypeName}}Delete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
`))
|
201
scripts/schemagen_test.go
Normal file
201
scripts/schemagen_test.go
Normal file
@ -0,0 +1,201 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"google.golang.org/api/discovery/v1"
|
||||
)
|
||||
|
||||
func TestGenerateFields_primitive(t *testing.T) {
|
||||
schema := map[string]discovery.JsonSchema{
|
||||
"Resource": {
|
||||
Type: "object",
|
||||
Properties: map[string]discovery.JsonSchema{
|
||||
"stringField": {
|
||||
Type: "string",
|
||||
Description: "string field",
|
||||
},
|
||||
"numberField": {
|
||||
Type: "number",
|
||||
Description: "Required. number field",
|
||||
},
|
||||
"intField": {
|
||||
Type: "integer",
|
||||
Description: "integer field",
|
||||
},
|
||||
"boolField": {
|
||||
Type: "boolean",
|
||||
Description: "Output-only. boolean field",
|
||||
},
|
||||
"mapField": {
|
||||
Type: "object",
|
||||
Description: "object field",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
reqFields, optFields, comFields := generateFields(schema, "Resource")
|
||||
|
||||
expectedReq := map[string]string{
|
||||
"number_field": "{\nType: schema.TypeFloat,\nDescription: \"Required. number field\",\nRequired: true,\nForceNew: true,\n}",
|
||||
}
|
||||
|
||||
expectedOpt := map[string]string{
|
||||
"string_field": "{\nType: schema.TypeString,\nDescription: \"string field\",\nOptional: true,\nForceNew: true,\n}",
|
||||
"int_field": "{\nType: schema.TypeInt,\nDescription: \"integer field\",\nOptional: true,\nForceNew: true,\n}",
|
||||
"map_field": "{\nType: schema.TypeMap,\nDescription: \"object field\",\nOptional: true,\nForceNew: true,\n}",
|
||||
}
|
||||
|
||||
expectedCom := map[string]string{
|
||||
"bool_field": "{\nType: schema.TypeBool,\nDescription: \"Output-only. boolean field\",\nForceNew: true,\nComputed: true,\n}",
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(reqFields, expectedReq) {
|
||||
t.Fatalf("Expected: %+v\n\nGiven: %+v\n", expectedReq, reqFields)
|
||||
}
|
||||
if !reflect.DeepEqual(optFields, expectedOpt) {
|
||||
t.Fatalf("Expected: %+v\n\nGiven: %+v\n", expectedOpt, optFields)
|
||||
}
|
||||
if !reflect.DeepEqual(comFields, expectedCom) {
|
||||
t.Fatalf("Expected: %+v\n\nGiven: %+v\n", expectedCom, comFields)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateFields_listOfPrimitives(t *testing.T) {
|
||||
schema := map[string]discovery.JsonSchema{
|
||||
"Resource": {
|
||||
Type: "object",
|
||||
Properties: map[string]discovery.JsonSchema{
|
||||
"stringsField": {
|
||||
Type: "array",
|
||||
Items: &discovery.JsonSchema{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
"numbersField": {
|
||||
Type: "array",
|
||||
Items: &discovery.JsonSchema{
|
||||
Type: "number",
|
||||
},
|
||||
},
|
||||
"intsField": {
|
||||
Type: "array",
|
||||
Items: &discovery.JsonSchema{
|
||||
Type: "integer",
|
||||
},
|
||||
},
|
||||
"boolsField": {
|
||||
Type: "array",
|
||||
Items: &discovery.JsonSchema{
|
||||
Type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, optFields, _ := generateFields(schema, "Resource")
|
||||
|
||||
expected := map[string]string{
|
||||
"strings_field": "{\nType: schema.TypeList,\nOptional: true,\nForceNew: true,\nElem: &schema.Schema{Type: schema.TypeString,},\n}",
|
||||
"numbers_field": "{\nType: schema.TypeList,\nOptional: true,\nForceNew: true,\nElem: &schema.Schema{Type: schema.TypeFloat,},\n}",
|
||||
"ints_field": "{\nType: schema.TypeList,\nOptional: true,\nForceNew: true,\nElem: &schema.Schema{Type: schema.TypeInt,},\n}",
|
||||
"bools_field": "{\nType: schema.TypeList,\nOptional: true,\nForceNew: true,\nElem: &schema.Schema{Type: schema.TypeBool,},\n}",
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(optFields, expected) {
|
||||
t.Fatalf("Expected: %+v\n\nGiven: %+v\n", expected, optFields)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateFields_nested(t *testing.T) {
|
||||
schema := map[string]discovery.JsonSchema{
|
||||
"Resource": {
|
||||
Type: "object",
|
||||
Properties: map[string]discovery.JsonSchema{
|
||||
"nestedField": {
|
||||
Ref: "OtherThing",
|
||||
},
|
||||
},
|
||||
},
|
||||
"OtherThing": {
|
||||
Type: "object",
|
||||
Properties: map[string]discovery.JsonSchema{
|
||||
"intField": {
|
||||
Type: "integer",
|
||||
},
|
||||
"stringField": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, optFields, _ := generateFields(schema, "Resource")
|
||||
|
||||
expected := map[string]string{
|
||||
"nested_field": "{\nType: schema.TypeList,\nOptional: true,\nForceNew: true,\nMaxItems: 1,\nElem: &schema.Resource{\nSchema: map[string]*schema.Schema{\n\"int_field\": {\nType: schema.TypeInt,\nOptional: true,\nForceNew: true,\n},\n\"string_field\": {\nType: schema.TypeString,\nOptional: true,\nForceNew: true,\n},\n},\n},\n}",
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(optFields, expected) {
|
||||
t.Fatalf("Expected: %+v\n\nGiven: %+v\n", expected, optFields)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateFields_nestedList(t *testing.T) {
|
||||
schema := map[string]discovery.JsonSchema{
|
||||
"Resource": {
|
||||
Type: "object",
|
||||
Properties: map[string]discovery.JsonSchema{
|
||||
"nestedField": {
|
||||
Type: "array",
|
||||
Items: &discovery.JsonSchema{
|
||||
Ref: "OtherThing",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"OtherThing": {
|
||||
Type: "object",
|
||||
Properties: map[string]discovery.JsonSchema{
|
||||
"intField": {
|
||||
Type: "integer",
|
||||
},
|
||||
"stringField": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, optFields, _ := generateFields(schema, "Resource")
|
||||
|
||||
expected := map[string]string{
|
||||
"nested_field": "{\nType: schema.TypeList,\nOptional: true,\nForceNew: true,\nElem: &schema.Resource{\nSchema: map[string]*schema.Schema{\n\"int_field\": {\nType: schema.TypeInt,\nOptional: true,\nForceNew: true,\n},\n\"string_field\": {\nType: schema.TypeString,\nOptional: true,\nForceNew: true,\n},\n},\n},\n}",
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(optFields, expected) {
|
||||
t.Fatalf("Expected: %+v\n\nGiven: %+v\n", expected, optFields)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnderscore(t *testing.T) {
|
||||
testCases := map[string]string{
|
||||
"camelCase": "camel_case",
|
||||
"CamelCase": "camel_case",
|
||||
"HTTPResponseCode": "http_response_code",
|
||||
"HTTPResponseCodeXYZ": "http_response_code_xyz",
|
||||
"getHTTPResponseCode": "get_http_response_code",
|
||||
"ISCSI": "iscsi",
|
||||
"externalIPs": "external_ips",
|
||||
}
|
||||
|
||||
for from, to := range testCases {
|
||||
converted := underscore(from)
|
||||
if converted != to {
|
||||
t.Fatalf("Expected %q after conversion, given: %q", to, converted)
|
||||
}
|
||||
}
|
||||
}
|
685
vendor/google.golang.org/api/discovery/v1/discovery-api.json
generated
vendored
Normal file
685
vendor/google.golang.org/api/discovery/v1/discovery-api.json
generated
vendored
Normal file
@ -0,0 +1,685 @@
|
||||
{
|
||||
"kind": "discovery#restDescription",
|
||||
"etag": "\"YWOzh2SDasdU84ArJnpYek-OMdg/Pyg0A4J33Dq212hoe9BYpSm0dl4\"",
|
||||
"discoveryVersion": "v1",
|
||||
"id": "discovery:v1",
|
||||
"name": "discovery",
|
||||
"version": "v1",
|
||||
"title": "APIs Discovery Service",
|
||||
"description": "Provides information about other Google APIs, such as what APIs are available, the resource, and method details for each API.",
|
||||
"ownerDomain": "google.com",
|
||||
"ownerName": "Google",
|
||||
"icons": {
|
||||
"x16": "http://www.google.com/images/icons/feature/filing_cabinet_search-g16.png",
|
||||
"x32": "http://www.google.com/images/icons/feature/filing_cabinet_search-g32.png"
|
||||
},
|
||||
"documentationLink": "https://developers.google.com/discovery/",
|
||||
"protocol": "rest",
|
||||
"baseUrl": "https://www.googleapis.com/discovery/v1/",
|
||||
"basePath": "/discovery/v1/",
|
||||
"rootUrl": "https://www.googleapis.com/",
|
||||
"servicePath": "discovery/v1/",
|
||||
"batchPath": "batch",
|
||||
"parameters": {
|
||||
"alt": {
|
||||
"type": "string",
|
||||
"description": "Data format for the response.",
|
||||
"default": "json",
|
||||
"enum": [
|
||||
"json"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"Responses with Content-Type of application/json"
|
||||
],
|
||||
"location": "query"
|
||||
},
|
||||
"fields": {
|
||||
"type": "string",
|
||||
"description": "Selector specifying which fields to include in a partial response.",
|
||||
"location": "query"
|
||||
},
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.",
|
||||
"location": "query"
|
||||
},
|
||||
"oauth_token": {
|
||||
"type": "string",
|
||||
"description": "OAuth 2.0 token for the current user.",
|
||||
"location": "query"
|
||||
},
|
||||
"prettyPrint": {
|
||||
"type": "boolean",
|
||||
"description": "Returns response with indentations and line breaks.",
|
||||
"default": "true",
|
||||
"location": "query"
|
||||
},
|
||||
"quotaUser": {
|
||||
"type": "string",
|
||||
"description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.",
|
||||
"location": "query"
|
||||
},
|
||||
"userIp": {
|
||||
"type": "string",
|
||||
"description": "IP address of the site where the request originates. Use this if you want to enforce per-user limits.",
|
||||
"location": "query"
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"DirectoryList": {
|
||||
"id": "DirectoryList",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"discoveryVersion": {
|
||||
"type": "string",
|
||||
"description": "Indicate the version of the Discovery API used to generate this doc.",
|
||||
"default": "v1"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"description": "The individual directory entries. One entry per api/version pair.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "The description of this API."
|
||||
},
|
||||
"discoveryLink": {
|
||||
"type": "string",
|
||||
"description": "A link to the discovery document."
|
||||
},
|
||||
"discoveryRestUrl": {
|
||||
"type": "string",
|
||||
"description": "The URL for the discovery REST document."
|
||||
},
|
||||
"documentationLink": {
|
||||
"type": "string",
|
||||
"description": "A link to human readable documentation for the API."
|
||||
},
|
||||
"icons": {
|
||||
"type": "object",
|
||||
"description": "Links to 16x16 and 32x32 icons representing the API.",
|
||||
"properties": {
|
||||
"x16": {
|
||||
"type": "string",
|
||||
"description": "The URL of the 16x16 icon."
|
||||
},
|
||||
"x32": {
|
||||
"type": "string",
|
||||
"description": "The URL of the 32x32 icon."
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "The id of this API."
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "The kind for this response.",
|
||||
"default": "discovery#directoryItem"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"description": "Labels for the status of this API, such as labs or deprecated.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the API."
|
||||
},
|
||||
"preferred": {
|
||||
"type": "boolean",
|
||||
"description": "True if this version is the preferred version to use."
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "The title of this API."
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the API."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "The kind for this response.",
|
||||
"default": "discovery#directoryList"
|
||||
}
|
||||
}
|
||||
},
|
||||
"JsonSchema": {
|
||||
"id": "JsonSchema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"$ref": {
|
||||
"type": "string",
|
||||
"description": "A reference to another schema. The value of this property is the \"id\" of another schema."
|
||||
},
|
||||
"additionalProperties": {
|
||||
"$ref": "JsonSchema",
|
||||
"description": "If this is a schema for an object, this property is the schema for any additional properties with dynamic keys on this object."
|
||||
},
|
||||
"annotations": {
|
||||
"type": "object",
|
||||
"description": "Additional information about this property.",
|
||||
"properties": {
|
||||
"required": {
|
||||
"type": "array",
|
||||
"description": "A list of methods for which this property is required on requests.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"type": "string",
|
||||
"description": "The default value of this property (if one exists)."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A description of this object."
|
||||
},
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"description": "Values this parameter may take (if it is an enum).",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"enumDescriptions": {
|
||||
"type": "array",
|
||||
"description": "The descriptions for the enums. Each position maps to the corresponding value in the \"enum\" array.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "An additional regular expression or key that helps constrain the value. For more details see: http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.23"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier for this schema."
|
||||
},
|
||||
"items": {
|
||||
"$ref": "JsonSchema",
|
||||
"description": "If this is a schema for an array, this property is the schema for each element in the array."
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"description": "Whether this parameter goes in the query or the path for REST requests."
|
||||
},
|
||||
"maximum": {
|
||||
"type": "string",
|
||||
"description": "The maximum value of this parameter."
|
||||
},
|
||||
"minimum": {
|
||||
"type": "string",
|
||||
"description": "The minimum value of this parameter."
|
||||
},
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"description": "The regular expression this parameter must conform to. Uses Java 6 regex format: http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html"
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"description": "If this is a schema for an object, list the schema for each property of this object.",
|
||||
"additionalProperties": {
|
||||
"$ref": "JsonSchema",
|
||||
"description": "A single property of this object. The value is itself a JSON Schema object describing this property."
|
||||
}
|
||||
},
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "The value is read-only, generated by the service. The value cannot be modified by the client. If the value is included in a POST, PUT, or PATCH request, it is ignored by the service."
|
||||
},
|
||||
"repeated": {
|
||||
"type": "boolean",
|
||||
"description": "Whether this parameter may appear multiple times."
|
||||
},
|
||||
"required": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the parameter is required."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The value type for this schema. A list of values can be found here: http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1"
|
||||
},
|
||||
"variant": {
|
||||
"type": "object",
|
||||
"description": "In a variant data type, the value of one property is used to determine how to interpret the entire entity. Its value must exist in a map of descriminant values to schema names.",
|
||||
"properties": {
|
||||
"discriminant": {
|
||||
"type": "string",
|
||||
"description": "The name of the type discriminant property."
|
||||
},
|
||||
"map": {
|
||||
"type": "array",
|
||||
"description": "The map of discriminant value to schema to use for parsing..",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"$ref": {
|
||||
"type": "string"
|
||||
},
|
||||
"type_value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"RestDescription": {
|
||||
"id": "RestDescription",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auth": {
|
||||
"type": "object",
|
||||
"description": "Authentication information.",
|
||||
"properties": {
|
||||
"oauth2": {
|
||||
"type": "object",
|
||||
"description": "OAuth 2.0 authentication information.",
|
||||
"properties": {
|
||||
"scopes": {
|
||||
"type": "object",
|
||||
"description": "Available OAuth 2.0 scopes.",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "The scope value.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Description of scope."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"basePath": {
|
||||
"type": "string",
|
||||
"description": "[DEPRECATED] The base path for REST requests."
|
||||
},
|
||||
"baseUrl": {
|
||||
"type": "string",
|
||||
"description": "[DEPRECATED] The base URL for REST requests."
|
||||
},
|
||||
"batchPath": {
|
||||
"type": "string",
|
||||
"description": "The path for REST batch requests.",
|
||||
"default": "batch"
|
||||
},
|
||||
"canonicalName": {
|
||||
"type": "string",
|
||||
"description": "Indicates how the API name should be capitalized and split into various parts. Useful for generating pretty class names."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "The description of this API."
|
||||
},
|
||||
"discoveryVersion": {
|
||||
"type": "string",
|
||||
"description": "Indicate the version of the Discovery API used to generate this doc.",
|
||||
"default": "v1"
|
||||
},
|
||||
"documentationLink": {
|
||||
"type": "string",
|
||||
"description": "A link to human readable documentation for the API."
|
||||
},
|
||||
"etag": {
|
||||
"type": "string",
|
||||
"description": "The ETag for this response.",
|
||||
"readOnly": true
|
||||
},
|
||||
"exponentialBackoffDefault": {
|
||||
"type": "boolean",
|
||||
"description": "Enable exponential backoff for suitable methods in the generated clients."
|
||||
},
|
||||
"features": {
|
||||
"type": "array",
|
||||
"description": "A list of supported features for this API.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"icons": {
|
||||
"type": "object",
|
||||
"description": "Links to 16x16 and 32x32 icons representing the API.",
|
||||
"properties": {
|
||||
"x16": {
|
||||
"type": "string",
|
||||
"description": "The URL of the 16x16 icon."
|
||||
},
|
||||
"x32": {
|
||||
"type": "string",
|
||||
"description": "The URL of the 32x32 icon."
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "The ID of this API."
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "The kind for this response.",
|
||||
"default": "discovery#restDescription"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"description": "Labels for the status of this API, such as labs or deprecated.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"methods": {
|
||||
"type": "object",
|
||||
"description": "API-level methods for this API.",
|
||||
"additionalProperties": {
|
||||
"$ref": "RestMethod",
|
||||
"description": "An individual method description."
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of this API."
|
||||
},
|
||||
"ownerDomain": {
|
||||
"type": "string",
|
||||
"description": "The domain of the owner of this API. Together with the ownerName and a packagePath values, this can be used to generate a library for this API which would have a unique fully qualified name."
|
||||
},
|
||||
"ownerName": {
|
||||
"type": "string",
|
||||
"description": "The name of the owner of this API. See ownerDomain."
|
||||
},
|
||||
"packagePath": {
|
||||
"type": "string",
|
||||
"description": "The package of the owner of this API. See ownerDomain."
|
||||
},
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"description": "Common parameters that apply across all apis.",
|
||||
"additionalProperties": {
|
||||
"$ref": "JsonSchema",
|
||||
"description": "Description of a single parameter."
|
||||
}
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string",
|
||||
"description": "The protocol described by this document.",
|
||||
"default": "rest"
|
||||
},
|
||||
"resources": {
|
||||
"type": "object",
|
||||
"description": "The resources in this API.",
|
||||
"additionalProperties": {
|
||||
"$ref": "RestResource",
|
||||
"description": "An individual resource description. Contains methods and sub-resources related to this resource."
|
||||
}
|
||||
},
|
||||
"revision": {
|
||||
"type": "string",
|
||||
"description": "The version of this API."
|
||||
},
|
||||
"rootUrl": {
|
||||
"type": "string",
|
||||
"description": "The root URL under which all API services live."
|
||||
},
|
||||
"schemas": {
|
||||
"type": "object",
|
||||
"description": "The schemas for this API.",
|
||||
"additionalProperties": {
|
||||
"$ref": "JsonSchema",
|
||||
"description": "An individual schema description."
|
||||
}
|
||||
},
|
||||
"servicePath": {
|
||||
"type": "string",
|
||||
"description": "The base path for all REST requests."
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "The title of this API."
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of this API."
|
||||
},
|
||||
"version_module": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RestMethod": {
|
||||
"id": "RestMethod",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Description of this method."
|
||||
},
|
||||
"etagRequired": {
|
||||
"type": "boolean",
|
||||
"description": "Whether this method requires an ETag to be specified. The ETag is sent as an HTTP If-Match or If-None-Match header."
|
||||
},
|
||||
"httpMethod": {
|
||||
"type": "string",
|
||||
"description": "HTTP method used by this method."
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "A unique ID for this method. This property can be used to match methods between different versions of Discovery."
|
||||
},
|
||||
"mediaUpload": {
|
||||
"type": "object",
|
||||
"description": "Media upload parameters.",
|
||||
"properties": {
|
||||
"accept": {
|
||||
"type": "array",
|
||||
"description": "MIME Media Ranges for acceptable media uploads to this method.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"maxSize": {
|
||||
"type": "string",
|
||||
"description": "Maximum size of a media upload, such as \"1MB\", \"2GB\" or \"3TB\"."
|
||||
},
|
||||
"protocols": {
|
||||
"type": "object",
|
||||
"description": "Supported upload protocols.",
|
||||
"properties": {
|
||||
"resumable": {
|
||||
"type": "object",
|
||||
"description": "Supports the Resumable Media Upload protocol.",
|
||||
"properties": {
|
||||
"multipart": {
|
||||
"type": "boolean",
|
||||
"description": "True if this endpoint supports uploading multipart media.",
|
||||
"default": "true"
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "The URI path to be used for upload. Should be used in conjunction with the basePath property at the api-level."
|
||||
}
|
||||
}
|
||||
},
|
||||
"simple": {
|
||||
"type": "object",
|
||||
"description": "Supports uploading as a single HTTP request.",
|
||||
"properties": {
|
||||
"multipart": {
|
||||
"type": "boolean",
|
||||
"description": "True if this endpoint supports upload multipart media.",
|
||||
"default": "true"
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "The URI path to be used for upload. Should be used in conjunction with the basePath property at the api-level."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameterOrder": {
|
||||
"type": "array",
|
||||
"description": "Ordered list of required parameters, serves as a hint to clients on how to structure their method signatures. The array is ordered such that the \"most-significant\" parameter appears first.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"description": "Details for all parameters in this method.",
|
||||
"additionalProperties": {
|
||||
"$ref": "JsonSchema",
|
||||
"description": "Details for a single parameter in this method."
|
||||
}
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "The URI path of this REST method. Should be used in conjunction with the basePath property at the api-level."
|
||||
},
|
||||
"request": {
|
||||
"type": "object",
|
||||
"description": "The schema for the request.",
|
||||
"properties": {
|
||||
"$ref": {
|
||||
"type": "string",
|
||||
"description": "Schema ID for the request schema."
|
||||
},
|
||||
"parameterName": {
|
||||
"type": "string",
|
||||
"description": "parameter name."
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"type": "object",
|
||||
"description": "The schema for the response.",
|
||||
"properties": {
|
||||
"$ref": {
|
||||
"type": "string",
|
||||
"description": "Schema ID for the response schema."
|
||||
}
|
||||
}
|
||||
},
|
||||
"scopes": {
|
||||
"type": "array",
|
||||
"description": "OAuth 2.0 scopes applicable to this method.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"supportsMediaDownload": {
|
||||
"type": "boolean",
|
||||
"description": "Whether this method supports media downloads."
|
||||
},
|
||||
"supportsMediaUpload": {
|
||||
"type": "boolean",
|
||||
"description": "Whether this method supports media uploads."
|
||||
},
|
||||
"supportsSubscription": {
|
||||
"type": "boolean",
|
||||
"description": "Whether this method supports subscriptions."
|
||||
},
|
||||
"useMediaDownloadService": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates that downloads from this method should use the download service URL (i.e. \"/download\"). Only applies if the method supports media download."
|
||||
}
|
||||
}
|
||||
},
|
||||
"RestResource": {
|
||||
"id": "RestResource",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"methods": {
|
||||
"type": "object",
|
||||
"description": "Methods on this resource.",
|
||||
"additionalProperties": {
|
||||
"$ref": "RestMethod",
|
||||
"description": "Description for any methods on this resource."
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"type": "object",
|
||||
"description": "Sub-resources on this resource.",
|
||||
"additionalProperties": {
|
||||
"$ref": "RestResource",
|
||||
"description": "Description for any sub-resources on this resource."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"apis": {
|
||||
"methods": {
|
||||
"getRest": {
|
||||
"id": "discovery.apis.getRest",
|
||||
"path": "apis/{api}/{version}/rest",
|
||||
"httpMethod": "GET",
|
||||
"description": "Retrieve the description of a particular version of an api.",
|
||||
"parameters": {
|
||||
"api": {
|
||||
"type": "string",
|
||||
"description": "The name of the API.",
|
||||
"required": true,
|
||||
"location": "path"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the API.",
|
||||
"required": true,
|
||||
"location": "path"
|
||||
}
|
||||
},
|
||||
"parameterOrder": [
|
||||
"api",
|
||||
"version"
|
||||
],
|
||||
"response": {
|
||||
"$ref": "RestDescription"
|
||||
}
|
||||
},
|
||||
"list": {
|
||||
"id": "discovery.apis.list",
|
||||
"path": "apis",
|
||||
"httpMethod": "GET",
|
||||
"description": "Retrieve the list of APIs supported at this endpoint.",
|
||||
"parameters": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Only include APIs with the given name.",
|
||||
"location": "query"
|
||||
},
|
||||
"preferred": {
|
||||
"type": "boolean",
|
||||
"description": "Return only the preferred version of an API.",
|
||||
"default": "false",
|
||||
"location": "query"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"$ref": "DirectoryList"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1234
vendor/google.golang.org/api/discovery/v1/discovery-gen.go
generated
vendored
Normal file
1234
vendor/google.golang.org/api/discovery/v1/discovery-gen.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@ -813,6 +813,12 @@
|
||||
"revision": "66dba45b06824cbfe030e696b156d562994531e1",
|
||||
"revisionTime": "2017-07-22T12:18:25Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "wv8+a9dOWrdJEIt1mva9qLlTSfo=",
|
||||
"path": "google.golang.org/api/discovery/v1",
|
||||
"revision": "295e4bb0ade057ae2cfb9876ab0b54635dbfcea4",
|
||||
"revisionTime": "2017-07-18T13:06:16Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "JYl35km48fLrIx7YUtzcgd4J7Rk=",
|
||||
"path": "google.golang.org/api/dns/v1",
|
||||
|
Loading…
Reference in New Issue
Block a user