Is it possible to modify an object namespace in a Mutating Webhook?

9/23/2021

I have created a Mutating Webhook for a Namespaced CRD. In this Webhook, I would like to dynamically change the namespace of the resource, no matter what the user specified.

When I try to create a resource, I get the following error:

Error from server (BadRequest): error when creating "crd.yaml": the namespace of the provided object does not match the namespace sent on the request

Is it possible to perform this change and, if so, am I missing any configuration?

-- Pedro Andrez
kubernetes

1 Answer

3/29/2022

Sadly, it might not be possible: looking at the code here, you can see that if the resource you're attempting to create already has a namespace (the request), and your webhook attempts to mutate the object to replace the namespace (the object), then there will be a mismatch.

	if err := EnsureObjectNamespaceMatchesRequestNamespace(ExpectedNamespaceForScope(requestNamespace, strategy.NamespaceScoped()), objectMeta); err != nil {
		return err
	}

You can see that the function EnsureObjectNamespaceMatchesRequestNamespace takes in two things: the expected namespace from the request and the object's metadata. If the request coming in is namespaced, then the request's namespace will be returned.

If you look at the function, you can see that your case falls through to the default case:

	switch {
	case objNamespace == requestNamespace:
		// already matches, no-op
		return nil

	case objNamespace == metav1.NamespaceNone:
		// unset, default to request namespace
		obj.SetNamespace(requestNamespace)
		return nil

	case requestNamespace == metav1.NamespaceNone:
		// cluster-scoped, clear namespace
		obj.SetNamespace(metav1.NamespaceNone)
		return nil

	default:
		// mismatch, error
		return errors.NewBadRequest("the namespace of the provided object does not match the namespace sent on the request")
	}

Did you end up figuring out a workaround for yourself?

-- johnatflatiron
Source: StackOverflow