Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions pkg/controller-gen/generators/type_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,24 @@ func (f *typeGo) Init(c *generator.Context, w io.Writer) error {
}

t := c.Universe.Type(*f.name)
hasKubebuilderStatus := false
noStatusSuffix := "NoStatus"
for _, line := range append(t.SecondClosestCommentLines, t.CommentLines...) {
if strings.Contains(line, "+kubebuilder:subresource:status") {
hasKubebuilderStatus = true
noStatusSuffix = ""
}
}

m := map[string]interface{}{
"type": f.name.Name,
"lowerName": namer.IL(f.name.Name),
"plural": plural.Name(t),
"version": f.gv.Version,
"namespaced": namespaced(t),
"hasStatus": hasStatus(t),
"statusType": statusType(t),
"type": f.name.Name,
"lowerName": namer.IL(f.name.Name),
"plural": plural.Name(t),
"version": f.gv.Version,
"namespaced": namespaced(t),
"hasStatus": hasKubebuilderStatus && hasStatus(t),
"noStatusSuffix": noStatusSuffix,
"statusType": statusType(t),
}

sw.Do(typeBody, m)
Expand Down Expand Up @@ -81,12 +91,12 @@ func hasStatus(t *types.Type) bool {
var typeBody = `
// {{.type}}Controller interface for managing {{.type}} resources.
type {{.type}}Controller interface {
generic.{{ if not .namespaced}}NonNamespaced{{end}}ControllerInterface[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List]
generic.{{ if not .namespaced}}NonNamespaced{{end}}ControllerInterface{{.noStatusSuffix}}[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List]
}

// {{.type}}Client interface for managing {{.type}} resources in Kubernetes.
type {{.type}}Client interface {
generic.{{ if not .namespaced}}NonNamespaced{{end}}ClientInterface[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List]
generic.{{ if not .namespaced}}NonNamespaced{{end}}ClientInterface{{.noStatusSuffix}}[*{{.version}}.{{.type}}, *{{.version}}.{{.type}}List]
}

// {{.type}}Cache interface for retrieving {{.type}} resources in memory.
Expand Down
96 changes: 96 additions & 0 deletions pkg/generic/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,27 @@ type RuntimeMetaObject interface {
metav1.Object
}

// ControllerInterface interface for managing K8s Objects.
type ControllerInterfaceNoStatus[T RuntimeMetaObject, TList runtime.Object] interface {
ControllerMeta
ClientInterfaceNoStatus[T, TList]

// OnChange runs the given object handler when the controller detects a resource was changed.
OnChange(ctx context.Context, name string, sync ObjectHandler[T])

// OnRemove runs the given object handler when the controller detects a resource was changed.
OnRemove(ctx context.Context, name string, sync ObjectHandler[T])

// Enqueue adds the resource with the given name in the provided namespace to the worker queue of the controller.
Enqueue(namespace, name string)

// EnqueueAfter runs Enqueue after the provided duration.
EnqueueAfter(namespace, name string, duration time.Duration)

// Cache returns a cache for the resource type T.
Cache() CacheInterface[T]
}

// ControllerInterface interface for managing K8s Objects.
type ControllerInterface[T RuntimeMetaObject, TList runtime.Object] interface {
ControllerMeta
Expand All @@ -66,6 +87,27 @@ type ControllerInterface[T RuntimeMetaObject, TList runtime.Object] interface {
Cache() CacheInterface[T]
}

// NonNamespacedControllerInterface interface for managing non namespaced K8s Objects.
type NonNamespacedControllerInterfaceNoStatus[T RuntimeMetaObject, TList runtime.Object] interface {
ControllerMeta
NonNamespacedClientInterfaceNoStatus[T, TList]

// OnChange runs the given object handler when the controller detects a resource was changed.
OnChange(ctx context.Context, name string, sync ObjectHandler[T])

// OnRemove runs the given object handler when the controller detects a resource was changed.
OnRemove(ctx context.Context, name string, sync ObjectHandler[T])

// Enqueue adds the resource with the given name to the worker queue of the controller.
Enqueue(name string)

// EnqueueAfter runs Enqueue after the provided duration.
EnqueueAfter(name string, duration time.Duration)

// Cache returns a cache for the resource type T.
Cache() NonNamespacedCacheInterface[T]
}

// NonNamespacedControllerInterface interface for managing non namespaced K8s Objects.
type NonNamespacedControllerInterface[T RuntimeMetaObject, TList runtime.Object] interface {
ControllerMeta
Expand Down Expand Up @@ -118,6 +160,60 @@ type ClientInterface[T RuntimeMetaObject, TList runtime.Object] interface {
WithImpersonation(impersonate rest.ImpersonationConfig) (ClientInterface[T, TList], error)
}

// ClientInterface is an interface to performs CRUD like operations on an Objects.
type ClientInterfaceNoStatus[T RuntimeMetaObject, TList runtime.Object] interface {
// Create creates a new object and return the newly created Object or an error.
Create(T) (T, error)

// Update updates the object and return the newly updated Object or an error.
Update(T) (T, error)

// Delete deletes the Object in the given name and namespace.
Delete(namespace, name string, options *metav1.DeleteOptions) error

// Get will attempt to retrieve the resource with the given name in the given namespace.
Get(namespace, name string, options metav1.GetOptions) (T, error)

// List will attempt to find resources in the given namespace.
List(namespace string, opts metav1.ListOptions) (TList, error)

// Watch will start watching resources in the given namespace.
Watch(namespace string, opts metav1.ListOptions) (watch.Interface, error)

// Patch will patch the resource with the matching name in the matching namespace.
Patch(namespace, name string, pt types.PatchType, data []byte, subresources ...string) (result T, err error)

// WithImpersonation returns a new copy of the client that uses impersonation.
WithImpersonation(impersonate rest.ImpersonationConfig) (ClientInterface[T, TList], error)
}

// NonNamespacedClientInterface is an interface to performs CRUD like operations on nonNamespaced Objects.
type NonNamespacedClientInterfaceNoStatus[T RuntimeMetaObject, TList runtime.Object] interface {
// Create creates a new object and return the newly created Object or an error.
Create(T) (T, error)

// Update updates the object and return the newly updated Object or an error.
Update(T) (T, error)

// Delete deletes the Object in the given name.
Delete(name string, options *metav1.DeleteOptions) error

// Get will attempt to retrieve the resource with the specified name.
Get(name string, options metav1.GetOptions) (T, error)

// List will attempt to find multiple resources.
List(opts metav1.ListOptions) (TList, error)

// Watch will start watching resources.
Watch(opts metav1.ListOptions) (watch.Interface, error)

// Patch will patch the resource with the matching name.
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result T, err error)

// WithImpersonation returns a new copy of the client that uses impersonation.
WithImpersonation(impersonate rest.ImpersonationConfig) (NonNamespacedClientInterface[T, TList], error)
}

// NonNamespacedClientInterface is an interface to performs CRUD like operations on nonNamespaced Objects.
type NonNamespacedClientInterface[T RuntimeMetaObject, TList runtime.Object] interface {
// Create creates a new object and return the newly created Object or an error.
Expand Down
Loading