Skip to content

Commit

Permalink
Add support for specifying a CRD shortname with // +resource:path=foo…
Browse files Browse the repository at this point in the history
…s,shortName=f
  • Loading branch information
pwittrock committed Mar 20, 2018
1 parent db44749 commit 61a6891
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 112 deletions.
9 changes: 5 additions & 4 deletions cmd/internal/codegen/parse/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ type genUnversionedType struct {

func (b *APIs) parseAPIs() {
apis := &codegen.APIs{
Domain: b.Domain,
Package: b.APIsPkg,
Groups: map[string]*codegen.APIGroup{},
Rules: b.Rules,
Domain: b.Domain,
Package: b.APIsPkg,
Groups: map[string]*codegen.APIGroup{},
Rules: b.Rules,
Informers: b.Informers,
}

Expand Down Expand Up @@ -70,6 +70,7 @@ func (b *APIs) parseAPIs() {
StatusStrategy: resource.StatusStrategy,
Strategy: resource.Strategy,
NonNamespaced: resource.NonNamespaced,
ShortName: resource.ShortName,
}
apiVersion.Resources[kind] = apiResource
// Set the package for the api version
Expand Down
197 changes: 100 additions & 97 deletions cmd/internal/codegen/parse/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package parse
import (
"fmt"
"log"
"path/filepath"
"strings"

"github.com/kubernetes-sigs/kubebuilder/cmd/internal/codegen"
Expand Down Expand Up @@ -71,8 +70,9 @@ func (b *APIs) parseIndex() {

rt := parseResourceTag(b.getResourceTag(c))
r.Resource = rt.Resource
r.REST = rt.REST
r.Strategy = rt.Strategy
r.ShortName = rt.ShortName
//r.REST = rt.REST
//r.Strategy = rt.Strategy

// Copy the Status strategy to mirror the non-status strategy
r.StatusStrategy = strings.TrimSuffix(r.Strategy, "Strategy")
Expand All @@ -96,85 +96,86 @@ func (b *APIs) parseIndex() {
b.ByGroupKindVersion[r.Group][r.Kind][r.Version] = r
b.ByGroupVersionKind[r.Group][r.Version][r.Kind] = r

if !HasSubresource(c) {
continue
}
//if !HasSubresource(c) {
// continue
//}
r.Type = c
r.Subresources = b.getSubresources(r)
//r.Subresources = b.getSubresources(r)
}
}

func (b *APIs) getSubresources(c *codegen.APIResource) map[string]*codegen.APISubresource {
r := map[string]*codegen.APISubresource{}
subresources := b.getSubresourceTags(c.Type)

if len(subresources) == 0 {
// Not a subresource
return r
}
for _, subresource := range subresources {
// Parse the values for each subresource
tags := parseSubresourceTag(c, subresource)
sr := &codegen.APISubresource{
Kind: tags.Kind,
Request: tags.RequestKind,
Path: tags.Path,
REST: tags.REST,
Domain: b.Domain,
Version: c.Version,
Resource: c.Resource,
Group: c.Group,
}
if !b.isInPackage(tags) {
// Out of package Request types require an import and are prefixed with the
// package name - e.g. v1.Scale
sr.Request, sr.ImportPackage = b.getNameAndImport(tags)
}
if v, found := r[sr.Path]; found {
log.Fatalf("Multiple subresources registered for path %s: %v %v",
sr.Path, v, subresource)
}
r[sr.Path] = sr
}
return r
}
//func (b *APIs) getSubresources(c *codegen.APIResource) map[string]*codegen.APISubresource {
// r := map[string]*codegen.APISubresource{}
// subresources := b.getSubresourceTags(c.Type)
//
// if len(subresources) == 0 {
// // Not a subresource
// return r
// }
//for _, subresource := range subresources {
// // Parse the values for each subresource
// tags := parseSubresourceTag(c, subresource)
// sr := &codegen.APISubresource{
// Kind: tags.Kind,
// Request: tags.RequestKind,
// Path: tags.Path,
// REST: tags.REST,
// Domain: b.Domain,
// Version: c.Version,
// Resource: c.Resource,
// Group: c.Group,
// }
// if !b.isInPackage(tags) {
// // Out of package Request types require an import and are prefixed with the
// // package name - e.g. v1.Scale
// sr.Request, sr.ImportPackage = b.getNameAndImport(tags)
// }
// if v, found := r[sr.Path]; found {
// log.Fatalf("Multiple subresources registered for path %s: %v %v",
// sr.Path, v, subresource)
// }
// r[sr.Path] = sr
//}
// return r
//}

// subresourceTags contains the tags present in a "+subresource=" comment
type subresourceTags struct {
Path string
Kind string
RequestKind string
REST string
}

func (b *APIs) getSubresourceTags(c *types.Type) []string {
comments := Comments(c.CommentLines)
return comments.getTags("subresource", ":")
}
//type subresourceTags struct {
// Path string
// Kind string
// RequestKind string
// REST string
//}
//
//func (b *APIs) getSubresourceTags(c *types.Type) []string {
// comments := Comments(c.CommentLines)
// return comments.getTags("subresource", ":")
//}

// Returns true if the subresource Request type is in the same package as the resource type
func (b *APIs) isInPackage(tags subresourceTags) bool {
return !strings.Contains(tags.RequestKind, ".")
}

// GetNameAndImport converts
func (b *APIs) getNameAndImport(tags subresourceTags) (string, string) {
last := strings.LastIndex(tags.RequestKind, ".")
importPackage := tags.RequestKind[:last]

// Set the request kind to the struct name
tags.RequestKind = tags.RequestKind[last+1:]
// Find the package
pkg := filepath.Base(importPackage)
// Prefix the struct name with the package it is in
return strings.Join([]string{pkg, tags.RequestKind}, "."), importPackage
}
//func (b *APIs) isInPackage(tags subresourceTags) bool {
// return !strings.Contains(tags.RequestKind, ".")
//}
//
//// GetNameAndImport converts
//func (b *APIs) getNameAndImport(tags subresourceTags) (string, string) {
// last := strings.LastIndex(tags.RequestKind, ".")
// importPackage := tags.RequestKind[:last]
//
// // Set the request kind to the struct name
// tags.RequestKind = tags.RequestKind[last+1:]
// // Find the package
// pkg := filepath.Base(importPackage)
// // Prefix the struct name with the package it is in
// return strings.Join([]string{pkg, tags.RequestKind}, "."), importPackage
//}

// resourceTags contains the tags present in a "+resource=" comment
type resourceTags struct {
Resource string
REST string
Strategy string
Resource string
REST string
Strategy string
ShortName string
}

// ParseResourceTag parses the tags in a "+resource=" comment into a resourceTags struct
Expand All @@ -189,40 +190,42 @@ func parseResourceTag(tag string) resourceTags {
}
value := kv[1]
switch kv[0] {
case "rest":
result.REST = value
//case "rest":
// result.REST = value
case "path":
result.Resource = value
case "strategy":
result.Strategy = value
//case "strategy":
// result.Strategy = value
case "shortName":
result.ShortName = value
}
}
return result
}

// ParseSubresourceTag parses the tags in a "+subresource=" comment into a subresourceTags struct
func parseSubresourceTag(c *codegen.APIResource, tag string) subresourceTags {
result := subresourceTags{}
for _, elem := range strings.Split(tag, ",") {
kv := strings.Split(elem, "=")
if len(kv) != 2 {
log.Fatalf("// +subresource: tags must be key value pairs. Expected "+
"keys [request=<requestType>,rest=<restImplType>,path=<subresourcepath>] "+
"Got string: [%s]", tag)
}
value := kv[1]
switch kv[0] {
case "request":
result.RequestKind = value
case "rest":
result.REST = value
case "path":
// Strip the parent resource
result.Path = strings.Replace(value, c.Resource+"/", "", -1)
}
}
return result
}
//func parseSubresourceTag(c *codegen.APIResource, tag string) subresourceTags {
// result := subresourceTags{}
// for _, elem := range strings.Split(tag, ",") {
// kv := strings.Split(elem, "=")
// if len(kv) != 2 {
// log.Fatalf("// +subresource: tags must be key value pairs. Expected "+
// "keys [request=<requestType>,rest=<restImplType>,path=<subresourcepath>] "+
// "Got string: [%s]", tag)
// }
// value := kv[1]
// switch kv[0] {
// case "request":
// result.RequestKind = value
// case "rest":
// result.REST = value
// case "path":
// // Strip the parent resource
// result.Path = strings.Replace(value, c.Resource+"/", "", -1)
// }
// }
// return result
//}

// getResourceTag returns the value of the "+resource=" comment tag
func (b *APIs) getResourceTag(c *types.Type) string {
Expand Down
4 changes: 4 additions & 0 deletions cmd/internal/codegen/parse/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ func (b *APIs) parseJSONSchemaProps() {
} else {
resource.CRD.Spec.Scope = "Namespaced"
}

if len(resource.ShortName) > 0 {
resource.CRD.Spec.Names.ShortNames = []string{resource.ShortName}
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/internal/codegen/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ type APIResource struct {
// NonNamespaced indicates that the resource kind is non namespaced
NonNamespaced bool

ShortName string

JSONSchemaProps v1beta1.JSONSchemaProps
CRD v1beta1.CustomResourceDefinition
Validation string
Expand Down
25 changes: 14 additions & 11 deletions cmd/kubebuilder-gen/internal/resourcegen/versioned_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ type versionedGenerator struct {

var _ generator.Generator = &versionedGenerator{}

func hasSubresources(version *codegen.APIVersion) bool {
for _, v := range version.Resources {
if len(v.Subresources) != 0 {
return true
}
}
return false
}
//func hasSubresources(version *codegen.APIVersion) bool {
// for _, v := range version.Resources {
// if len(v.Subresources) != 0 {
// return true
// }
// }
// return false
//}

func (d *versionedGenerator) Imports(c *generator.Context) []string {
imports := []string{
Expand All @@ -49,9 +49,9 @@ func (d *versionedGenerator) Imports(c *generator.Context) []string {
"k8s.io/apimachinery/pkg/runtime/schema",
d.apigroup.Pkg.Path,
}
if hasSubresources(d.apiversion) {
imports = append(imports, "k8s.io/apiserver/pkg/registry/rest")
}
//if hasSubresources(d.apiversion) {
// imports = append(imports, "k8s.io/apiserver/pkg/registry/rest")
//}

return imports
}
Expand Down Expand Up @@ -120,6 +120,9 @@ var (
Names: v1beta1.CustomResourceDefinitionNames{
Kind: "{{.Kind}}",
Plural: "{{.Resource}}",
{{ if .ShortName -}}
ShortNames: []string{"{{.ShortName}}"},
{{ end -}}
},
{{ if .NonNamespaced -}}
Scope: "Cluster",
Expand Down
2 changes: 2 additions & 0 deletions cmd/kubebuilder/create/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package config
import (
"fmt"
"github.com/spf13/cobra"
"log"
"path/filepath"
)

Expand All @@ -41,6 +42,7 @@ var configCmd = &cobra.Command{
return
}
CodeGenerator{}.Execute()
log.Printf("Config written to hack/install.yaml")
},
}

Expand Down

0 comments on commit 61a6891

Please sign in to comment.