-
Notifications
You must be signed in to change notification settings - Fork 88
kopf can't post events #164
Comments
@olivier-mauras Thanks for reporting. I fought with this issue few times, to no avail. Brief summary: K8s events are namespaced, there are no cluster-scoped events. Also, k8s events can refer to an object via I could not find a way to post namespaced events for cluster-scoped resources. It always fails with namespace mismatch (regardless of which library is used). For an isolated example, here is an attempt to do this for minikube start
curl -i \
--cacert ~/.minikube/ca.crt --cert ~/.minikube/client.crt --key ~/.minikube/client.key \
-X POST -H "Content-Type: application/json" \
https://192.168.64.15:8443/api/v1/namespaces/default/events \
-d '{
"metadata": {"namespace": "default", "generateName": "kopf-event-"},
"action": "Action?", "type": "SomeType", "reason": "SomeReason", "message": "Some message", "reportingComponent": "kopf", "reportingInstance": "dev", "source": {"component": "kopf"},
"firstTimestamp": "2019-08-05T16:44:56.078476Z", "lastTimestamp": "2019-08-05T16:44:56.078476Z", "eventTime": "2019-08-05T16:44:56.078476Z",
"involvedObject": {"kind": "Node", "name": "minikube", "uid": "minikube"}}'
HTTP/2 422
content-type: application/json
content-length: 532
date: Mon, 05 Aug 2019 17:19:09 GMT
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "Event \"kopf-event-8h65p\" is invalid: involvedObject.namespace: Invalid value: \"\": does not match event.namespace",
"reason": "Invalid",
"details": {
"name": "kopf-event-8h65p",
"kind": "Event",
"causes": [
{
"reason": "FieldValueInvalid",
"message": "Invalid value: \"\": does not match event.namespace",
"field": "involvedObject.namespace"
}
]
},
"code": 422
} If I assign a namespace to the involved object, in the assumption that the cluster-scoped object kind of "exists" in all namespaces at once, then the event is created. However, it is not shown on Surprisingly, in the same minikube deployment, I can see such events for kubectl get events -o yaml | less - apiVersion: v1
count: 1
eventTime: null
firstTimestamp: "2019-08-05T16:38:01Z"
involvedObject:
kind: Node
name: minikube
uid: minikube
kind: Event
lastTimestamp: "2019-08-05T16:38:01Z"
message: Starting kubelet.
metadata:
creationTimestamp: "2019-08-05T16:38:11Z"
name: minikube.15b8143362eeb00f
namespace: default
resourceVersion: "193"
selfLink: /api/v1/namespaces/default/events/minikube.15b8143362eeb00f
uid: d23980be-d745-40c7-8378-656fe2b31cb7
reason: Starting
reportingComponent: ""
reportingInstance: ""
source:
component: kubelet
host: minikube
type: Normal So, conceptually it is possible for a namespaced event to refer to a non-namespaced object. But the API does not allow to do this, or I do it somehow wrong. The API documentation gives no clues on how to post such events. Any help on how such events can or should be posted, is welcomed. What I can do here, is to fix a little bit, to post the events to the current context's namespace (i.e. with the broken link, as explained above). At least, they will be visible there via |
@nolar Thanks for your extended reply. Right now my controller is handling namespaces creations/update. For each namespace handled, the controller will create a set of predefined namespaced resources - service acounts, network policies. I've seen your other comments about handling children deletions and indeed I thought it would be smart and as non convoluted as possible to have an on.delete handler for the children resources that would actually send a "delete" event to the namespace. So here's my code @kopf.on.delete('', 'v1', 'serviceaccounts', annotations={'custom/created_by': 'namespace-manager'})
async def sa_delete(body, namespace, **kwargs):
try:
api = kubernetes.client.CoreV1Api()
ns = api.read_namespace(name=namespace)
except ApiException as err:
sprint('ERROR', 'Exception when calling CoreV1Api->read_namespace: {}'.format(err))
kopf.info(ns.to_dict(), reason='SA_DELETED', message='Managed service account got deleted')
return And so here's the problem with the event not working is that I can't "notify" the namespace of the modification. |
Answering myself, something along the following that you posted in #153 would certainly work well @kopf.on.event('', 'v1', 'services')
def service_event(meta, name, namespace, event, **_):
# filter out irrelevant services
if not meta.get('labels', {}).get('my-app'):
return
# Now, it is surely our service.
# NB: the old service is already absent at this event, so there will be no HTTP 409 conflict.
if event['type'] == 'DELETED':
_recreate_service(name, namespace) |
@olivier-mauras Ah, I see your point. Just to clarify: Kopf is not a K8s client library, and is not going to be such. It only tries to be friendly to all existing K8s client libraries, leaving this choice to the developers. The k8s-events support in Kopf is rudimentary: only to the extent needed for K8s<->Python integration of per-object logging (i.e. Python's This is the main purpose of Kopf: to marshal K8s activities/structures into Python primitives/functions/libraries, and back from Python to K8s. Non-current object's logging is not intended as a feature (though, may work as a side effect, as in your example). If you need to post some other sophisticated events for some other objects, you can use a client library API calls directly. In case of |
@olivier-mauras Regarding the code example, please note, that label-filtering is now possible via the decorator kwargs, so that it will suppress excessive logging for not-matching objects: https://kopf.readthedocs.io/en/latest/handlers/#filtering |
@nolar Thanks for your clarification, as you say what I thought as a feature is more a side effect :) |
The changes are now in |
@nolar for what it's worth, I'm seeing this in 0.27rc6. Periodically I see the following messages in the logs:
I have a timer called MonitorTriadSets that's set to interval=3, idle=3. |
@nolar do you think this can be reopened since it appears to be occurring on timers? I'm not sure if there's a newer version maybe, but it seems the project hasn't been updated in many months. |
For me, adding the following to my ClusterRole solved this.
I recognize that if you bind to cluster-admin, you should expect to be able to post events... but in my case I defined a custom ClusterRole for my operator. |
Expected Behavior
Be able to post events either custom of defaults.
Actual Behavior
Steps to Reproduce the Problem
No particular code is actually running
My controller is running with a cluster-admin role in it's own namespace.
A simple example like this gives the same result:
Run with:
kopf run --standalone ./example.py
Specifications
Python 3.7.4
The text was updated successfully, but these errors were encountered: