mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
Add lister-gen
This commit is contained in:
parent
f67ecd73f7
commit
f85ac9023a
1
cmd/libs/go2idl/lister-gen/.import-restrictions
Normal file
1
cmd/libs/go2idl/lister-gen/.import-restrictions
Normal file
@ -0,0 +1 @@
|
||||
{}
|
345
cmd/libs/go2idl/lister-gen/generators/lister.go
Normal file
345
cmd/libs/go2idl/lister-gen/generators/lister.go
Normal file
@ -0,0 +1,345 @@
|
||||
/*
|
||||
Copyright 2016 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.
|
||||
*/
|
||||
|
||||
package generators
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
clientgentypes "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/types"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// NameSystems returns the name system used by the generators in this package.
|
||||
func NameSystems() namer.NameSystems {
|
||||
pluralExceptions := map[string]string{
|
||||
"Endpoints": "Endpoints",
|
||||
}
|
||||
return namer.NameSystems{
|
||||
"public": namer.NewPublicNamer(0),
|
||||
"private": namer.NewPrivateNamer(0),
|
||||
"raw": namer.NewRawNamer("", nil),
|
||||
"publicPlural": namer.NewPublicPluralNamer(pluralExceptions),
|
||||
"allLowercasePlural": namer.NewAllLowercasePluralNamer(pluralExceptions),
|
||||
"lowercaseSingular": &lowercaseSingularNamer{},
|
||||
}
|
||||
}
|
||||
|
||||
// lowercaseSingularNamer implements Namer
|
||||
type lowercaseSingularNamer struct{}
|
||||
|
||||
// Name returns t's name in all lowercase.
|
||||
func (n *lowercaseSingularNamer) Name(t *types.Type) string {
|
||||
return strings.ToLower(t.Name.Name)
|
||||
}
|
||||
|
||||
// DefaultNameSystem returns the default name system for ordering the types to be
|
||||
// processed by the generators in this package.
|
||||
func DefaultNameSystem() string {
|
||||
return "public"
|
||||
}
|
||||
|
||||
// generatedBy returns information about the arguments used to invoke
|
||||
// lister-gen.
|
||||
func generatedBy() string {
|
||||
var cmdArgs string
|
||||
pflag.VisitAll(func(f *pflag.Flag) {
|
||||
if !f.Changed || f.Name == "verify-only" {
|
||||
return
|
||||
}
|
||||
cmdArgs += fmt.Sprintf("--%s=%s ", f.Name, f.Value)
|
||||
})
|
||||
return fmt.Sprintf("\n// This file was automatically generated by lister-gen with arguments: %s\n\n", cmdArgs)
|
||||
}
|
||||
|
||||
// Packages makes the client package definition.
|
||||
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
|
||||
boilerplate, err := arguments.LoadGoBoilerplate()
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed loading boilerplate: %v", err)
|
||||
}
|
||||
|
||||
boilerplate = append(boilerplate, []byte(generatedBy())...)
|
||||
|
||||
var packageList generator.Packages
|
||||
for _, inputDir := range arguments.InputDirs {
|
||||
p := context.Universe.Package(inputDir)
|
||||
|
||||
objectMeta, err := objectMetaForPackage(p)
|
||||
if err != nil {
|
||||
glog.Fatal(err)
|
||||
}
|
||||
if objectMeta == nil {
|
||||
// no types in this package had genclient
|
||||
continue
|
||||
}
|
||||
|
||||
var gv clientgentypes.GroupVersion
|
||||
|
||||
if isInternal(objectMeta) {
|
||||
lastSlash := strings.LastIndex(p.Path, "/")
|
||||
if lastSlash == -1 {
|
||||
glog.Fatalf("error constructing internal group version for package %q", p.Path)
|
||||
}
|
||||
gv.Group = clientgentypes.Group(p.Path[lastSlash+1:])
|
||||
} else {
|
||||
parts := strings.Split(p.Path, "/")
|
||||
gv.Group = clientgentypes.Group(parts[len(parts)-2])
|
||||
gv.Version = clientgentypes.Version(parts[len(parts)-1])
|
||||
}
|
||||
|
||||
packageList = append(packageList, &generator.DefaultPackage{
|
||||
PackageName: strings.ToLower(gv.Version.NonEmpty()),
|
||||
PackagePath: filepath.Join(arguments.OutputPackagePath, strings.ToLower(gv.Group.NonEmpty()), strings.ToLower(gv.Version.NonEmpty())),
|
||||
HeaderText: boilerplate,
|
||||
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
|
||||
for _, t := range p.Types {
|
||||
// filter out types which dont have genclient=true.
|
||||
if extractBoolTagOrDie("genclient", t.SecondClosestCommentLines) == false {
|
||||
continue
|
||||
}
|
||||
generators = append(generators, &listerGenerator{
|
||||
DefaultGen: generator.DefaultGen{
|
||||
OptionalName: arguments.OutputFileBaseName + "." + strings.ToLower(t.Name.Name),
|
||||
},
|
||||
outputPackage: arguments.OutputPackagePath,
|
||||
groupVersion: gv,
|
||||
typeToGenerate: t,
|
||||
imports: generator.NewImportTracker(),
|
||||
objectMeta: objectMeta,
|
||||
})
|
||||
}
|
||||
return generators
|
||||
},
|
||||
FilterFunc: func(c *generator.Context, t *types.Type) bool {
|
||||
// piggy-back on types that are tagged for client-gen
|
||||
return extractBoolTagOrDie("genclient", t.SecondClosestCommentLines) == true
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return packageList
|
||||
}
|
||||
|
||||
// objectMetaForPackage returns the type of ObjectMeta used by package p.
|
||||
func objectMetaForPackage(p *types.Package) (*types.Type, error) {
|
||||
generatingForPackage := false
|
||||
for _, t := range p.Types {
|
||||
// filter out types which dont have genclient=true.
|
||||
if extractBoolTagOrDie("genclient", t.SecondClosestCommentLines) == false {
|
||||
continue
|
||||
}
|
||||
generatingForPackage = true
|
||||
for _, member := range t.Members {
|
||||
if member.Name == "ObjectMeta" {
|
||||
return member.Type, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if generatingForPackage {
|
||||
return nil, fmt.Errorf("unable to find ObjectMeta for any types in package %s", p.Path)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// isInternal returns true if t's package is k8s.io/kubernetes/pkg/api.
|
||||
func isInternal(t *types.Type) bool {
|
||||
return t.Name.Package == "k8s.io/kubernetes/pkg/api"
|
||||
}
|
||||
|
||||
// listerGenerator produces a file of listers for a given GroupVersion and
|
||||
// type.
|
||||
type listerGenerator struct {
|
||||
generator.DefaultGen
|
||||
outputPackage string
|
||||
groupVersion clientgentypes.GroupVersion
|
||||
typeToGenerate *types.Type
|
||||
imports namer.ImportTracker
|
||||
objectMeta *types.Type
|
||||
}
|
||||
|
||||
var _ generator.Generator = &listerGenerator{}
|
||||
|
||||
func (g *listerGenerator) Filter(c *generator.Context, t *types.Type) bool {
|
||||
return t == g.typeToGenerate
|
||||
}
|
||||
|
||||
func (g *listerGenerator) Namers(c *generator.Context) namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer(g.outputPackage, g.imports),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *listerGenerator) Imports(c *generator.Context) (imports []string) {
|
||||
imports = append(imports, g.imports.ImportLines()...)
|
||||
imports = append(imports, "k8s.io/kubernetes/pkg/api/errors")
|
||||
imports = append(imports, "k8s.io/kubernetes/pkg/labels")
|
||||
// for Indexer
|
||||
imports = append(imports, "k8s.io/kubernetes/pkg/client/cache")
|
||||
return
|
||||
}
|
||||
|
||||
func (g *listerGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
|
||||
glog.V(5).Infof("processing type %v", t)
|
||||
m := map[string]interface{}{
|
||||
"group": g.groupVersion.Group.String(),
|
||||
"type": t,
|
||||
"objectMeta": g.objectMeta,
|
||||
}
|
||||
|
||||
namespaced := !extractBoolTagOrDie("nonNamespaced", t.SecondClosestCommentLines)
|
||||
if namespaced {
|
||||
sw.Do(typeListerInterface, m)
|
||||
} else {
|
||||
sw.Do(typeListerInterface_NonNamespaced, m)
|
||||
}
|
||||
|
||||
sw.Do(typeListerStruct, m)
|
||||
sw.Do(typeListerConstructor, m)
|
||||
sw.Do(typeLister_List, m)
|
||||
|
||||
if namespaced {
|
||||
sw.Do(typeLister_NamespaceLister, m)
|
||||
sw.Do(namespaceListerInterface, m)
|
||||
sw.Do(namespaceListerStruct, m)
|
||||
sw.Do(namespaceLister_List, m)
|
||||
sw.Do(namespaceLister_Get, m)
|
||||
} else {
|
||||
sw.Do(typeLister_NonNamespacedGet, m)
|
||||
}
|
||||
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
var typeListerInterface = `
|
||||
// $.type|public$Lister helps list $.type|publicPlural$.
|
||||
type $.type|public$Lister interface {
|
||||
// List lists all $.type|publicPlural$ in the indexer.
|
||||
List(selector labels.Selector) (ret []*$.type|raw$, err error)
|
||||
// $.type|publicPlural$ returns an object that can list and get $.type|publicPlural$.
|
||||
$.type|publicPlural$(namespace string) $.type|public$NamespaceLister
|
||||
}
|
||||
`
|
||||
|
||||
var typeListerInterface_NonNamespaced = `
|
||||
// $.type|public$Lister helps list $.type|publicPlural$.
|
||||
type $.type|public$Lister interface {
|
||||
// List lists all $.type|publicPlural$ in the indexer.
|
||||
List(selector labels.Selector) (ret []*$.type|raw$, err error)
|
||||
// Get retrieves the $.type|public$ from the index for a given name.
|
||||
Get(name string) (*$.type|raw$, error)
|
||||
}
|
||||
`
|
||||
|
||||
var typeListerStruct = `
|
||||
// $.type|private$Lister implements the $.type|public$Lister interface.
|
||||
type $.type|private$Lister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
`
|
||||
|
||||
var typeListerConstructor = `
|
||||
// New$.type|public$Lister returns a new $.type|public$Lister.
|
||||
func New$.type|public$Lister(indexer cache.Indexer) $.type|public$Lister {
|
||||
return &$.type|private$Lister{indexer: indexer}
|
||||
}
|
||||
`
|
||||
|
||||
var typeLister_List = `
|
||||
// List lists all $.type|publicPlural$ in the indexer.
|
||||
func (s *$.type|private$Lister) List(selector labels.Selector) (ret []*$.type|raw$, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*$.type|raw$))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
`
|
||||
|
||||
var typeLister_NamespaceLister = `
|
||||
// $.type|publicPlural$ returns an object that can list and get $.type|publicPlural$.
|
||||
func (s *$.type|private$Lister) $.type|publicPlural$(namespace string) $.type|public$NamespaceLister {
|
||||
return $.type|private$NamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
`
|
||||
|
||||
var typeLister_NonNamespacedGet = `
|
||||
// Get retrieves the $.type|public$ from the index for a given name.
|
||||
func (s *$.type|private$Lister) Get(name string) (*$.type|raw$, error) {
|
||||
key := &$.type|raw${ObjectMeta: $.objectMeta|raw${Name: name}}
|
||||
obj, exists, err := s.indexer.Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound($.group$.Resource("$.type|lowercaseSingular$"), name)
|
||||
}
|
||||
return obj.(*$.type|raw$), nil
|
||||
}
|
||||
`
|
||||
|
||||
var namespaceListerInterface = `
|
||||
// $.type|public$NamespaceLister helps list and get $.type|publicPlural$.
|
||||
type $.type|public$NamespaceLister interface {
|
||||
// List lists all $.type|publicPlural$ in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*$.type|raw$, err error)
|
||||
// Get retrieves the $.type|public$ from the indexer for a given namespace and name.
|
||||
Get(name string) (*$.type|raw$, error)
|
||||
}
|
||||
`
|
||||
|
||||
var namespaceListerStruct = `
|
||||
// $.type|private$NamespaceLister implements the $.type|public$NamespaceLister
|
||||
// interface.
|
||||
type $.type|private$NamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
`
|
||||
|
||||
var namespaceLister_List = `
|
||||
// List lists all $.type|publicPlural$ in the indexer for a given namespace.
|
||||
func (s $.type|private$NamespaceLister) List(selector labels.Selector) (ret []*$.type|raw$, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*$.type|raw$))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
`
|
||||
|
||||
var namespaceLister_Get = `
|
||||
// Get retrieves the $.type|public$ from the indexer for a given namespace and name.
|
||||
func (s $.type|private$NamespaceLister) Get(name string) (*$.type|raw$, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound($.group$.Resource("$.type|lowercaseSingular$"), name)
|
||||
}
|
||||
return obj.(*$.type|raw$), nil
|
||||
}
|
||||
`
|
33
cmd/libs/go2idl/lister-gen/generators/tags.go
Normal file
33
cmd/libs/go2idl/lister-gen/generators/tags.go
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2016 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.
|
||||
*/
|
||||
|
||||
package generators
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if
|
||||
// it exists, the value is boolean. If the tag did not exist, it returns
|
||||
// false.
|
||||
func extractBoolTagOrDie(key string, lines []string) bool {
|
||||
val, err := types.ExtractSingleBoolCommentTag("+", key, false, lines)
|
||||
if err != nil {
|
||||
glog.Fatalf(err.Error())
|
||||
}
|
||||
return val
|
||||
}
|
48
cmd/libs/go2idl/lister-gen/main.go
Normal file
48
cmd/libs/go2idl/lister-gen/main.go
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright 2016 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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/kubernetes/cmd/libs/go2idl/lister-gen/generators"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func main() {
|
||||
arguments := &args.GeneratorArgs{
|
||||
OutputBase: args.DefaultSourceTree(),
|
||||
GoHeaderFilePath: filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt"),
|
||||
GeneratedBuildTag: "ignore_autogenerated",
|
||||
OutputFileBaseName: "zz_generated",
|
||||
OutputPackagePath: "k8s.io/kubernetes/pkg/client/listers",
|
||||
}
|
||||
arguments.AddFlags(pflag.CommandLine)
|
||||
|
||||
// Run it.
|
||||
if err := arguments.Execute(
|
||||
generators.NameSystems(),
|
||||
generators.DefaultNameSystem(),
|
||||
generators.Packages,
|
||||
); err != nil {
|
||||
glog.Fatalf("Error: %v", err)
|
||||
}
|
||||
glog.V(2).Info("Completed successfully.")
|
||||
}
|
@ -33,6 +33,7 @@ cmd/libs/go2idl/generator
|
||||
cmd/libs/go2idl/go-to-protobuf
|
||||
cmd/libs/go2idl/go-to-protobuf/protoc-gen-gogo
|
||||
cmd/libs/go2idl/import-boss
|
||||
cmd/libs/go2idl/lister-gen
|
||||
cmd/libs/go2idl/openapi-gen
|
||||
cmd/libs/go2idl/parser
|
||||
cmd/libs/go2idl/set-gen
|
||||
|
@ -26,11 +26,13 @@ kube::golang::setup_env
|
||||
BUILD_TARGETS=(
|
||||
cmd/libs/go2idl/client-gen
|
||||
cmd/libs/go2idl/set-gen
|
||||
cmd/libs/go2idl/lister-gen
|
||||
)
|
||||
make -C "${KUBE_ROOT}" WHAT="${BUILD_TARGETS[*]}"
|
||||
|
||||
clientgen=$(kube::util::find-binary "client-gen")
|
||||
setgen=$(kube::util::find-binary "set-gen")
|
||||
listergen=$(kube::util::find-binary "lister-gen")
|
||||
|
||||
# Please do not add any logic to this shell script. Add logic to the go code
|
||||
# that generates the set-gen program.
|
||||
@ -63,4 +65,18 @@ ${clientgen} --clientset-name=federation_internalclientset --clientset-path=k8s.
|
||||
${clientgen} --clientset-name=federation_release_1_5 --clientset-path=k8s.io/kubernetes/federation/client/clientset_generated --input="../../federation/apis/federation/v1beta1","api/v1","extensions/v1beta1" --included-types-overrides="api/v1/Service,api/v1/Namespace,extensions/v1beta1/ReplicaSet,api/v1/Secret,extensions/v1beta1/Ingress,extensions/v1beta1/Deployment,extensions/v1beta1/DaemonSet,api/v1/ConfigMap,api/v1/Event" "$@"
|
||||
${setgen} "$@"
|
||||
|
||||
LISTERGEN_APIS=(
|
||||
pkg/api
|
||||
pkg/api/v1
|
||||
$(
|
||||
cd ${KUBE_ROOT}
|
||||
find pkg/apis -name types.go | xargs dirname | sort
|
||||
)
|
||||
)
|
||||
|
||||
LISTERGEN_APIS=(${LISTERGEN_APIS[@]/#/k8s.io/kubernetes/})
|
||||
LISTERGEN_APIS=$(IFS=,; echo "${LISTERGEN_APIS[*]}")
|
||||
|
||||
${listergen} --input-dirs "${LISTERGEN_APIS}" "$@"
|
||||
|
||||
# You may add additional calls of code generators like set-gen above.
|
||||
|
Loading…
Reference in New Issue
Block a user