Skip to content

Instantly share code, notes, and snippets.

@bshephar
Created June 15, 2023 11:42
Show Gist options
  • Save bshephar/b8f597e0cc9f80336783b7758e0f307f to your computer and use it in GitHub Desktop.
Save bshephar/b8f597e0cc9f80336783b7758e0f307f to your computer and use it in GitHub Desktop.
Trying to use generics instead of two seperate functions that do exactly the same thing
type GenericDataPlaneObject interface {
*dataplanev1beta1.OpenStackDataPlaneRole | *dataplanev1beta1.OpenStackDataPlaneNode
}
// removeControllerManagedAnnotations will check for and remove annotations on Role objects that are managed by a OpenStackDataPlane controller.
func removeControllerManagedAnnotations[T GenericDataPlaneObject](ctx context.Context, instance T, helper *helper.Helper, annotation map[string]string) error {
client := helper.GetClient()
// Get all of the current annotations
annotations := instance.ObjectMeta.GetAnnotations()
// Remove the redeployProtectionAnnoation
delete(annotations, "edpm.openstack.org/deploy-protection")
for _, or := range instance.GetObjectMeta().GetOwnerReferences() {
if *or.Controller {
instance.ObjectMeta.SetAnnotations(annotations)
return client.Update(ctx, instance)
}
}
return nil
}
@bshephar
Copy link
Author

Doesn't love it:

❯ go vet ./...
# github.com/openstack-k8s-operators/dataplane-operator/controllers
controllers/openstackdataplane_controller.go:453:26: instance.ObjectMeta undefined (type T has no field or method ObjectMeta)
controllers/openstackdataplane_controller.go:457:30: instance.GetObjectMeta undefined (type T has no field or method GetObjectMeta)
controllers/openstackdataplane_controller.go:459:13: instance.ObjectMeta undefined (type T has no field or method ObjectMeta)
controllers/openstackdataplane_controller.go:460:30: cannot use instance (variable of type T constrained by GenericDataPlaneObject) as client.Object value in argument to client.Update: T does not implement client.Object (missing method DeepCopyObject)

I'm sure it's something simple that I'm missing.

@bshephar
Copy link
Author

Same errors with:

// removeControllerManagedAnnotations will check for and remove annotations on Role objects that are managed by a OpenStackDataPlane controller.
func removeControllerManagedAnnotations[T *dataplanev1beta1.OpenStackDataPlaneRole | *dataplanev1beta1.OpenStackDataPlaneNode](ctx context.Context, instance T, helper *helper.Helper, annotation map[string]string) error {
	client := helper.GetClient()

	// Get all of the current annotations
	annotations := instance.ObjectMeta.GetAnnotations()
	// Remove the redeployProtectionAnnoation
	delete(annotations, "edpm.openstack.org/deploy-protection")

	for _, or := range instance.GetObjectMeta().GetOwnerReferences() {
		if *or.Controller {
			instance.ObjectMeta.SetAnnotations(annotations)
			return client.Update(ctx, instance)
		}
	}
	return nil
}

@bshephar
Copy link
Author

Calling the function like this:

		err = removeControllerManagedAnnotations[*dataplanev1beta1.OpenStackDataPlaneRole](ctx, role, helper, redeployProtectionAnnotation)

@bshephar
Copy link
Author

It seems like the DeepCopy methods aren't available when these types are passed to the generics.

For example, this method is available on the OpenStackDataPlane* types when used individually.
https://github.com/kubernetes/apimachinery/blob/release-1.26/pkg/apis/meta/v1/meta.go#L131

But when passed to the function as generics, all of the methods that are deep copy methods are not available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment