1
0
mirror of https://github.com/rancher/types.git synced 2025-09-01 05:09:10 +00:00

Update norman and vendor

This commit is contained in:
Darren Shepherd
2017-11-28 14:34:13 -07:00
parent 7917ce217d
commit d36708b38c
23 changed files with 409 additions and 48 deletions

View File

@@ -117,7 +117,6 @@ func (p *ObjectClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
r, err := p.restClient.Get().
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).
Prefix("watch").
Namespace(p.ns).
NamespaceIfScoped(p.ns, p.resource.Namespaced).
Resource(p.resource.Name).
VersionedParams(&opts, dynamic.VersionedParameterEncoderWithV1Fallback).

View File

@@ -24,7 +24,9 @@ type HandlerFunc func(key string) error
type GenericController interface {
Informer() cache.SharedIndexInformer
AddHandler(handler HandlerFunc)
HandlerCount() int
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
@@ -35,6 +37,7 @@ type genericController struct {
queue workqueue.RateLimitingInterface
name string
running bool
synced bool
}
func NewGenericController(name string, objectClient *clientbase.ObjectClient) GenericController {
@@ -53,6 +56,10 @@ func NewGenericController(name string, objectClient *clientbase.ObjectClient) Ge
}
}
func (g *genericController) HandlerCount() int {
return len(g.handlers)
}
func (g *genericController) Informer() cache.SharedIndexInformer {
return g.informer
}
@@ -69,10 +76,50 @@ func (g *genericController) AddHandler(handler HandlerFunc) {
g.handlers = append(g.handlers, handler)
}
func (g *genericController) Sync(ctx context.Context) error {
g.Lock()
defer g.Unlock()
return g.sync(ctx)
}
func (g *genericController) sync(ctx context.Context) error {
if g.synced {
return nil
}
defer utilruntime.HandleCrash()
g.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: g.queueObject,
UpdateFunc: func(_, obj interface{}) {
g.queueObject(obj)
},
DeleteFunc: g.queueObject,
})
logrus.Infof("Starting %s Controller", g.name)
go g.informer.Run(ctx.Done())
if !cache.WaitForCacheSync(ctx.Done(), g.informer.HasSynced) {
return fmt.Errorf("failed to sync controller %s", g.name)
}
g.synced = true
return nil
}
func (g *genericController) Start(ctx context.Context, threadiness int) error {
g.Lock()
defer g.Unlock()
if !g.synced {
if err := g.sync(ctx); err != nil {
return err
}
}
if !g.running {
go g.run(ctx, threadiness)
}
@@ -92,22 +139,6 @@ func (g *genericController) run(ctx context.Context, threadiness int) {
defer utilruntime.HandleCrash()
defer g.queue.ShutDown()
g.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: g.queueObject,
UpdateFunc: func(_, obj interface{}) {
g.queueObject(obj)
},
DeleteFunc: g.queueObject,
})
logrus.Infof("Starting %s Controller", g.name)
go g.informer.Run(ctx.Done())
if !cache.WaitForCacheSync(ctx.Done(), g.informer.HasSynced) {
return
}
for i := 0; i < threadiness; i++ {
go wait.Until(g.runWorker, time.Second, ctx.Done())
}

33
vendor/github.com/rancher/norman/controller/starter.go generated vendored Normal file
View File

@@ -0,0 +1,33 @@
package controller
import (
"context"
"golang.org/x/sync/errgroup"
)
type Starter interface {
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
func Sync(ctx context.Context, starters ...Starter) error {
eg, ctx := errgroup.WithContext(ctx)
for _, starter := range starters {
func(starter Starter) {
eg.Go(func() error {
return starter.Sync(ctx)
})
}(starter)
}
return eg.Wait()
}
func Start(ctx context.Context, threadiness int, starters ...Starter) error {
for _, starter := range starters {
if err := starter.Start(ctx, threadiness); err != nil {
return err
}
}
return nil
}

View File

@@ -3,17 +3,17 @@ package generator
var controllerTemplate = `package {{.schema.Version.Version}}
import (
"sync"
"context"
{{.importPackage}}
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
)
@@ -26,7 +26,11 @@ var (
{{.schema.CodeName}}Resource = metav1.APIResource{
Name: "{{.schema.PluralName | toLower}}",
SingularName: "{{.schema.ID | toLower}}",
{{- if eq .schema.Scope "namespace" }}
Namespaced: true,
{{ else }}
Namespaced: false,
{{- end }}
Kind: {{.schema.CodeName}}GroupVersionKind.Kind,
}
)
@@ -34,33 +38,73 @@ var (
type {{.schema.CodeName}}List struct {
metav1.TypeMeta %BACK%json:",inline"%BACK%
metav1.ListMeta %BACK%json:"metadata,omitempty"%BACK%
Items []{{.schema.CodeName}}
Items []{{.prefix}}{{.schema.CodeName}}
}
type {{.schema.CodeName}}HandlerFunc func(key string, obj *{{.schema.CodeName}}) error
type {{.schema.CodeName}}HandlerFunc func(key string, obj *{{.prefix}}{{.schema.CodeName}}) error
type {{.schema.CodeName}}Lister interface {
List(namespace string, selector labels.Selector) (ret []*{{.prefix}}{{.schema.CodeName}}, err error)
Get(namespace, name string) (*{{.prefix}}{{.schema.CodeName}}, error)
}
type {{.schema.CodeName}}Controller interface {
Informer() cache.SharedIndexInformer
Lister() {{.schema.CodeName}}Lister
AddHandler(handler {{.schema.CodeName}}HandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type {{.schema.CodeName}}Interface interface {
Create(*{{.schema.CodeName}}) (*{{.schema.CodeName}}, error)
Get(name string, opts metav1.GetOptions) (*{{.schema.CodeName}}, error)
Update(*{{.schema.CodeName}}) (*{{.schema.CodeName}}, error)
ObjectClient() *clientbase.ObjectClient
Create(*{{.prefix}}{{.schema.CodeName}}) (*{{.prefix}}{{.schema.CodeName}}, error)
Get(name string, opts metav1.GetOptions) (*{{.prefix}}{{.schema.CodeName}}, error)
Update(*{{.prefix}}{{.schema.CodeName}}) (*{{.prefix}}{{.schema.CodeName}}, error)
Delete(name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*{{.schema.CodeName}}List, error)
List(opts metav1.ListOptions) (*{{.prefix}}{{.schema.CodeName}}List, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() {{.schema.CodeName}}Controller
}
type {{.schema.ID}}Lister struct {
controller *{{.schema.ID}}Controller
}
func (l *{{.schema.ID}}Lister) List(namespace string, selector labels.Selector) (ret []*{{.prefix}}{{.schema.CodeName}}, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*{{.prefix}}{{.schema.CodeName}}))
})
return
}
func (l *{{.schema.ID}}Lister) Get(namespace, name string) (*{{.prefix}}{{.schema.CodeName}}, error) {
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: {{.schema.CodeName}}GroupVersionKind.Group,
Resource: "{{.schema.ID}}",
}, name)
}
return obj.(*{{.prefix}}{{.schema.CodeName}}), nil
}
type {{.schema.ID}}Controller struct {
controller.GenericController
}
func (c *{{.schema.ID}}Controller) Lister() {{.schema.CodeName}}Lister {
return &{{.schema.ID}}Lister{
controller: c,
}
}
func (c *{{.schema.ID}}Controller) AddHandler(handler {{.schema.CodeName}}HandlerFunc) {
c.GenericController.AddHandler(func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
@@ -70,7 +114,7 @@ func (c *{{.schema.ID}}Controller) AddHandler(handler {{.schema.CodeName}}Handle
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*{{.schema.CodeName}}))
return handler(key, obj.(*{{.prefix}}{{.schema.CodeName}}))
})
}
@@ -78,7 +122,7 @@ type {{.schema.ID}}Factory struct {
}
func (c {{.schema.ID}}Factory) Object() runtime.Object {
return &{{.schema.CodeName}}{}
return &{{.prefix}}{{.schema.CodeName}}{}
}
func (c {{.schema.ID}}Factory) List() runtime.Object {
@@ -102,6 +146,7 @@ func (s *{{.schema.ID}}Client) Controller() {{.schema.CodeName}}Controller {
}
s.client.{{.schema.ID}}Controllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
@@ -113,28 +158,32 @@ type {{.schema.ID}}Client struct {
controller {{.schema.CodeName}}Controller
}
func (s *{{.schema.ID}}Client) Create(o *{{.schema.CodeName}}) (*{{.schema.CodeName}}, error) {
func (s *{{.schema.ID}}Client) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *{{.schema.ID}}Client) Create(o *{{.prefix}}{{.schema.CodeName}}) (*{{.prefix}}{{.schema.CodeName}}, error) {
obj, err := s.objectClient.Create(o)
return obj.(*{{.schema.CodeName}}), err
return obj.(*{{.prefix}}{{.schema.CodeName}}), err
}
func (s *{{.schema.ID}}Client) Get(name string, opts metav1.GetOptions) (*{{.schema.CodeName}}, error) {
func (s *{{.schema.ID}}Client) Get(name string, opts metav1.GetOptions) (*{{.prefix}}{{.schema.CodeName}}, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*{{.schema.CodeName}}), err
return obj.(*{{.prefix}}{{.schema.CodeName}}), err
}
func (s *{{.schema.ID}}Client) Update(o *{{.schema.CodeName}}) (*{{.schema.CodeName}}, error) {
func (s *{{.schema.ID}}Client) Update(o *{{.prefix}}{{.schema.CodeName}}) (*{{.prefix}}{{.schema.CodeName}}, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*{{.schema.CodeName}}), err
return obj.(*{{.prefix}}{{.schema.CodeName}}), err
}
func (s *{{.schema.ID}}Client) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *{{.schema.ID}}Client) List(opts metav1.ListOptions) (*{{.schema.CodeName}}List, error) {
func (s *{{.schema.ID}}Client) List(opts metav1.ListOptions) (*{{.prefix}}{{.schema.CodeName}}List, error) {
obj, err := s.objectClient.List(opts)
return obj.(*{{.schema.CodeName}}List), err
return obj.(*{{.prefix}}{{.schema.CodeName}}List), err
}
func (s *{{.schema.ID}}Client) Watch(opts metav1.ListOptions) (watch.Interface, error) {

View File

@@ -1,6 +1,8 @@
package generator
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
@@ -10,8 +12,6 @@ import (
"strings"
"text/template"
"io"
"github.com/pkg/errors"
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
@@ -135,7 +135,7 @@ func generateType(outputDir string, schema *types.Schema, schemas *types.Schemas
})
}
func generateController(outputDir string, schema *types.Schema, schemas *types.Schemas) error {
func generateController(external bool, outputDir string, schema *types.Schema, schemas *types.Schemas) error {
filePath := strings.ToLower("zz_generated_" + addUnderscore(schema.ID) + "_controller.go")
output, err := os.Create(path.Join(outputDir, filePath))
if err != nil {
@@ -150,8 +150,18 @@ func generateController(outputDir string, schema *types.Schema, schemas *types.S
return err
}
importPackage := ""
prefix := ""
if external {
parts := strings.Split(schema.PkgName, "/vendor/")
importPackage = fmt.Sprintf("\"%s\"", parts[len(parts)-1])
prefix = schema.Version.Version + "."
}
return typeTemplate.Execute(output, map[string]interface{}{
"schema": schema,
"schema": schema,
"importPackage": importPackage,
"prefix": prefix,
})
}
@@ -195,6 +205,40 @@ func generateClient(outputDir string, schemas []*types.Schema) error {
})
}
func GenerateControllerForTypes(version *types.APIVersion, k8sOutputPackage string, objs ...interface{}) error {
baseDir := args.DefaultSourceTree()
k8sDir := path.Join(baseDir, k8sOutputPackage)
if err := prepareDirs(k8sDir); err != nil {
return err
}
schemas := types.NewSchemas()
var controllers []*types.Schema
for _, obj := range objs {
schema, err := schemas.Import(version, obj)
if err != nil {
return err
}
controllers = append(controllers, schema)
if err := generateController(true, k8sDir, schema, schemas); err != nil {
return err
}
}
if err := deepCopyGen(baseDir, k8sOutputPackage); err != nil {
return err
}
if err := generateK8sClient(k8sDir, version, controllers); err != nil {
return err
}
return gofmt(baseDir, k8sOutputPackage)
}
func Generate(schemas *types.Schemas, cattleOutputPackage, k8sOutputPackage string) error {
baseDir := args.DefaultSourceTree()
cattleDir := path.Join(baseDir, cattleOutputPackage)
@@ -220,7 +264,7 @@ func Generate(schemas *types.Schemas, cattleOutputPackage, k8sOutputPackage stri
!strings.HasPrefix(schema.PkgName, "k8s.io") &&
!strings.Contains(schema.PkgName, "/vendor/") {
controllers = append(controllers, schema)
if err := generateController(k8sDir, schema, schemas); err != nil {
if err := generateController(false, k8sDir, schema, schemas); err != nil {
return err
}
}

View File

@@ -4,14 +4,17 @@ var k8sClientTemplate = `package {{.version.Version}}
import (
"sync"
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
)
type Interface interface {
RESTClient() rest.Interface
controller.Starter
{{range .schemas}}
{{.CodeNamePlural}}Getter{{end}}
}
@@ -19,6 +22,7 @@ type Interface interface {
type Client struct {
sync.Mutex
restClient rest.Interface
starters []controller.Starter
{{range .schemas}}
{{.ID}}Controllers map[string]{{.CodeName}}Controller{{end}}
}
@@ -45,6 +49,14 @@ func (c *Client) RESTClient() rest.Interface {
return c.restClient
}
func (c *Client) Sync(ctx context.Context) error {
return controller.Sync(ctx, c.starters...)
}
func (c *Client) Start(ctx context.Context, threadiness int) error {
return controller.Start(ctx, threadiness, c.starters...)
}
{{range .schemas}}
type {{.CodeNamePlural}}Getter interface {
{{.CodeNamePlural}}(namespace string) {{.CodeName}}Interface

View File

@@ -14,6 +14,10 @@ func IsReferenceType(fieldType string) bool {
return strings.HasPrefix(fieldType, "reference[") && strings.HasSuffix(fieldType, "]")
}
func HasReferenceType(fieldType string) bool {
return strings.Contains(fieldType, "reference[")
}
func SubType(fieldType string) string {
i := strings.Index(fieldType, "[")
if i <= 0 || i >= len(fieldType)-1 {

View File

@@ -1,6 +1,8 @@
package types
import (
"fmt"
"github.com/rancher/norman/types/definition"
)
@@ -67,7 +69,7 @@ func (t *typeMapper) FromInternal(data map[string]interface{}) {
data["type"] = t.typeName
}
name, _ := data["name"].(string)
namespace, _ := data["namespace"].(string)
namespace, _ := data["namespaceId"].(string)
if _, ok := data["id"]; !ok {
if name != "" {
@@ -106,7 +108,7 @@ func (t *typeMapper) ToInternal(data map[string]interface{}) {
func (t *typeMapper) ModifySchema(schema *Schema, schemas *Schemas) error {
t.subSchemas = map[string]*Schema{}
t.subArraySchemas = map[string]*Schema{}
t.typeName = schema.ID
t.typeName = fmt.Sprintf("%s/schemas/%s", schema.Version.Path, schema.ID)
mapperSchema := schema
if schema.InternalSchema != nil {

View File

@@ -7,6 +7,7 @@ import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
"github.com/rancher/norman/types/definition"
)
type Move struct {
@@ -64,7 +65,11 @@ func getField(schema *types.Schema, schemas *types.Schemas, target string) (*typ
continue
}
subSchema := schemas.Schema(&schema.Version, schema.ResourceFields[part].Type)
fieldType := schema.ResourceFields[part].Type
if definition.IsArrayType(fieldType) {
fieldType = definition.SubType(fieldType)
}
subSchema := schemas.Schema(&schema.Version, fieldType)
if subSchema == nil {
return nil, "", types.Field{}, false, fmt.Errorf("failed to find field or schema for %s on %s", part, schema.ID)
}

View File

@@ -52,6 +52,11 @@ func (s SliceToMap) ModifySchema(schema *types.Schema, schemas *types.Schemas) e
return err
}
subSchema, subFieldName, _, _, err := getField(schema, schemas, fmt.Sprintf("%s/%s", s.Field, s.Key))
if err != nil {
return err
}
field := schema.ResourceFields[s.Field]
if !definition.IsArrayType(field.Type) {
return fmt.Errorf("field %s on %s is not an array", s.Field, schema.ID)
@@ -60,5 +65,7 @@ func (s SliceToMap) ModifySchema(schema *types.Schema, schemas *types.Schemas) e
field.Type = "map[" + definition.SubType(field.Type) + "]"
schema.ResourceFields[s.Field] = field
delete(subSchema.ResourceFields, subFieldName)
return nil
}

View File

@@ -174,7 +174,7 @@ func (s *Schemas) importType(version *APIVersion, t reflect.Type, overrides ...r
schema.Mapper = mapper
s.AddSchema(schema)
return schema, nil
return schema, s.Err()
}
func jsonName(f reflect.StructField) string {

View File

@@ -63,7 +63,7 @@ func (s *Schemas) AddSchema(schema *Schema) *Schemas {
s.errors = append(s.errors, fmt.Errorf("ID is not set on schema: %v", schema))
return s
}
if schema.Version.Path == "" || schema.Version.Group == "" || schema.Version.Version == "" {
if schema.Version.Path == "" || schema.Version.Version == "" {
s.errors = append(s.errors, fmt.Errorf("version is not set on schema: %s", schema.ID))
return s
}

View File

@@ -126,6 +126,7 @@ type QueryOptions struct {
Sort Sort
Pagination *Pagination
Conditions []*QueryCondition
Options map[string]string
}
type ReferenceValidator interface {
@@ -153,4 +154,5 @@ type Store interface {
Create(apiContext *APIContext, schema *Schema, data map[string]interface{}) (map[string]interface{}, error)
Update(apiContext *APIContext, schema *Schema, data map[string]interface{}, id string) (map[string]interface{}, error)
Delete(apiContext *APIContext, schema *Schema, id string) error
Watch(apiContext *APIContext, schema *Schema, opt QueryOptions) (chan map[string]interface{}, error)
}

View File

@@ -89,7 +89,7 @@ type Schema struct {
Version APIVersion `json:"version"`
PluralName string `json:"pluralName,omitempty"`
ResourceMethods []string `json:"resourceMethods,omitempty"`
ResourceFields map[string]Field `json:"resourceFields,omitempty"`
ResourceFields map[string]Field `json:"resourceFields"`
ResourceActions map[string]Action `json:"resourceActions,omitempty"`
CollectionMethods []string `json:"collectionMethods,omitempty"`
CollectionFields map[string]Field `json:"collectionFields,omitempty"`