
- Move from the old github.com/golang/glog to k8s.io/klog - klog as explicit InitFlags() so we add them as necessary - we update the other repositories that we vendor that made a similar change from glog to klog * github.com/kubernetes/repo-infra * k8s.io/gengo/ * k8s.io/kube-openapi/ * github.com/google/cadvisor - Entirely remove all references to glog - Fix some tests by explicit InitFlags in their init() methods Change-Id: I92db545ff36fcec83afe98f550c9e630098b3135
1377 lines
41 KiB
Go
1377 lines
41 KiB
Go
/*
|
|
Copyright 2017 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// Generator for GCE compute wrapper code. You must regenerate the code after
|
|
// modifying this file:
|
|
//
|
|
// $ go run gen/main.go > gen.go
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"text/template"
|
|
"time"
|
|
|
|
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta"
|
|
)
|
|
|
|
const (
|
|
gofmt = "gofmt"
|
|
packageRoot = "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud"
|
|
|
|
// readOnly specifies that the given resource is read-only and should not
|
|
// have insert() or delete() methods generated for the wrapper.
|
|
readOnly = iota
|
|
)
|
|
|
|
var flags = struct {
|
|
gofmt bool
|
|
mode string
|
|
}{}
|
|
|
|
func init() {
|
|
flag.BoolVar(&flags.gofmt, "gofmt", true, "run output through gofmt")
|
|
flag.StringVar(&flags.mode, "mode", "src", "content to generate: src, test, dummy")
|
|
}
|
|
|
|
// gofmtContent runs "gofmt" on the given contents.
|
|
func gofmtContent(r io.Reader) string {
|
|
cmd := exec.Command(gofmt, "-s")
|
|
out := &bytes.Buffer{}
|
|
cmd.Stdin = r
|
|
cmd.Stdout = out
|
|
cmdErr := &bytes.Buffer{}
|
|
cmd.Stderr = cmdErr
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
fmt.Fprintf(os.Stderr, cmdErr.String())
|
|
panic(err)
|
|
}
|
|
return out.String()
|
|
}
|
|
|
|
// genHeader generate the header for the file.
|
|
func genHeader(wr io.Writer) {
|
|
const text = `/*
|
|
Copyright {{.Year}} The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// This file was generated by "go run gen/main.go > gen.go". Do not edit
|
|
// directly.
|
|
|
|
package cloud
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"sync"
|
|
|
|
"google.golang.org/api/googleapi"
|
|
"k8s.io/klog"
|
|
|
|
"{{.PackageRoot}}/filter"
|
|
"{{.PackageRoot}}/meta"
|
|
|
|
`
|
|
tmpl := template.Must(template.New("header").Parse(text))
|
|
values := map[string]string{
|
|
"Year": fmt.Sprintf("%v", time.Now().Year()),
|
|
"PackageRoot": packageRoot,
|
|
}
|
|
if err := tmpl.Execute(wr, values); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
var hasGA, hasAlpha, hasBeta bool
|
|
for _, s := range meta.AllServices {
|
|
switch s.Version() {
|
|
case meta.VersionGA:
|
|
hasGA = true
|
|
case meta.VersionAlpha:
|
|
hasAlpha = true
|
|
case meta.VersionBeta:
|
|
hasBeta = true
|
|
}
|
|
}
|
|
if hasAlpha {
|
|
fmt.Fprintln(wr, ` alpha "google.golang.org/api/compute/v0.alpha"`)
|
|
}
|
|
if hasBeta {
|
|
fmt.Fprintln(wr, ` beta "google.golang.org/api/compute/v0.beta"`)
|
|
}
|
|
if hasGA {
|
|
fmt.Fprintln(wr, ` ga "google.golang.org/api/compute/v1"`)
|
|
}
|
|
fmt.Fprintf(wr, ")\n\n")
|
|
}
|
|
|
|
// genStubs generates the interface and wrapper stubs.
|
|
func genStubs(wr io.Writer) {
|
|
const text = `// Cloud is an interface for the GCE compute API.
|
|
type Cloud interface {
|
|
{{- range .All}}
|
|
{{.WrapType}}() {{.WrapType}}
|
|
{{- end}}
|
|
}
|
|
|
|
// NewGCE returns a GCE.
|
|
func NewGCE(s *Service) *GCE {
|
|
g := &GCE{
|
|
{{- range .All}}
|
|
{{.Field}}: &{{.GCEWrapType}}{s},
|
|
{{- end}}
|
|
}
|
|
return g
|
|
}
|
|
|
|
// GCE implements Cloud.
|
|
var _ Cloud = (*GCE)(nil)
|
|
|
|
// GCE is the golang adapter for the compute APIs.
|
|
type GCE struct {
|
|
{{- range .All}}
|
|
{{.Field}} *{{.GCEWrapType}}
|
|
{{- end}}
|
|
}
|
|
|
|
{{range .All}}
|
|
// {{.WrapType}} returns the interface for the {{.Version}} {{.Service}}.
|
|
func (gce *GCE) {{.WrapType}}() {{.WrapType}} {
|
|
return gce.{{.Field}}
|
|
}
|
|
{{- end}}
|
|
|
|
// NewMockGCE returns a new mock for GCE.
|
|
func NewMockGCE(projectRouter ProjectRouter) *MockGCE {
|
|
{{- range .Groups}}
|
|
mock{{.Service}}Objs := map[meta.Key]*Mock{{.Service}}Obj{}
|
|
{{- end}}
|
|
|
|
mock := &MockGCE{
|
|
{{- range .All}}
|
|
{{.MockField}}: New{{.MockWrapType}}(projectRouter, mock{{.Service}}Objs),
|
|
{{- end}}
|
|
}
|
|
return mock
|
|
}
|
|
|
|
// MockGCE implements Cloud.
|
|
var _ Cloud = (*MockGCE)(nil)
|
|
|
|
// MockGCE is the mock for the compute API.
|
|
type MockGCE struct {
|
|
{{- range .All}}
|
|
{{.MockField}} *{{.MockWrapType}}
|
|
{{- end}}
|
|
}
|
|
{{range .All}}
|
|
// {{.WrapType}} returns the interface for the {{.Version}} {{.Service}}.
|
|
func (mock *MockGCE) {{.WrapType}}() {{.WrapType}} {
|
|
return mock.{{.MockField}}
|
|
}
|
|
{{end}}
|
|
|
|
{{range .Groups}}
|
|
// Mock{{.Service}}Obj is used to store the various object versions in the shared
|
|
// map of mocked objects. This allows for multiple API versions to co-exist and
|
|
// share the same "view" of the objects in the backend.
|
|
type Mock{{.Service}}Obj struct {
|
|
Obj interface{}
|
|
}
|
|
{{- if .HasAlpha}}
|
|
// ToAlpha retrieves the given version of the object.
|
|
func (m *Mock{{.Service}}Obj) ToAlpha() *{{.Alpha.FQObjectType}} {
|
|
if ret, ok := m.Obj.(*{{.Alpha.FQObjectType}}); ok {
|
|
return ret
|
|
}
|
|
// Convert the object via JSON copying to the type that was requested.
|
|
ret := &{{.Alpha.FQObjectType}}{}
|
|
if err := copyViaJSON(ret, m.Obj); err != nil {
|
|
klog.Errorf("Could not convert %T to *{{.Alpha.FQObjectType}} via JSON: %v", m.Obj, err)
|
|
}
|
|
return ret
|
|
}
|
|
{{- end}}
|
|
{{- if .HasBeta}}
|
|
// ToBeta retrieves the given version of the object.
|
|
func (m *Mock{{.Service}}Obj) ToBeta() *{{.Beta.FQObjectType}} {
|
|
if ret, ok := m.Obj.(*{{.Beta.FQObjectType}}); ok {
|
|
return ret
|
|
}
|
|
// Convert the object via JSON copying to the type that was requested.
|
|
ret := &{{.Beta.FQObjectType}}{}
|
|
if err := copyViaJSON(ret, m.Obj); err != nil {
|
|
klog.Errorf("Could not convert %T to *{{.Beta.FQObjectType}} via JSON: %v", m.Obj, err)
|
|
}
|
|
return ret
|
|
}
|
|
{{- end}}
|
|
{{- if .HasGA}}
|
|
// ToGA retrieves the given version of the object.
|
|
func (m *Mock{{.Service}}Obj) ToGA() *{{.GA.FQObjectType}} {
|
|
if ret, ok := m.Obj.(*{{.GA.FQObjectType}}); ok {
|
|
return ret
|
|
}
|
|
// Convert the object via JSON copying to the type that was requested.
|
|
ret := &{{.GA.FQObjectType}}{}
|
|
if err := copyViaJSON(ret, m.Obj); err != nil {
|
|
klog.Errorf("Could not convert %T to *{{.GA.FQObjectType}} via JSON: %v", m.Obj, err)
|
|
}
|
|
return ret
|
|
}
|
|
{{- end}}
|
|
{{- end}}
|
|
`
|
|
data := struct {
|
|
All []*meta.ServiceInfo
|
|
Groups map[string]*meta.ServiceGroup
|
|
}{meta.AllServices, meta.AllServicesByGroup}
|
|
|
|
tmpl := template.Must(template.New("interface").Parse(text))
|
|
if err := tmpl.Execute(wr, data); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// genTypes generates the type wrappers.
|
|
func genTypes(wr io.Writer) {
|
|
const text = `// {{.WrapType}} is an interface that allows for mocking of {{.Service}}.
|
|
type {{.WrapType}} interface {
|
|
{{- if .GenerateCustomOps}}
|
|
// {{.WrapTypeOps}} is an interface with additional non-CRUD type methods.
|
|
// This interface is expected to be implemented by hand (non-autogenerated).
|
|
{{.WrapTypeOps}}
|
|
{{- end}}
|
|
{{- if .GenerateGet}}
|
|
Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error)
|
|
{{- end -}}
|
|
{{- if .GenerateList}}
|
|
{{- if .KeyIsGlobal}}
|
|
List(ctx context.Context, fl *filter.F) ([]*{{.FQObjectType}}, error)
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional}}
|
|
List(ctx context.Context, region string, fl *filter.F) ([]*{{.FQObjectType}}, error)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
List(ctx context.Context, zone string, fl *filter.F) ([]*{{.FQObjectType}}, error)
|
|
{{- end -}}
|
|
{{- end -}}
|
|
{{- if .GenerateInsert}}
|
|
Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error
|
|
{{- end -}}
|
|
{{- if .GenerateDelete}}
|
|
Delete(ctx context.Context, key *meta.Key) error
|
|
{{- end -}}
|
|
{{- if .AggregatedList}}
|
|
AggregatedList(ctx context.Context, fl *filter.F) (map[string][]*{{.FQObjectType}}, error)
|
|
{{- end}}
|
|
{{- with .Methods -}}
|
|
{{- range .}}
|
|
{{.InterfaceFunc}}
|
|
{{- end -}}
|
|
{{- end}}
|
|
}
|
|
|
|
// New{{.MockWrapType}} returns a new mock for {{.Service}}.
|
|
func New{{.MockWrapType}}(pr ProjectRouter, objs map[meta.Key]*Mock{{.Service}}Obj) *{{.MockWrapType}} {
|
|
mock := &{{.MockWrapType}}{
|
|
ProjectRouter: pr,
|
|
|
|
Objects: objs,
|
|
{{- if .GenerateGet}}
|
|
GetError: map[meta.Key]error{},
|
|
{{- end -}}
|
|
{{- if .GenerateInsert}}
|
|
InsertError: map[meta.Key]error{},
|
|
{{- end -}}
|
|
{{- if .GenerateDelete}}
|
|
DeleteError: map[meta.Key]error{},
|
|
{{- end}}
|
|
}
|
|
return mock
|
|
}
|
|
|
|
// {{.MockWrapType}} is the mock for {{.Service}}.
|
|
type {{.MockWrapType}} struct {
|
|
Lock sync.Mutex
|
|
|
|
ProjectRouter ProjectRouter
|
|
|
|
// Objects maintained by the mock.
|
|
Objects map[meta.Key]*Mock{{.Service}}Obj
|
|
|
|
// If an entry exists for the given key and operation, then the error
|
|
// will be returned instead of the operation.
|
|
{{- if .GenerateGet}}
|
|
GetError map[meta.Key]error
|
|
{{- end -}}
|
|
{{- if .GenerateList}}
|
|
ListError *error
|
|
{{- end -}}
|
|
{{- if .GenerateInsert}}
|
|
InsertError map[meta.Key]error
|
|
{{- end -}}
|
|
{{- if .GenerateDelete}}
|
|
DeleteError map[meta.Key]error
|
|
{{- end -}}
|
|
{{- if .AggregatedList}}
|
|
AggregatedListError *error
|
|
{{- end}}
|
|
|
|
// xxxHook allow you to intercept the standard processing of the mock in
|
|
// order to add your own logic. Return (true, _, _) to prevent the normal
|
|
// execution flow of the mock. Return (false, nil, nil) to continue with
|
|
// normal mock behavior/ after the hook function executes.
|
|
{{- if .GenerateGet}}
|
|
GetHook func(ctx context.Context, key *meta.Key, m *{{.MockWrapType}}) (bool, *{{.FQObjectType}}, error)
|
|
{{- end -}}
|
|
{{- if .GenerateList}}
|
|
{{- if .KeyIsGlobal}}
|
|
ListHook func(ctx context.Context, fl *filter.F, m *{{.MockWrapType}}) (bool, []*{{.FQObjectType}}, error)
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional}}
|
|
ListHook func(ctx context.Context, region string, fl *filter.F, m *{{.MockWrapType}}) (bool, []*{{.FQObjectType}}, error)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
ListHook func(ctx context.Context, zone string, fl *filter.F, m *{{.MockWrapType}}) (bool, []*{{.FQObjectType}}, error)
|
|
{{- end}}
|
|
{{- end -}}
|
|
{{- if .GenerateInsert}}
|
|
InsertHook func(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}, m *{{.MockWrapType}}) (bool, error)
|
|
{{- end -}}
|
|
{{- if .GenerateDelete}}
|
|
DeleteHook func(ctx context.Context, key *meta.Key, m *{{.MockWrapType}}) (bool, error)
|
|
{{- end -}}
|
|
{{- if .AggregatedList}}
|
|
AggregatedListHook func(ctx context.Context, fl *filter.F, m *{{.MockWrapType}}) (bool, map[string][]*{{.FQObjectType}}, error)
|
|
{{- end}}
|
|
|
|
{{- with .Methods -}}
|
|
{{- range .}}
|
|
{{.MockHook}}
|
|
{{- end -}}
|
|
{{- end}}
|
|
|
|
// X is extra state that can be used as part of the mock. Generated code
|
|
// will not use this field.
|
|
X interface{}
|
|
}
|
|
|
|
{{- if .GenerateGet}}
|
|
// Get returns the object from the mock.
|
|
func (m *{{.MockWrapType}}) Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error) {
|
|
if m.GetHook != nil {
|
|
if intercept, obj, err := m.GetHook(ctx, key, m); intercept {
|
|
klog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = %+v, %v", ctx, key, obj ,err)
|
|
return obj, err
|
|
}
|
|
}
|
|
if !key.Valid() {
|
|
return nil, fmt.Errorf("invalid GCE key (%+v)", key)
|
|
}
|
|
|
|
m.Lock.Lock()
|
|
defer m.Lock.Unlock()
|
|
|
|
if err, ok := m.GetError[*key]; ok {
|
|
klog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = nil, %v", ctx, key, err)
|
|
return nil, err
|
|
}
|
|
if obj, ok := m.Objects[*key]; ok {
|
|
typedObj := obj.To{{.VersionTitle}}()
|
|
klog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = %+v, nil", ctx, key, typedObj)
|
|
return typedObj, nil
|
|
}
|
|
|
|
err := &googleapi.Error{
|
|
Code: http.StatusNotFound,
|
|
Message: fmt.Sprintf("{{.MockWrapType}} %v not found", key),
|
|
}
|
|
klog.V(5).Infof("{{.MockWrapType}}.Get(%v, %s) = nil, %v", ctx, key, err)
|
|
return nil, err
|
|
}
|
|
{{- end}}
|
|
|
|
{{- if .GenerateList}}
|
|
{{if .KeyIsGlobal -}}
|
|
// List all of the objects in the mock.
|
|
func (m *{{.MockWrapType}}) List(ctx context.Context, fl *filter.F) ([]*{{.FQObjectType}}, error) {
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional -}}
|
|
// List all of the objects in the mock in the given region.
|
|
func (m *{{.MockWrapType}}) List(ctx context.Context, region string, fl *filter.F) ([]*{{.FQObjectType}}, error) {
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal -}}
|
|
// List all of the objects in the mock in the given zone.
|
|
func (m *{{.MockWrapType}}) List(ctx context.Context, zone string, fl *filter.F) ([]*{{.FQObjectType}}, error) {
|
|
{{- end}}
|
|
if m.ListHook != nil {
|
|
{{if .KeyIsGlobal -}}
|
|
if intercept, objs, err := m.ListHook(ctx, fl, m); intercept {
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %v) = [%v items], %v", ctx, fl, len(objs), err)
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional -}}
|
|
if intercept, objs, err := m.ListHook(ctx, region, fl, m); intercept {
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = [%v items], %v", ctx, region, fl, len(objs), err)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal -}}
|
|
if intercept, objs, err := m.ListHook(ctx, zone, fl, m); intercept {
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = [%v items], %v", ctx, zone, fl, len(objs), err)
|
|
{{- end}}
|
|
return objs, err
|
|
}
|
|
}
|
|
|
|
m.Lock.Lock()
|
|
defer m.Lock.Unlock()
|
|
|
|
if m.ListError != nil {
|
|
err := *m.ListError
|
|
{{if .KeyIsGlobal -}}
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %v) = nil, %v", ctx, fl, err)
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional -}}
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = nil, %v", ctx, region, fl, err)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal -}}
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = nil, %v", ctx, zone, fl, err)
|
|
{{- end}}
|
|
|
|
return nil, *m.ListError
|
|
}
|
|
|
|
var objs []*{{.FQObjectType}}
|
|
{{- if .KeyIsGlobal}}
|
|
for _, obj := range m.Objects {
|
|
{{- else}}
|
|
for key, obj := range m.Objects {
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional}}
|
|
if key.Region != region {
|
|
continue
|
|
}
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
if key.Zone != zone {
|
|
continue
|
|
}
|
|
{{- end}}
|
|
if !fl.Match(obj.To{{.VersionTitle}}()) {
|
|
continue
|
|
}
|
|
objs = append(objs, obj.To{{.VersionTitle}}())
|
|
}
|
|
|
|
{{if .KeyIsGlobal -}}
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %v) = [%v items], nil", ctx, fl, len(objs))
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional -}}
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = [%v items], nil", ctx, region, fl, len(objs))
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal -}}
|
|
klog.V(5).Infof("{{.MockWrapType}}.List(%v, %q, %v) = [%v items], nil", ctx, zone, fl, len(objs))
|
|
{{- end}}
|
|
return objs, nil
|
|
}
|
|
{{- end}}
|
|
|
|
{{- if .GenerateInsert}}
|
|
// Insert is a mock for inserting/creating a new object.
|
|
func (m *{{.MockWrapType}}) Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error {
|
|
if m.InsertHook != nil {
|
|
if intercept, err := m.InsertHook(ctx, key, obj, m); intercept {
|
|
klog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = %v", ctx, key, obj, err)
|
|
return err
|
|
}
|
|
}
|
|
if !key.Valid() {
|
|
return fmt.Errorf("invalid GCE key (%+v)", key)
|
|
}
|
|
|
|
m.Lock.Lock()
|
|
defer m.Lock.Unlock()
|
|
|
|
if err, ok := m.InsertError[*key]; ok {
|
|
klog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = %v", ctx, key, obj, err)
|
|
return err
|
|
}
|
|
if _, ok := m.Objects[*key]; ok {
|
|
err := &googleapi.Error{
|
|
Code: http.StatusConflict,
|
|
Message: fmt.Sprintf("{{.MockWrapType}} %v exists", key),
|
|
}
|
|
klog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = %v", ctx, key, obj, err)
|
|
return err
|
|
}
|
|
|
|
obj.Name = key.Name
|
|
projectID := m.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Resource}}")
|
|
obj.SelfLink = SelfLink(meta.Version{{.VersionTitle}}, projectID, "{{.Resource}}", key)
|
|
|
|
m.Objects[*key] = &Mock{{.Service}}Obj{obj}
|
|
klog.V(5).Infof("{{.MockWrapType}}.Insert(%v, %v, %+v) = nil", ctx, key, obj)
|
|
return nil
|
|
}
|
|
{{- end}}
|
|
|
|
{{- if .GenerateDelete}}
|
|
// Delete is a mock for deleting the object.
|
|
func (m *{{.MockWrapType}}) Delete(ctx context.Context, key *meta.Key) error {
|
|
if m.DeleteHook != nil {
|
|
if intercept, err := m.DeleteHook(ctx, key, m); intercept {
|
|
klog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = %v", ctx, key, err)
|
|
return err
|
|
}
|
|
}
|
|
if !key.Valid() {
|
|
return fmt.Errorf("invalid GCE key (%+v)", key)
|
|
}
|
|
|
|
m.Lock.Lock()
|
|
defer m.Lock.Unlock()
|
|
|
|
if err, ok := m.DeleteError[*key]; ok {
|
|
klog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = %v", ctx, key, err)
|
|
return err
|
|
}
|
|
if _, ok := m.Objects[*key]; !ok {
|
|
err := &googleapi.Error{
|
|
Code: http.StatusNotFound,
|
|
Message: fmt.Sprintf("{{.MockWrapType}} %v not found", key),
|
|
}
|
|
klog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = %v", ctx, key, err)
|
|
return err
|
|
}
|
|
|
|
delete(m.Objects, *key)
|
|
klog.V(5).Infof("{{.MockWrapType}}.Delete(%v, %v) = nil", ctx, key)
|
|
return nil
|
|
}
|
|
{{- end}}
|
|
|
|
{{- if .AggregatedList}}
|
|
// AggregatedList is a mock for AggregatedList.
|
|
func (m *{{.MockWrapType}}) AggregatedList(ctx context.Context, fl *filter.F) (map[string][]*{{.FQObjectType}}, error) {
|
|
if m.AggregatedListHook != nil {
|
|
if intercept, objs, err := m.AggregatedListHook(ctx, fl, m); intercept {
|
|
klog.V(5).Infof("{{.MockWrapType}}.AggregatedList(%v, %v) = [%v items], %v", ctx, fl, len(objs), err)
|
|
return objs, err
|
|
}
|
|
}
|
|
|
|
m.Lock.Lock()
|
|
defer m.Lock.Unlock()
|
|
|
|
if m.AggregatedListError != nil {
|
|
err := *m.AggregatedListError
|
|
klog.V(5).Infof("{{.MockWrapType}}.AggregatedList(%v, %v) = nil, %v", ctx, fl, err)
|
|
return nil, err
|
|
}
|
|
|
|
objs := map[string][]*{{.FQObjectType}}{}
|
|
for _, obj := range m.Objects {
|
|
res, err := ParseResourceURL(obj.To{{.VersionTitle}}().SelfLink)
|
|
{{- if .KeyIsRegional}}
|
|
location := res.Key.Region
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
location := res.Key.Zone
|
|
{{- end}}
|
|
if err != nil {
|
|
klog.V(5).Infof("{{.MockWrapType}}.AggregatedList(%v, %v) = nil, %v", ctx, fl, err)
|
|
return nil, err
|
|
}
|
|
if !fl.Match(obj.To{{.VersionTitle}}()) {
|
|
continue
|
|
}
|
|
objs[location] = append(objs[location], obj.To{{.VersionTitle}}())
|
|
}
|
|
klog.V(5).Infof("{{.MockWrapType}}.AggregatedList(%v, %v) = [%v items], nil", ctx, fl, len(objs))
|
|
return objs, nil
|
|
}
|
|
{{- end}}
|
|
|
|
// Obj wraps the object for use in the mock.
|
|
func (m *{{.MockWrapType}}) Obj(o *{{.FQObjectType}}) *Mock{{.Service}}Obj {
|
|
return &Mock{{.Service}}Obj{o}
|
|
}
|
|
|
|
{{with .Methods -}}
|
|
{{- range .}}
|
|
// {{.Name}} is a mock for the corresponding method.
|
|
func (m *{{.MockWrapType}}) {{.FcnArgs}} {
|
|
{{- if .IsOperation }}
|
|
if m.{{.MockHookName}} != nil {
|
|
return m.{{.MockHookName}}(ctx, key {{.CallArgs}}, m)
|
|
}
|
|
return nil
|
|
{{- else if .IsGet}}
|
|
if m.{{.MockHookName}} != nil {
|
|
return m.{{.MockHookName}}(ctx, key {{.CallArgs}}, m)
|
|
}
|
|
return nil, fmt.Errorf("{{.MockHookName}} must be set")
|
|
{{- else if .IsPaged}}
|
|
if m.{{.MockHookName}} != nil {
|
|
return m.{{.MockHookName}}(ctx, key {{.CallArgs}}, fl, m)
|
|
}
|
|
return nil, nil
|
|
{{- end}}
|
|
}
|
|
{{end -}}
|
|
{{- end}}
|
|
// {{.GCEWrapType}} is a simplifying adapter for the GCE {{.Service}}.
|
|
type {{.GCEWrapType}} struct {
|
|
s *Service
|
|
}
|
|
|
|
{{- if .GenerateGet}}
|
|
// Get the {{.Object}} named by key.
|
|
func (g *{{.GCEWrapType}}) Get(ctx context.Context, key *meta.Key) (*{{.FQObjectType}}, error) {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.Get(%v, %v): called", ctx, key)
|
|
|
|
if !key.Valid() {
|
|
klog.V(2).Infof("{{.GCEWrapType}}.Get(%v, %v): key is invalid (%#v)", ctx, key, key)
|
|
return nil, fmt.Errorf("invalid GCE key (%#v)", key)
|
|
}
|
|
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
|
rk := &RateLimitKey{
|
|
ProjectID: projectID,
|
|
Operation: "Get",
|
|
Version: meta.Version("{{.Version}}"),
|
|
Service: "{{.Service}}",
|
|
}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.Get(%v, %v): projectID = %v, rk = %+v", ctx, key, projectID, rk)
|
|
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.Get(%v, %v): RateLimiter error: %v", ctx, key, err)
|
|
return nil, err
|
|
}
|
|
{{- if .KeyIsGlobal}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Get(projectID, key.Name)
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Get(projectID, key.Region, key.Name)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Get(projectID, key.Zone, key.Name)
|
|
{{- end}}
|
|
call.Context(ctx)
|
|
v, err := call.Do()
|
|
klog.V(4).Infof("{{.GCEWrapType}}.Get(%v, %v) = %+v, %v", ctx, key, v, err)
|
|
return v, err
|
|
}
|
|
{{- end}}
|
|
|
|
{{- if .GenerateList}}
|
|
// List all {{.Object}} objects.
|
|
{{- if .KeyIsGlobal}}
|
|
func (g *{{.GCEWrapType}}) List(ctx context.Context, fl *filter.F) ([]*{{.FQObjectType}}, error) {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v) called", ctx, fl)
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional}}
|
|
func (g *{{.GCEWrapType}}) List(ctx context.Context, region string, fl *filter.F) ([]*{{.FQObjectType}}, error) {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v, %v) called", ctx, region, fl)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
func (g *{{.GCEWrapType}}) List(ctx context.Context, zone string, fl *filter.F) ([]*{{.FQObjectType}}, error) {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v, %v) called", ctx, zone, fl)
|
|
{{- end}}
|
|
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
|
rk := &RateLimitKey{
|
|
ProjectID: projectID,
|
|
Operation: "List",
|
|
Version: meta.Version("{{.Version}}"),
|
|
Service: "{{.Service}}",
|
|
}
|
|
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
|
return nil, err
|
|
}
|
|
{{- if .KeyIsGlobal}}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v): projectID = %v, rk = %+v", ctx, fl, projectID, rk)
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.List(projectID)
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional}}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v, %v): projectID = %v, rk = %+v", ctx, region, fl, projectID, rk)
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.List(projectID, region)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.List(%v, %v, %v): projectID = %v, rk = %+v", ctx, zone, fl, projectID, rk)
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.List(projectID, zone)
|
|
{{- end}}
|
|
if fl != filter.None {
|
|
call.Filter(fl.String())
|
|
}
|
|
var all []*{{.FQObjectType}}
|
|
f := func(l *{{.ObjectListType}}) error {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.List(%v, ..., %v): page %+v", ctx, fl, l)
|
|
all = append(all, l.Items...)
|
|
return nil
|
|
}
|
|
if err := call.Pages(ctx, f); err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.List(%v, ..., %v) = %v, %v", ctx, fl, nil, err)
|
|
return nil, err
|
|
}
|
|
|
|
if klog.V(4) {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.List(%v, ..., %v) = [%v items], %v", ctx, fl, len(all), nil)
|
|
} else if klog.V(5) {
|
|
var asStr []string
|
|
for _, o := range all {
|
|
asStr = append(asStr, fmt.Sprintf("%+v", o))
|
|
}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.List(%v, ..., %v) = %v, %v", ctx, fl, asStr, nil)
|
|
}
|
|
|
|
return all, nil
|
|
}
|
|
{{- end}}
|
|
|
|
{{- if .GenerateInsert}}
|
|
// Insert {{.Object}} with key of value obj.
|
|
func (g *{{.GCEWrapType}}) Insert(ctx context.Context, key *meta.Key, obj *{{.FQObjectType}}) error {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.Insert(%v, %v, %+v): called", ctx, key, obj)
|
|
if !key.Valid() {
|
|
klog.V(2).Infof("{{.GCEWrapType}}.Insert(%v, %v, ...): key is invalid (%#v)", ctx, key, key)
|
|
return fmt.Errorf("invalid GCE key (%+v)", key)
|
|
}
|
|
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
|
rk := &RateLimitKey{
|
|
ProjectID: projectID,
|
|
Operation: "Insert",
|
|
Version: meta.Version("{{.Version}}"),
|
|
Service: "{{.Service}}",
|
|
}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.Insert(%v, %v, ...): projectID = %v, rk = %+v", ctx, key, projectID, rk)
|
|
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.Insert(%v, %v, ...): RateLimiter error: %v", ctx, key, err)
|
|
return err
|
|
}
|
|
obj.Name = key.Name
|
|
{{- if .KeyIsGlobal}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Insert(projectID, obj)
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Insert(projectID, key.Region, obj)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Insert(projectID, key.Zone, obj)
|
|
{{- end}}
|
|
call.Context(ctx)
|
|
|
|
op, err := call.Do()
|
|
if err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.Insert(%v, %v, ...) = %+v", ctx, key, err)
|
|
return err
|
|
}
|
|
|
|
err = g.s.WaitForCompletion(ctx, op)
|
|
klog.V(4).Infof("{{.GCEWrapType}}.Insert(%v, %v, %+v) = %+v", ctx, key, obj, err)
|
|
return err
|
|
}
|
|
{{- end}}
|
|
|
|
{{- if .GenerateDelete}}
|
|
// Delete the {{.Object}} referenced by key.
|
|
func (g *{{.GCEWrapType}}) Delete(ctx context.Context, key *meta.Key) error {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.Delete(%v, %v): called", ctx, key)
|
|
if !key.Valid() {
|
|
klog.V(2).Infof("{{.GCEWrapType}}.Delete(%v, %v): key is invalid (%#v)", ctx, key, key)
|
|
return fmt.Errorf("invalid GCE key (%+v)", key)
|
|
}
|
|
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
|
rk := &RateLimitKey{
|
|
ProjectID: projectID,
|
|
Operation: "Delete",
|
|
Version: meta.Version("{{.Version}}"),
|
|
Service: "{{.Service}}",
|
|
}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.Delete(%v, %v): projectID = %v, rk = %+v", ctx, key, projectID, rk)
|
|
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.Delete(%v, %v): RateLimiter error: %v", ctx, key, err)
|
|
return err
|
|
}
|
|
{{- if .KeyIsGlobal}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Delete(projectID, key.Name)
|
|
{{end -}}
|
|
{{- if .KeyIsRegional}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Delete(projectID, key.Region, key.Name)
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.Delete(projectID, key.Zone, key.Name)
|
|
{{- end}}
|
|
call.Context(ctx)
|
|
|
|
op, err := call.Do()
|
|
if err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.Delete(%v, %v) = %v", ctx, key, err)
|
|
return err
|
|
}
|
|
|
|
err = g.s.WaitForCompletion(ctx, op)
|
|
klog.V(4).Infof("{{.GCEWrapType}}.Delete(%v, %v) = %v", ctx, key, err)
|
|
return err
|
|
}
|
|
{{end -}}
|
|
|
|
{{- if .AggregatedList}}
|
|
// AggregatedList lists all resources of the given type across all locations.
|
|
func (g *{{.GCEWrapType}}) AggregatedList(ctx context.Context, fl *filter.F) (map[string][]*{{.FQObjectType}}, error) {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v) called", ctx, fl)
|
|
|
|
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
|
rk := &RateLimitKey{
|
|
ProjectID: projectID,
|
|
Operation: "AggregatedList",
|
|
Version: meta.Version("{{.Version}}"),
|
|
Service: "{{.Service}}",
|
|
}
|
|
|
|
klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v): projectID = %v, rk = %+v", ctx, fl, projectID, rk)
|
|
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v): RateLimiter error: %v", ctx, fl, err)
|
|
return nil, err
|
|
}
|
|
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.AggregatedList(projectID)
|
|
call.Context(ctx)
|
|
if fl != filter.None {
|
|
call.Filter(fl.String())
|
|
}
|
|
|
|
all := map[string][]*{{.FQObjectType}}{}
|
|
f := func(l *{{.ObjectAggregatedListType}}) error {
|
|
for k, v := range l.Items {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v): page[%v]%+v", ctx, fl, k, v)
|
|
all[k] = append(all[k], v.{{.AggregatedListField}}...)
|
|
}
|
|
return nil
|
|
}
|
|
if err := call.Pages(ctx, f); err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v) = %v, %v", ctx, fl, nil, err)
|
|
return nil, err
|
|
}
|
|
if klog.V(4) {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v) = [%v items], %v", ctx, fl, len(all), nil)
|
|
} else if klog.V(5) {
|
|
var asStr []string
|
|
for _, o := range all {
|
|
asStr = append(asStr, fmt.Sprintf("%+v", o))
|
|
}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.AggregatedList(%v, %v) = %v, %v", ctx, fl, asStr, nil)
|
|
}
|
|
return all, nil
|
|
}
|
|
{{- end}}
|
|
|
|
{{- with .Methods -}}
|
|
{{- range .}}
|
|
// {{.Name}} is a method on {{.GCEWrapType}}.
|
|
func (g *{{.GCEWrapType}}) {{.FcnArgs}} {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): called", ctx, key)
|
|
|
|
if !key.Valid() {
|
|
klog.V(2).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): key is invalid (%#v)", ctx, key, key)
|
|
{{- if .IsOperation}}
|
|
return fmt.Errorf("invalid GCE key (%+v)", key)
|
|
{{- else if .IsGet}}
|
|
return nil, fmt.Errorf("invalid GCE key (%+v)", key)
|
|
{{- else if .IsPaged}}
|
|
return nil, fmt.Errorf("invalid GCE key (%+v)", key)
|
|
{{- end}}
|
|
}
|
|
projectID := g.s.ProjectRouter.ProjectID(ctx, "{{.Version}}", "{{.Service}}")
|
|
rk := &RateLimitKey{
|
|
ProjectID: projectID,
|
|
Operation: "{{.Name}}",
|
|
Version: meta.Version("{{.Version}}"),
|
|
Service: "{{.Service}}",
|
|
}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): projectID = %v, rk = %+v", ctx, key, projectID, rk)
|
|
|
|
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): RateLimiter error: %v", ctx, key, err)
|
|
{{- if .IsOperation}}
|
|
return err
|
|
{{- else}}
|
|
return nil, err
|
|
{{- end}}
|
|
}
|
|
{{- if .KeyIsGlobal}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.{{.Name}}(projectID, key.Name {{.CallArgs}})
|
|
{{- end -}}
|
|
{{- if .KeyIsRegional}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.{{.Name}}(projectID, key.Region, key.Name {{.CallArgs}})
|
|
{{- end -}}
|
|
{{- if .KeyIsZonal}}
|
|
call := g.s.{{.VersionTitle}}.{{.Service}}.{{.Name}}(projectID, key.Zone, key.Name {{.CallArgs}})
|
|
{{- end}}
|
|
{{- if .IsOperation}}
|
|
call.Context(ctx)
|
|
op, err := call.Do()
|
|
if err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %+v", ctx, key, err)
|
|
return err
|
|
}
|
|
err = g.s.WaitForCompletion(ctx, op)
|
|
klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %+v", ctx, key, err)
|
|
return err
|
|
{{- else if .IsGet}}
|
|
call.Context(ctx)
|
|
v, err := call.Do()
|
|
klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %+v, %v", ctx, key, v, err)
|
|
return v, err
|
|
{{- else if .IsPaged}}
|
|
var all []*{{.Version}}.{{.ItemType}}
|
|
f := func(l *{{.Version}}.{{.ReturnType}}) error {
|
|
klog.V(5).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...): page %+v", ctx, key, l)
|
|
all = append(all, l.Items...)
|
|
return nil
|
|
}
|
|
if err := call.Pages(ctx, f); err != nil {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %v, %v", ctx, key, nil, err)
|
|
return nil, err
|
|
}
|
|
if klog.V(4) {
|
|
klog.V(4).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = [%v items], %v", ctx, key, len(all), nil)
|
|
} else if klog.V(5) {
|
|
var asStr []string
|
|
for _, o := range all {
|
|
asStr = append(asStr, fmt.Sprintf("%+v", o))
|
|
}
|
|
klog.V(5).Infof("{{.GCEWrapType}}.{{.Name}}(%v, %v, ...) = %v, %v", ctx, key, asStr, nil)
|
|
}
|
|
return all, nil
|
|
{{- end}}
|
|
}
|
|
{{end -}}
|
|
{{- end}}
|
|
`
|
|
tmpl := template.Must(template.New("interface").Parse(text))
|
|
for _, s := range meta.AllServices {
|
|
if err := tmpl.Execute(wr, s); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// genTypes generates the type wrappers.
|
|
func genResourceIDs(wr io.Writer) {
|
|
const text = `
|
|
// New{{.Service}}ResourceID creates a ResourceID for the {{.Service}} resource.
|
|
{{- if .KeyIsProject}}
|
|
func New{{.Service}}ResourceID(project string) *ResourceID {
|
|
var key *meta.Key
|
|
{{- else}}
|
|
{{- if .KeyIsGlobal}}
|
|
func New{{.Service}}ResourceID(project, name string) *ResourceID {
|
|
key := meta.GlobalKey(name)
|
|
{{- end}}
|
|
{{- if .KeyIsRegional}}
|
|
func New{{.Service}}ResourceID(project, region, name string) *ResourceID {
|
|
key := meta.RegionalKey(name, region)
|
|
{{- end}}
|
|
{{- if .KeyIsZonal}}
|
|
func New{{.Service}}ResourceID(project, zone, name string) *ResourceID {
|
|
key := meta.ZonalKey(name, zone)
|
|
{{- end -}}
|
|
{{end}}
|
|
return &ResourceID{project, "{{.Resource}}", key}
|
|
}
|
|
`
|
|
tmpl := template.Must(template.New("resourceIDs").Parse(text))
|
|
for _, sg := range meta.SortedServicesGroups {
|
|
if err := tmpl.Execute(wr, sg.ServiceInfo()); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func genUnitTestHeader(wr io.Writer) {
|
|
const text = `/*
|
|
Copyright {{.Year}} The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// This file was generated by "go run gen/main.go -mode test > gen_test.go". Do not edit
|
|
// directly.
|
|
|
|
package cloud
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"testing"
|
|
|
|
alpha "google.golang.org/api/compute/v0.alpha"
|
|
beta "google.golang.org/api/compute/v0.beta"
|
|
ga "google.golang.org/api/compute/v1"
|
|
|
|
"{{.PackageRoot}}/filter"
|
|
"{{.PackageRoot}}/meta"
|
|
)
|
|
|
|
const location = "location"
|
|
`
|
|
tmpl := template.Must(template.New("header").Parse(text))
|
|
values := map[string]string{
|
|
"Year": fmt.Sprintf("%v", time.Now().Year()),
|
|
"PackageRoot": packageRoot,
|
|
}
|
|
if err := tmpl.Execute(wr, values); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func genUnitTestServices(wr io.Writer) {
|
|
const text = `
|
|
func Test{{.Service}}Group(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ctx := context.Background()
|
|
pr := &SingleProjectRouter{"mock-project"}
|
|
mock := NewMockGCE(pr)
|
|
|
|
var key *meta.Key
|
|
{{- if .HasAlpha}}
|
|
keyAlpha := meta.{{.Alpha.MakeKey "key-alpha" "location"}}
|
|
key = keyAlpha
|
|
{{- end}}
|
|
{{- if .HasBeta}}
|
|
keyBeta := meta.{{.Beta.MakeKey "key-beta" "location"}}
|
|
key = keyBeta
|
|
{{- end}}
|
|
{{- if .HasGA}}
|
|
keyGA := meta.{{.GA.MakeKey "key-ga" "location"}}
|
|
key = keyGA
|
|
{{- end}}
|
|
// Ignore unused variables.
|
|
_, _, _ = ctx, mock, key
|
|
|
|
// Get not found.
|
|
{{- if .HasAlpha}}{{- if .Alpha.GenerateGet}}
|
|
if _, err := mock.Alpha{{.Service}}().Get(ctx, key); err == nil {
|
|
t.Errorf("Alpha{{.Service}}().Get(%v, %v) = _, nil; want error", ctx, key)
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasBeta}}{{- if .Beta.GenerateGet}}
|
|
if _, err := mock.Beta{{.Service}}().Get(ctx, key); err == nil {
|
|
t.Errorf("Beta{{.Service}}().Get(%v, %v) = _, nil; want error", ctx, key)
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasGA}}{{- if .GA.GenerateGet}}
|
|
if _, err := mock.{{.Service}}().Get(ctx, key); err == nil {
|
|
t.Errorf("{{.Service}}().Get(%v, %v) = _, nil; want error", ctx, key)
|
|
}
|
|
{{- end}}{{- end}}
|
|
|
|
// Insert.
|
|
{{- if .HasAlpha}}{{- if .Alpha.GenerateInsert}}
|
|
{
|
|
obj := &alpha.{{.Alpha.Object}}{}
|
|
if err := mock.Alpha{{.Service}}().Insert(ctx, keyAlpha, obj); err != nil {
|
|
t.Errorf("Alpha{{.Service}}().Insert(%v, %v, %v) = %v; want nil", ctx, keyAlpha, obj, err)
|
|
}
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasBeta}}{{- if .Beta.GenerateInsert}}
|
|
{
|
|
obj := &beta.{{.Beta.Object}}{}
|
|
if err := mock.Beta{{.Service}}().Insert(ctx, keyBeta, obj); err != nil {
|
|
t.Errorf("Beta{{.Service}}().Insert(%v, %v, %v) = %v; want nil", ctx, keyBeta, obj, err)
|
|
}
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasGA}}{{- if .GA.GenerateInsert}}
|
|
{
|
|
obj := &ga.{{.GA.Object}}{}
|
|
if err := mock.{{.Service}}().Insert(ctx, keyGA, obj); err != nil {
|
|
t.Errorf("{{.Service}}().Insert(%v, %v, %v) = %v; want nil", ctx, keyGA, obj, err)
|
|
}
|
|
}
|
|
{{- end}}{{- end}}
|
|
|
|
// Get across versions.
|
|
{{- if .HasAlpha}}{{- if .Alpha.GenerateInsert}}
|
|
if obj, err := mock.Alpha{{.Service}}().Get(ctx, key); err != nil {
|
|
t.Errorf("Alpha{{.Service}}().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err)
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasBeta}}{{- if .Beta.GenerateInsert}}
|
|
if obj, err := mock.Beta{{.Service}}().Get(ctx, key); err != nil {
|
|
t.Errorf("Beta{{.Service}}().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err)
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasGA}}{{- if .GA.GenerateInsert}}
|
|
if obj, err := mock.{{.Service}}().Get(ctx, key); err != nil {
|
|
t.Errorf("{{.Service}}().Get(%v, %v) = %v, %v; want nil", ctx, key, obj, err)
|
|
}
|
|
{{- end}}{{- end}}
|
|
|
|
// List.
|
|
{{- if .HasAlpha}}
|
|
mock.MockAlpha{{.Service}}.Objects[*keyAlpha] = mock.MockAlpha{{.Service}}.Obj(&alpha.{{.Alpha.Object}}{Name: keyAlpha.Name})
|
|
{{- end}}
|
|
{{- if .HasBeta}}
|
|
mock.MockBeta{{.Service}}.Objects[*keyBeta] = mock.MockBeta{{.Service}}.Obj(&beta.{{.Beta.Object}}{Name: keyBeta.Name})
|
|
{{- end}}
|
|
{{- if .HasGA}}
|
|
mock.Mock{{.Service}}.Objects[*keyGA] = mock.Mock{{.Service}}.Obj(&ga.{{.GA.Object}}{Name: keyGA.Name})
|
|
{{- end}}
|
|
want := map[string]bool{
|
|
{{- if .HasAlpha}}
|
|
"key-alpha": true,
|
|
{{- end}}
|
|
{{- if .HasBeta}}
|
|
"key-beta": true,
|
|
{{- end}}
|
|
{{- if .HasGA}}
|
|
"key-ga": true,
|
|
{{- end}}
|
|
}
|
|
_ = want // ignore unused variables.
|
|
|
|
{{- if .HasAlpha}}{{- if .Alpha.GenerateList}}
|
|
{
|
|
{{- if .Alpha.KeyIsGlobal }}
|
|
objs, err := mock.Alpha{{.Service}}().List(ctx, filter.None)
|
|
{{- else}}
|
|
objs, err := mock.Alpha{{.Service}}().List(ctx, location, filter.None)
|
|
{{- end}}
|
|
if err != nil {
|
|
t.Errorf("Alpha{{.Service}}().List(%v, %v, %v) = %v, %v; want _, nil", ctx, location, filter.None, objs, err)
|
|
} else {
|
|
got := map[string]bool{}
|
|
for _, obj := range objs {
|
|
got[obj.Name] = true
|
|
}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("Alpha{{.Service}}().List(); got %+v, want %+v", got, want)
|
|
}
|
|
}
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasBeta}}{{- if .Beta.GenerateList}}
|
|
{
|
|
{{- if .Beta.KeyIsGlobal }}
|
|
objs, err := mock.Beta{{.Service}}().List(ctx, filter.None)
|
|
{{- else}}
|
|
objs, err := mock.Beta{{.Service}}().List(ctx, location, filter.None)
|
|
{{- end}}
|
|
if err != nil {
|
|
t.Errorf("Beta{{.Service}}().List(%v, %v, %v) = %v, %v; want _, nil", ctx, location, filter.None, objs, err)
|
|
} else {
|
|
got := map[string]bool{}
|
|
for _, obj := range objs {
|
|
got[obj.Name] = true
|
|
}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("Beta{{.Service}}().List(); got %+v, want %+v", got, want)
|
|
}
|
|
}
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasGA}}{{- if .GA.GenerateList}}
|
|
{
|
|
{{- if .GA.KeyIsGlobal }}
|
|
objs, err := mock.{{.Service}}().List(ctx, filter.None)
|
|
{{- else}}
|
|
objs, err := mock.{{.Service}}().List(ctx, location, filter.None)
|
|
{{- end}}
|
|
if err != nil {
|
|
t.Errorf("{{.Service}}().List(%v, %v, %v) = %v, %v; want _, nil", ctx, location, filter.None, objs, err)
|
|
} else {
|
|
got := map[string]bool{}
|
|
for _, obj := range objs {
|
|
got[obj.Name] = true
|
|
}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("{{.Service}}().List(); got %+v, want %+v", got, want)
|
|
}
|
|
}
|
|
}
|
|
{{- end}}{{- end}}
|
|
|
|
// Delete across versions.
|
|
{{- if .HasAlpha}}{{- if .Alpha.GenerateDelete}}
|
|
if err := mock.Alpha{{.Service}}().Delete(ctx, keyAlpha); err != nil {
|
|
t.Errorf("Alpha{{.Service}}().Delete(%v, %v) = %v; want nil", ctx, keyAlpha, err)
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasBeta}}{{- if .Beta.GenerateDelete}}
|
|
if err := mock.Beta{{.Service}}().Delete(ctx, keyBeta); err != nil {
|
|
t.Errorf("Beta{{.Service}}().Delete(%v, %v) = %v; want nil", ctx, keyBeta, err)
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasGA}}{{- if .GA.GenerateDelete}}
|
|
if err := mock.{{.Service}}().Delete(ctx, keyGA); err != nil {
|
|
t.Errorf("{{.Service}}().Delete(%v, %v) = %v; want nil", ctx, keyGA, err)
|
|
}
|
|
{{- end}}{{- end}}
|
|
|
|
// Delete not found.
|
|
{{- if .HasAlpha}}{{- if .Alpha.GenerateDelete}}
|
|
if err := mock.Alpha{{.Service}}().Delete(ctx, keyAlpha); err == nil {
|
|
t.Errorf("Alpha{{.Service}}().Delete(%v, %v) = nil; want error", ctx, keyAlpha)
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasBeta}}{{- if .Beta.GenerateDelete}}
|
|
if err := mock.Beta{{.Service}}().Delete(ctx, keyBeta); err == nil {
|
|
t.Errorf("Beta{{.Service}}().Delete(%v, %v) = nil; want error", ctx, keyBeta)
|
|
}
|
|
{{- end}}{{- end}}
|
|
{{- if .HasGA}}{{- if .GA.GenerateDelete}}
|
|
if err := mock.{{.Service}}().Delete(ctx, keyGA); err == nil {
|
|
t.Errorf("{{.Service}}().Delete(%v, %v) = nil; want error", ctx, keyGA)
|
|
}
|
|
{{- end}}{{- end}}
|
|
}
|
|
`
|
|
tmpl := template.Must(template.New("unittest").Parse(text))
|
|
for _, sg := range meta.SortedServicesGroups {
|
|
if err := tmpl.Execute(wr, sg); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func genUnitTestResourceIDConversion(wr io.Writer) {
|
|
const text = `
|
|
func TestResourceIDConversion(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for _, id := range []*ResourceID{
|
|
{{- range .Groups}}
|
|
{{- with .ServiceInfo}}
|
|
{{- if .KeyIsProject}}
|
|
New{{.Service}}ResourceID("my-{{.Resource}}-resource"),
|
|
{{- else}}
|
|
{{- if .KeyIsGlobal}}
|
|
New{{.Service}}ResourceID("some-project", "my-{{.Resource}}-resource"),
|
|
{{- end}}
|
|
{{- if .KeyIsRegional}}
|
|
New{{.Service}}ResourceID("some-project", "us-central1", "my-{{.Resource}}-resource"),
|
|
{{- end}}
|
|
{{- if .KeyIsZonal}}
|
|
New{{.Service}}ResourceID("some-project", "us-east1-b", "my-{{.Resource}}-resource"),
|
|
{{- end -}}
|
|
{{end -}}
|
|
{{end -}}
|
|
{{end}}
|
|
} {
|
|
t.Run(id.Resource, func(t *testing.T) {
|
|
// Test conversion to and from full URL.
|
|
fullURL := id.SelfLink(meta.VersionGA)
|
|
parsedID, err := ParseResourceURL(fullURL)
|
|
if err != nil {
|
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", fullURL, err)
|
|
}
|
|
if !reflect.DeepEqual(id, parsedID) {
|
|
t.Errorf("SelfLink(%+v) -> ParseResourceURL(%s) = %+v, want original ID", id, fullURL, parsedID)
|
|
}
|
|
|
|
// Test conversion to and from relative resource name.
|
|
relativeName := id.RelativeResourceName()
|
|
parsedID, err = ParseResourceURL(relativeName)
|
|
if err != nil {
|
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", relativeName, err)
|
|
}
|
|
if !reflect.DeepEqual(id, parsedID) {
|
|
t.Errorf("RelativeResourceName(%+v) -> ParseResourceURL(%s) = %+v, want original ID", id, relativeName, parsedID)
|
|
}
|
|
|
|
// Do not test ResourcePath for projects.
|
|
if id.Resource == "projects" {
|
|
return
|
|
}
|
|
|
|
// Test conversion to and from resource path.
|
|
resourcePath := id.ResourcePath()
|
|
parsedID, err = ParseResourceURL(resourcePath)
|
|
if err != nil {
|
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", resourcePath, err)
|
|
}
|
|
id.ProjectID = ""
|
|
if !reflect.DeepEqual(id, parsedID) {
|
|
t.Errorf("ResourcePath(%+v) -> ParseResourceURL(%s) = %+v, want %+v", id, resourcePath, parsedID, id)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
`
|
|
data := struct {
|
|
Groups []*meta.ServiceGroup
|
|
}{meta.SortedServicesGroups}
|
|
tmpl := template.Must(template.New("unittest-resourceIDs").Parse(text))
|
|
if err := tmpl.Execute(wr, data); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
out := &bytes.Buffer{}
|
|
|
|
switch flags.mode {
|
|
case "src":
|
|
genHeader(out)
|
|
genStubs(out)
|
|
genTypes(out)
|
|
genResourceIDs(out)
|
|
case "test":
|
|
genUnitTestHeader(out)
|
|
genUnitTestServices(out)
|
|
genUnitTestResourceIDConversion(out)
|
|
default:
|
|
log.Fatalf("Invalid -mode: %q", flags.mode)
|
|
}
|
|
|
|
if flags.gofmt {
|
|
fmt.Print(gofmtContent(out))
|
|
} else {
|
|
fmt.Print(out.String())
|
|
}
|
|
}
|