Skip to content

Commit

Permalink
Updates ControllerInterface to use a cache struct.
Browse files Browse the repository at this point in the history
Changes the generated cache to a pointer receiver, and the
ControllerInterface now returns a real struct instead of an interface.
These changes greatly reduce the amount of generated code needed and
allows users to use the mocks directly with controllers without
having to wrap them as an embedded object.
  • Loading branch information
KevinJoiner committed Jun 14, 2023
1 parent b6c9c82 commit b2a9c90
Show file tree
Hide file tree
Showing 45 changed files with 133 additions and 3,056 deletions.
4 changes: 1 addition & 3 deletions pkg/controller-gen/generators/group_version_interface_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ func (f *groupInterfaceGo) Init(c *generator.Context, w io.Writer) error {
}
body := `
func (v *version) {{.type}}() {{.type}}Controller {
return &{{.type}}GenericController {
generic.New{{ if not .namespaced}}NonNamespaced{{end}}Controller[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List](schema.GroupVersionKind{Group: "{{.group}}", Version: "{{.version}}", Kind: "{{.type}}"}, "{{.pluralLower}}", {{ if .namespaced}}true, {{end}}v.controllerFactory),
}
return generic.New{{ if not .namespaced}}NonNamespaced{{end}}Controller[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List](schema.GroupVersionKind{Group: "{{.group}}", Version: "{{.version}}", Kind: "{{.type}}"}, "{{.pluralLower}}", {{ if .namespaced}}true, {{end}}v.controllerFactory)
}
`
sw.Do(body, m)
Expand Down
104 changes: 3 additions & 101 deletions pkg/controller-gen/generators/type_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,129 +84,31 @@ func hasStatus(t *types.Type) bool {
var typeBody = `
// {{.type}}Controller interface for managing {{.type}} resources.
type {{.type}}Controller interface {
generic.ControllerMeta
{{.type}}Client
// OnChange runs the given handler when the controller detects a resource was changed.
OnChange(ctx context.Context, name string, sync {{.type}}Handler)
// OnRemove runs the given handler when the controller detects a resource was changed.
OnRemove(ctx context.Context, name string, sync {{.type}}Handler)
// Enqueue adds the resource with the given name to the worker queue of the controller.
Enqueue({{ if .namespaced}}namespace, {{end}}name string)
// EnqueueAfter runs Enqueue after the provided duration.
EnqueueAfter({{ if .namespaced}}namespace, {{end}}name string, duration time.Duration)
// Cache returns a cache for the resource type T.
Cache() {{.type}}Cache
generic.{{ if not .namespaced}}NonNamespaced{{end}}ControllerInterface[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List]
}
// {{.type}}Client interface for managing {{.type}} resources in Kubernetes.
type {{.type}}Client interface {
// Create creates a new object and return the newly created Object or an error.
Create(*{{.version}}.{{.type}}) (*{{.version}}.{{.type}}, error)
// Update updates the object and return the newly updated Object or an error.
Update(*{{.version}}.{{.type}}) (*{{.version}}.{{.type}}, error)
{{ if .hasStatus -}}
// UpdateStatus updates the Status field of a the object and return the newly updated Object or an error.
// Will always return an error if the object does not have a status field.
UpdateStatus(*{{.version}}.{{.type}}) (*{{.version}}.{{.type}}, error)
{{- end }}
// Delete deletes the Object in the given name.
Delete({{ if .namespaced}}namespace, {{end}}name string, options *metav1.DeleteOptions) error
// Get will attempt to retrieve the resource with the specified name.
Get({{ if .namespaced}}namespace, {{end}}name string, options metav1.GetOptions) (*{{.version}}.{{.type}}, error)
// List will attempt to find multiple resources.
List({{ if .namespaced}}namespace string, {{end}}opts metav1.ListOptions) (*{{.version}}.{{.type}}List, error)
// Watch will start watching resources.
Watch({{ if .namespaced}}namespace string, {{end}}opts metav1.ListOptions) (watch.Interface, error)
// Patch will patch the resource with the matching name.
Patch({{ if .namespaced}}namespace, {{end}}name string, pt types.PatchType, data []byte, subresources ...string) (result *{{.version}}.{{.type}}, err error)
// WithImpersonation returns a new client that will use the provided impersonation config for new request.
WithImpersonation(impersonate rest.ImpersonationConfig) (generic.{{ if not .namespaced}}NonNamespaced{{end}}ClientInterface[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List], error)
generic.{{ if not .namespaced}}NonNamespaced{{end}}ClientInterface[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List]
}
// {{.type}}Cache interface for retrieving {{.type}} resources in memory.
type {{.type}}Cache interface {
// Get returns the resources with the specified name from the cache.
Get({{ if .namespaced}}namespace, {{end}}name string) (*{{.version}}.{{.type}}, error)
// List will attempt to find resources from the Cache.
List({{ if .namespaced}}namespace string, {{end}}selector labels.Selector) ([]*{{.version}}.{{.type}}, error)
// AddIndexer adds a new Indexer to the cache with the provided name.
// If you call this after you already have data in the store, the results are undefined.
AddIndexer(indexName string, indexer {{.type}}Indexer)
// GetByIndex returns the stored objects whose set of indexed values
// for the named index includes the given indexed value.
GetByIndex(indexName, key string) ([]*{{.version}}.{{.type}}, error)
}
// {{.type}}Handler is function for performing any potential modifications to a {{.type}} resource.
type {{.type}}Handler func(string, *{{.version}}.{{.type}}) (*{{.version}}.{{.type}}, error)
// {{.type}}Indexer computes a set of indexed values for the provided object.
type {{.type}}Indexer func(obj *{{.version}}.{{.type}}) ([]string, error)
// {{.type}}GenericController wraps wrangler/pkg/generic.{{ if not .namespaced}}NonNamespaced{{end}}Controller so that the function definitions adhere to {{.type}}Controller interface.
type {{.type}}GenericController struct {
generic.{{ if not .namespaced}}NonNamespaced{{end}}ControllerInterface[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List]
}
// OnChange runs the given resource handler when the controller detects a resource was changed.
func (c *{{.type}}GenericController) OnChange(ctx context.Context, name string, sync {{.type}}Handler) {
c.{{ if not .namespaced}}NonNamespaced{{end}}ControllerInterface.OnChange(ctx, name, generic.ObjectHandler[*{{.version}}.{{.type}}](sync))
}
// OnRemove runs the given object handler when the controller detects a resource was changed.
func (c *{{.type}}GenericController) OnRemove(ctx context.Context, name string, sync {{.type}}Handler) {
c.{{ if not .namespaced}}NonNamespaced{{end}}ControllerInterface.OnRemove(ctx, name, generic.ObjectHandler[*{{.version}}.{{.type}}](sync))
}
// Cache returns a cache of resources in memory.
func (c *{{.type}}GenericController) Cache() {{.type}}Cache {
return &{{.type}}GenericCache{
c.{{ if not .namespaced}}NonNamespaced{{end}}ControllerInterface.Cache(),
}
}
// {{.type}}GenericCache wraps wrangler/pkg/generic.{{ if not .namespaced}}NonNamespaced{{end}}Cache so the function definitions adhere to {{.type}}Cache interface.
type {{.type}}GenericCache struct {
generic.{{ if not .namespaced}}NonNamespaced{{end}}CacheInterface[*{{.version}}.{{.type}}]
}
// AddIndexer adds a new Indexer to the cache with the provided name.
// If you call this after you already have data in the store, the results are undefined.
func (c {{.type}}GenericCache) AddIndexer(indexName string, indexer {{.type}}Indexer) {
c.{{ if not .namespaced}}NonNamespaced{{end}}CacheInterface.AddIndexer(indexName, generic.Indexer[*{{.version}}.{{.type}}](indexer))
}
{{ if .hasStatus -}}
type {{.type}}StatusHandler func(obj *{{.version}}.{{.type}}, status {{.version}}.{{.statusType}}) ({{.version}}.{{.statusType}}, error)
type {{.type}}GeneratingHandler func(obj *{{.version}}.{{.type}}, status {{.version}}.{{.statusType}}) ([]runtime.Object, {{.version}}.{{.statusType}}, error)
func From{{.type}}HandlerToHandler(sync {{.type}}Handler) generic.Handler {
return generic.FromObjectHandlerToHandler(generic.ObjectHandler[*{{.version}}.{{.type}},](sync))
}
func Register{{.type}}StatusHandler(ctx context.Context, controller {{.type}}Controller, condition condition.Cond, name string, handler {{.type}}StatusHandler) {
statusHandler := &{{.lowerName}}StatusHandler{
client: controller,
condition: condition,
handler: handler,
}
controller.AddGenericHandler(ctx, name, From{{.type}}HandlerToHandler(statusHandler.sync))
controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync))
}
func Register{{.type}}GeneratingHandler(ctx context.Context, controller {{.type}}Controller, apply apply.Apply,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b2a9c90

Please sign in to comment.