Repository: kubernetes/kubernetes (language: go)

Issue:
Is event.InvolvedObject fields is required in kubernetes?
### What happened?

When I try to create an `event` resource with an empty `InvolvedObject` in k8s with client-go, I get a validation error `“InvolvedObject.namespace does not match event.namespace”` and the creation fails.

### What did you expect to happen?

This is probably because the validation step of event does not check the status of the `InvolvedObject` itself, but refers to event.InvolvedObject.Namespace.
https://github.com/kubernetes/kubernetes/blob/7ad1eaa66bc5cf270a0b44889aac555529feff83/pkg/apis/core/validation/events.go#L159-L161

### How can we reproduce it (as minimally and precisely as possible)?

This function will fail due to a validating error.

```go
func createEvent(clientset *kubernetes.Clientset, pod *corev1.Pod) {
	event := &corev1.Event{
		ObjectMeta: metav1.ObjectMeta{
			GenerateName: "pod-created-",
			Namespace:    pod.Namespace,
		},
		// InvolvedObject: corev1.ObjectReference{
		// 	Kind:      "Pod",
		// 	Namespace: pod.Namespace,
		// 	Name:      pod.Name,
		// 	UID:       pod.UID,
		// },
		Reason:  "PodCreated",
		Message: fmt.Sprintf("Pod %s was created", pod.Name),
		Type:    "Normal",
		Source: corev1.EventSource{
			Component: "pod-watcher",
		},
	}

	_, err := clientset.CoreV1().Events(pod.Namespace).Create(context.TODO(), event, metav1.CreateOptions{})
	if err != nil {
		fmt.Printf("Error creating event: %v\n", err)
	}
}
```

The below function is working.

```go
func createEvent(clientset *kubernetes.Clientset, pod *corev1.Pod) {
	event := &corev1.Event{
		ObjectMeta: metav1.ObjectMeta{
			GenerateName: "pod-created-",
			Namespace:    pod.Namespace,
		},
		InvolvedObject: corev1.ObjectReference{
		// 	Kind:      "Pod",
			Namespace: pod.Namespace,
		// 	Name:      pod.Name,
		// 	UID:       pod.UID,
		// },
		Reason:  "PodCreated",
		Message: fmt.Sprintf("Pod %s was created", pod.Name),
		Type:    "Normal",
		Source: corev1.EventSource{
			Component: "pod-watcher",
		},
	}

	_, err := clientset.CoreV1().Events(pod.Namespace).Create(context.TODO(), event, metav1.CreateOptions{})
	if err != nil {
		fmt.Printf("Error creating event: %v\n", err)
	}
}
```

### Anything else we need to know?

It looks like validating only checks the `Namespace` field in `InvolvedObject`.
If kubernetes decide to require `InvolvedObject` field for event resource, I feel we need to add more validation.

### Kubernetes version

<details>

```console
 Kubernetes v1.29.2
```

</details>


### Cloud provider

<details>
```
on-prem
```
</details>


### OS version

<details>

```console
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here
```

</details>


### Install tools

<details>

</details>


### Container runtime (CRI) and version (if applicable)

<details>

</details>


### Related plugins (CNI, CSI, ...) and versions (if applicable)

<details>

</details>



Discussion / hints:
/sig api-machinery
If I am wrong, I would appreciate correction.
> If kubernetes decide to require InvolvedObject field for event resource

That's indicated currently

> [...] I feel we need to add more validation.

This isn't super actionable? 
> That's indicated currently
> This isn't super actionable?

Sorry for the confusing way of writing this. It is currently an `optional` field in the API definition, so I thought it would be better to clarify this if it were to be made mandatory.

https://github.com/kubernetes/kubernetes/blob/08382213e83b5e90cbfb9465d48ba67d51e7a7a0/pkg/apis/core/types.go#L5686
Thanks for clarifying, we discussed in the API Machinery triage meeting, we should fix this consistency issue.

cc @liggitt , it seems like ever since https://github.com/kubernetes/kubernetes/commit/5b7edc1aa673a1e69835c48087bfa1a6ee42564b the involved object is defacto required?

It seems like the two options are:
1. add a nil check and make it actually optional (and potentially break ecosystem expecting involvedObject)
2. mark involvedObject required
/triage accepted
We wouldn't relax existing validation. I'm not sure I see the issue here.

The involvedObject field in the v1 API (which is where openapi schemas, etc, are generated) is already marked as required:

https://github.com/kubernetes/kubernetes/blob/04bba3c222bb2c5b1b1565713de4bf334ee7fbe4/staging/src/k8s.io/api/core/v1/types.go#L6881-L6882

and that is shown in the openapi schema:
```json
      "required": [
        "metadata",
        "involvedObject"
      ],
```
we can drop `// +optional` from the internal Event type if we want, but that won't change any behavior anywhere in the system
Thanks.

> we can drop // +optional from the internal Event type if we want, but that won't change any behavior anywhere in the system

Makes sense, it might reduce further user confusion though.
We were similarly confused running through this in the SIG API Machinery triage call 😅 
/assign
```
(base) ➜  kubernetes git:(master) kubectl explain events
..skipped..
  involvedObject	<ObjectReference> -required-
    The object that this event is about.
..skipped..

(base) ➜  kubernetes git:(master) kubectl explain events --api-version=events.k8s.io/v1
..skipped..
  regarding	<ObjectReference>
    regarding contains the object this Event is about. In most cases it's an
    Object reporting controller implements, e.g. ReplicaSetController implements
    ReplicaSets and this event is emitted because it acts on some changes in a
    ReplicaSet object.
..skipped..
```

the `regarding` field will be converted to `involvedObject` field of the internal object. Should we also drop the `//option` mark to make `regarding` as required? 

I looked at https://github.com/kubernetes/kubernetes/pull/49112 and there was no existing discussion about this field, it was introduced as an optional field. I don't know the reason.

@liggitt 

Fix patch:
diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go
index 96e9b0a5c6e92..ec2fbc6fb4d3c 100644
--- a/pkg/apis/core/types.go
+++ b/pkg/apis/core/types.go
@@ -5683,7 +5683,6 @@ type Event struct {
 	metav1.ObjectMeta
 
 	// The object that this event is about. Mapped to events.Event.regarding
-	// +optional
 	InvolvedObject ObjectReference
 
 	// Optional; this should be a short, machine understandable string that gives the reason


Test patch: