예제 #1
0
func packageForGroup(gv unversioned.GroupVersion, typeList []*types.Type, packageBasePath string, srcTreePath string, boilerplate []byte, generatedBy string) generator.Package {
	outputPackagePath := filepath.Join(packageBasePath, gv.Group, gv.Version)
	return &generator.DefaultPackage{
		PackageName: gv.Version,
		PackagePath: outputPackagePath,
		HeaderText:  boilerplate,
		PackageDocumentation: []byte(
			generatedBy +
				`// This package has the automatically generated typed clients.
`),
		// GeneratorFunc returns a list of generators. Each generator makes a
		// single file.
		GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
			generators = []generator.Generator{
				// Always generate a "doc.go" file.
				generator.DefaultGen{OptionalName: "doc"},
			}
			// Since we want a file per type that we generate a client for, we
			// have to provide a function for this.
			for _, t := range typeList {
				generators = append(generators, &genClientForType{
					DefaultGen: generator.DefaultGen{
						OptionalName: strings.ToLower(c.Namers["private"].Name(t)),
					},
					outputPackage: outputPackagePath,
					group:         normalization.BeforeFirstDot(gv.Group),
					typeToMatch:   t,
					imports:       generator.NewImportTracker(),
				})
			}

			generators = append(generators, &genGroup{
				DefaultGen: generator.DefaultGen{
					OptionalName: normalization.BeforeFirstDot(gv.Group) + "_client",
				},
				outputPackage: outputPackagePath,
				group:         gv.Group,
				version:       gv.Version,
				types:         typeList,
				imports:       generator.NewImportTracker(),
			})

			expansionFileName := "generated_expansion"
			// To avoid overriding user's manual modification, only generate the expansion file if it doesn't exist.
			if _, err := os.Stat(filepath.Join(srcTreePath, outputPackagePath, expansionFileName+".go")); os.IsNotExist(err) {
				generators = append(generators, &genExpansion{
					DefaultGen: generator.DefaultGen{
						OptionalName: expansionFileName,
					},
					types: typeList,
				})
			}

			return generators
		},
		FilterFunc: func(c *generator.Context, t *types.Type) bool {
			return types.ExtractCommentTags("+", t.SecondClosestCommentLines)["genclient"] == "true"
		},
	}
}
예제 #2
0
func packageForGroup(gv unversioned.GroupVersion, typeList []*types.Type, packageBasePath string, apiPath string, srcTreePath string, inputPath string, boilerplate []byte, generatedBy string) generator.Package {
	outputPackagePath := filepath.Join(packageBasePath, gv.Group, gv.Version)
	return &generator.DefaultPackage{
		PackageName: gv.Version,
		PackagePath: outputPackagePath,
		HeaderText:  boilerplate,
		PackageDocumentation: []byte(
			generatedBy +
				`// This package has the automatically generated typed clients.
`),
		// GeneratorFunc returns a list of generators. Each generator makes a
		// single file.
		GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
			generators = []generator.Generator{
				// Always generate a "doc.go" file.
				generator.DefaultGen{OptionalName: "doc"},
			}
			// Since we want a file per type that we generate a client for, we
			// have to provide a function for this.
			for _, t := range typeList {
				generators = append(generators, &genClientForType{
					DefaultGen: generator.DefaultGen{
						OptionalName: strings.ToLower(c.Namers["private"].Name(t)),
					},
					outputPackage: outputPackagePath,
					group:         normalization.BeforeFirstDot(gv.Group),
					typeToMatch:   t,
					imports:       generator.NewImportTracker(),
				})
			}

			generators = append(generators, &genGroup{
				DefaultGen: generator.DefaultGen{
					OptionalName: normalization.BeforeFirstDot(gv.Group) + "_client",
				},
				outputPackage: outputPackagePath,
				inputPacakge:  inputPath,
				group:         gv.Group,
				version:       gv.Version,
				apiPath:       apiPath,
				types:         typeList,
				imports:       generator.NewImportTracker(),
			})

			expansionFileName := "generated_expansion"
			generators = append(generators, &genExpansion{
				groupPath: filepath.Join(srcTreePath, outputPackagePath),
				DefaultGen: generator.DefaultGen{
					OptionalName: expansionFileName,
				},
				types: typeList,
			})

			return generators
		},
		FilterFunc: func(c *generator.Context, t *types.Type) bool {
			return extractBoolTagOrDie("genclient", t.SecondClosestCommentLines) == true
		},
	}
}
예제 #3
0
func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	const pkgRESTClient = "k8s.io/kubernetes/pkg/client/restclient"
	const pkgRegistered = "k8s.io/kubernetes/pkg/apimachinery/registered"
	const pkgAPI = "k8s.io/kubernetes/pkg/api"
	apiPath := func(group string) string {
		if group == "core" {
			return `"/api"`
		}
		return `"/apis"`
	}

	canonize := func(group string) string {
		if group == "core" {
			return ""
		}
		return group
	}

	m := map[string]interface{}{
		"group":                      normalization.BeforeFirstDot(g.group),
		"Group":                      namer.IC(normalization.BeforeFirstDot(g.group)),
		"canonicalGroup":             canonize(g.group),
		"types":                      g.types,
		"Config":                     c.Universe.Type(types.Name{Package: pkgRESTClient, Name: "Config"}),
		"DefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: pkgRESTClient, Name: "DefaultKubernetesUserAgent"}),
		"RESTClient":                 c.Universe.Type(types.Name{Package: pkgRESTClient, Name: "RESTClient"}),
		"RESTClientFor":              c.Universe.Function(types.Name{Package: pkgRESTClient, Name: "RESTClientFor"}),
		"latestGroup":                c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "Group"}),
		"GroupOrDie":                 c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "GroupOrDie"}),
		"apiPath":                    apiPath(g.group),
		"codecs":                     c.Universe.Variable(types.Name{Package: pkgAPI, Name: "Codecs"}),
	}
	sw.Do(groupInterfaceTemplate, m)
	sw.Do(groupClientTemplate, m)
	for _, t := range g.types {
		wrapper := map[string]interface{}{
			"type":  t,
			"Group": namer.IC(normalization.BeforeFirstDot(g.group)),
		}
		namespaced := !(types.ExtractCommentTags("+", t.SecondClosestCommentLines)["nonNamespaced"] == "true")
		if namespaced {
			sw.Do(getterImplNamespaced, wrapper)
		} else {
			sw.Do(getterImplNonNamespaced, wrapper)

		}
	}
	sw.Do(newClientForConfigTemplate, m)
	sw.Do(newClientForConfigOrDieTemplate, m)
	sw.Do(newClientForRESTClientTemplate, m)
	sw.Do(setClientDefaultsTemplate, m)

	return sw.Error()
}
예제 #4
0
func PackageForGroup(gv unversioned.GroupVersion, typeList []*types.Type, packageBasePath string, srcTreePath string, inputPath string, boilerplate []byte, generatedBy string) generator.Package {
	outputPackagePath := filepath.Join(packageBasePath, gv.Group, gv.Version, "fake")
	// TODO: should make this a function, called by here and in client-generator.go
	realClientPath := filepath.Join(packageBasePath, gv.Group, gv.Version)
	return &generator.DefaultPackage{
		PackageName: "fake",
		PackagePath: outputPackagePath,
		HeaderText:  boilerplate,
		PackageDocumentation: []byte(
			generatedBy +
				`// Package fake has the automatically generated clients.
`),
		// GeneratorFunc returns a list of generators. Each generator makes a
		// single file.
		GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
			generators = []generator.Generator{
				// Always generate a "doc.go" file.
				generator.DefaultGen{OptionalName: "doc"},
			}
			// Since we want a file per type that we generate a client for, we
			// have to provide a function for this.
			for _, t := range typeList {
				generators = append(generators, &genFakeForType{
					DefaultGen: generator.DefaultGen{
						OptionalName: "fake_" + strings.ToLower(c.Namers["private"].Name(t)),
					},
					outputPackage: outputPackagePath,
					group:         normalization.BeforeFirstDot(gv.Group),
					inputPackage:  inputPath,
					version:       gv.Version,
					typeToMatch:   t,
					imports:       generator.NewImportTracker(),
				})
			}

			generators = append(generators, &genFakeForGroup{
				DefaultGen: generator.DefaultGen{
					OptionalName: "fake_" + normalization.BeforeFirstDot(gv.Group) + "_client",
				},
				outputPackage:  outputPackagePath,
				realClientPath: realClientPath,
				group:          normalization.BeforeFirstDot(gv.Group),
				types:          typeList,
				imports:        generator.NewImportTracker(),
			})
			return generators
		},
		FilterFunc: func(c *generator.Context, t *types.Type) bool {
			return types.ExtractCommentTags("+", t.SecondClosestCommentLines)["genclient"] == "true"
		},
	}
}
예제 #5
0
func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	// TODO: We actually don't need any type information to generate the clientset,
	// perhaps we can adapt the go2ild framework to this kind of usage.
	sw := generator.NewSnippetWriter(w, c, "$", "$")

	sw.Do(common, nil)

	sw.Do(checkImpl, nil)

	type arg struct {
		Group       string
		PackageName string
	}
	allGroups := []arg{}
	for _, gv := range g.groupVersions {
		group := normalization.BeforeFirstDot(normalization.Group(gv.Group))
		version := normalization.Version(gv.Version)
		allGroups = append(allGroups, arg{namer.IC(group), version + group})
	}

	for _, g := range allGroups {
		sw.Do(clientsetInterfaceImplTemplate, g)
	}

	return sw.Error()
}
예제 #6
0
func (g *genClientset) Imports(c *generator.Context) (imports []string) {
	imports = append(imports, g.imports.ImportLines()...)
	for _, gv := range g.groupVersions {
		group := normalization.Group(gv.Group)
		version := normalization.Version(gv.Version)
		undotted_group := normalization.BeforeFirstDot(group)
		typedClientPath := filepath.Join(g.typedClientPath, group, version)
		imports = append(imports, fmt.Sprintf("%s%s \"%s\"", version, undotted_group, typedClientPath))
		fakeTypedClientPath := filepath.Join(typedClientPath, "fake")
		imports = append(imports, fmt.Sprintf("fake%s%s \"%s\"", version, undotted_group, fakeTypedClientPath))
	}
	// the package that has the clientset Interface
	imports = append(imports, fmt.Sprintf("clientset \"%s\"", g.clientsetPath))
	// imports for the code in commonTemplate
	imports = append(imports,
		"k8s.io/kubernetes/pkg/api",
		"k8s.io/kubernetes/pkg/apimachinery/registered",
		"k8s.io/kubernetes/pkg/client/testing/core",
		"k8s.io/kubernetes/pkg/client/typed/discovery",
		"fakediscovery \"k8s.io/kubernetes/pkg/client/typed/discovery/fake\"",
		"k8s.io/kubernetes/pkg/runtime",
		"k8s.io/kubernetes/pkg/watch",
	)

	return
}
func (g *genClientset) Imports(c *generator.Context) (imports []string) {
	imports = append(imports, g.imports.ImportLines()...)
	for _, gv := range g.groupVersions {
		group := normalization.Group(gv.Group)
		version := normalization.Version(gv.Version)
		typedClientPath := filepath.Join(g.typedClientPath, group, version)
		group = normalization.BeforeFirstDot(group)
		imports = append(imports, fmt.Sprintf("%s%s \"%s\"", version, group, typedClientPath))
		imports = append(imports, "github.com/golang/glog")
	}
	return
}
예제 #8
0
func (g *genClientset) Imports(c *generator.Context) (imports []string) {
	imports = append(imports, g.imports.ImportLines()...)
	for _, gv := range g.groupVersions {
		group := normalization.Group(gv.Group)
		version := normalization.Version(gv.Version)
		typedClientPath := filepath.Join(g.typedClientPath, group, version)
		group = normalization.BeforeFirstDot(group)
		imports = append(imports, fmt.Sprintf("%s%s \"%s\"", version, group, typedClientPath))
	}
	imports = append(imports, "github.com/golang/glog")
	imports = append(imports, "k8s.io/kubernetes/pkg/util/flowcontrol")
	// import solely to initialize client auth plugins.
	imports = append(imports, "_ \"k8s.io/kubernetes/plugin/pkg/client/auth\"")
	return
}
예제 #9
0
func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	// TODO: We actually don't need any type information to generate the clientset,
	// perhaps we can adapt the go2ild framework to this kind of usage.
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	const pkgDiscovery = "k8s.io/kubernetes/pkg/client/typed/discovery"
	const pkgRESTClient = "k8s.io/kubernetes/pkg/client/restclient"

	type arg struct {
		Group       string
		PackageName string
	}

	allGroups := []arg{}
	for _, gv := range g.groupVersions {
		group := normalization.BeforeFirstDot(normalization.Group(gv.Group))
		version := normalization.Version(gv.Version)
		allGroups = append(allGroups, arg{namer.IC(group), version + group})
	}

	m := map[string]interface{}{
		"allGroups":                        allGroups,
		"Config":                           c.Universe.Type(types.Name{Package: pkgRESTClient, Name: "Config"}),
		"DefaultKubernetesUserAgent":       c.Universe.Function(types.Name{Package: pkgRESTClient, Name: "DefaultKubernetesUserAgent"}),
		"RESTClient":                       c.Universe.Type(types.Name{Package: pkgRESTClient, Name: "RESTClient"}),
		"DiscoveryInterface":               c.Universe.Type(types.Name{Package: pkgDiscovery, Name: "DiscoveryInterface"}),
		"DiscoveryClient":                  c.Universe.Type(types.Name{Package: pkgDiscovery, Name: "DiscoveryClient"}),
		"NewDiscoveryClientForConfig":      c.Universe.Function(types.Name{Package: pkgDiscovery, Name: "NewDiscoveryClientForConfig"}),
		"NewDiscoveryClientForConfigOrDie": c.Universe.Function(types.Name{Package: pkgDiscovery, Name: "NewDiscoveryClientForConfigOrDie"}),
		"NewDiscoveryClient":               c.Universe.Function(types.Name{Package: pkgDiscovery, Name: "NewDiscoveryClient"}),
	}
	sw.Do(clientsetInterfaceTemplate, m)
	sw.Do(clientsetTemplate, m)
	for _, g := range allGroups {
		sw.Do(clientsetInterfaceImplTemplate, g)
	}
	sw.Do(getDiscoveryTemplate, m)
	sw.Do(newClientsetForConfigTemplate, m)
	sw.Do(newClientsetForConfigOrDieTemplate, m)
	sw.Do(newClientsetForRESTClientTemplate, m)

	return sw.Error()
}
예제 #10
0
func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
	sw := generator.NewSnippetWriter(w, c, "$", "$")
	const pkgRESTClient = "k8s.io/kubernetes/pkg/client/restclient"
	const pkgRegistered = "k8s.io/kubernetes/pkg/apimachinery/registered"
	const pkgAPI = "k8s.io/kubernetes/pkg/api"
	const pkgSerializer = "k8s.io/kubernetes/pkg/runtime/serializer"
	apiPath := func(group string) string {
		if len(g.apiPath) > 0 {
			return `"` + g.apiPath + `"`
		}
		if group == "core" {
			return `"/api"`
		}
		return `"/apis"`
	}

	groupName := g.group
	if g.group == "core" {
		groupName = ""
	}
	// allow user to define a group name that's different from the one parsed from the directory.
	p := c.Universe.Package(g.inputPacakge)
	if override := types.ExtractCommentTags("+", p.DocComments)["groupName"]; override != nil {
		groupName = override[0]
	}

	m := map[string]interface{}{
		"group":                      normalization.BeforeFirstDot(g.group),
		"Group":                      namer.IC(normalization.BeforeFirstDot(g.group)),
		"groupName":                  groupName,
		"types":                      g.types,
		"Config":                     c.Universe.Type(types.Name{Package: pkgRESTClient, Name: "Config"}),
		"DefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: pkgRESTClient, Name: "DefaultKubernetesUserAgent"}),
		"RESTClientInterface":        c.Universe.Type(types.Name{Package: pkgRESTClient, Name: "Interface"}),
		"RESTClientFor":              c.Universe.Function(types.Name{Package: pkgRESTClient, Name: "RESTClientFor"}),
		"latestGroup":                c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "Group"}),
		"GroupOrDie":                 c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "GroupOrDie"}),
		"apiPath":                    apiPath(g.group),
		"codecs":                     c.Universe.Variable(types.Name{Package: pkgAPI, Name: "Codecs"}),
		"directCodecFactory":         c.Universe.Variable(types.Name{Package: pkgSerializer, Name: "DirectCodecFactory"}),
		"Errorf":                     c.Universe.Variable(types.Name{Package: "fmt", Name: "Errorf"}),
	}
	sw.Do(groupInterfaceTemplate, m)
	sw.Do(groupClientTemplate, m)
	for _, t := range g.types {
		wrapper := map[string]interface{}{
			"type":  t,
			"Group": namer.IC(normalization.BeforeFirstDot(g.group)),
		}
		namespaced := !extractBoolTagOrDie("nonNamespaced", t.SecondClosestCommentLines)
		if namespaced {
			sw.Do(getterImplNamespaced, wrapper)
		} else {
			sw.Do(getterImplNonNamespaced, wrapper)

		}
	}
	sw.Do(newClientForConfigTemplate, m)
	sw.Do(newClientForConfigOrDieTemplate, m)
	sw.Do(newClientForRESTClientTemplate, m)
	if g.version == "unversioned" {
		sw.Do(setInternalVersionClientDefaultsTemplate, m)
	} else {
		sw.Do(setClientDefaultsTemplate, m)
	}
	sw.Do(getRESTClient, m)

	return sw.Error()
}