diff --git a/.travis.yml b/.travis.yml index 8aa2f891..2b0b6757 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ matrix: - python: "3.8-dev" before_script: - - scripts/minikube-for-travis.sh + - tools/minikube-for-travis.sh script: - pytest -v diff --git a/kopf/k8s/events.py b/kopf/k8s/events.py index bd4e9dff..8cb15a2a 100644 --- a/kopf/k8s/events.py +++ b/kopf/k8s/events.py @@ -12,10 +12,9 @@ def post_event(*, obj, type, reason, message=''): namespace = obj['metadata']['namespace'] # Object reference - similar to the owner reference, but different. - # TODO: reconstruct from `resource` once kind<->plural mapping is done. #57 ref = dict( - apiVersion=obj['apiVersion'], # resource.version - kind=obj['kind'], # resource.kind (~resource.plural) + apiVersion=obj['apiVersion'], + kind=obj['kind'], name=obj['metadata']['name'], uid=obj['metadata']['uid'], namespace=obj['metadata']['namespace'], @@ -25,27 +24,26 @@ def post_event(*, obj, type, reason, message=''): namespace=namespace, generate_name='kopf-event-', ) - body = kubernetes.client.V1beta1Event( + body = kubernetes.client.V1Event( metadata=meta, action='Action?', type=type, reason=reason, - note=message, - # message=message, + message=message, - reporting_controller='kopf', + reporting_component='kopf', reporting_instance='dev', - deprecated_source=kubernetes.client.V1EventSource(component='kopf'), # used in the "From" column in `kubectl describe`. + source=kubernetes.client.V1EventSource(component='kopf'), # used in the "From" column in `kubectl describe`. - regarding=ref, - # related=ref, + involved_object=ref, + first_timestamp=now.isoformat() + 'Z', # '2019-01-28T18:25:03.000000Z' -- seen in `kubectl describe ...` + last_timestamp=now.isoformat() + 'Z', # '2019-01-28T18:25:03.000000Z' - seen in `kubectl get events` event_time=now.isoformat() + 'Z', # '2019-01-28T18:25:03.000000Z' - deprecated_first_timestamp=now.isoformat() + 'Z', # used in the "Age" column in `kubectl describe`. ) - api = kubernetes.client.EventsV1beta1Api() + api = kubernetes.client.CoreV1Api() api.create_namespaced_event( namespace=namespace, body=body, diff --git a/tests/k8s/test_events.py b/tests/k8s/test_events.py new file mode 100644 index 00000000..c1a9949d --- /dev/null +++ b/tests/k8s/test_events.py @@ -0,0 +1,63 @@ +from asynctest import call, ANY +from kubernetes.client import V1Event as V1Event_orig +from kubernetes.client import V1EventSource as V1EventSource_orig +from kubernetes.client import V1ObjectMeta as V1ObjectMeta_orig +from kubernetes.client import V1beta1Event as V1beta1Event_orig + +from kopf.k8s.events import post_event + + +def test_posting(client_mock): + client_mock.V1Event = V1Event_orig + client_mock.V1beta1Event = V1beta1Event_orig + client_mock.V1EventSource = V1EventSource_orig + client_mock.V1ObjectMeta = V1ObjectMeta_orig + + result = object() + apicls_mock = client_mock.CoreV1Api + apicls_mock.return_value.create_namespaced_event.return_value = result + postfn_mock = apicls_mock.return_value.create_namespaced_event + + obj = {'apiVersion': 'group/version', + 'kind': 'kind', + 'metadata': {'namespace': 'ns', + 'name': 'name', + 'uid': 'uid'}} + post_event(obj=obj, type='type', reason='reason', message='message') + + assert postfn_mock.called + assert postfn_mock.call_count == 1 + assert postfn_mock.call_args_list == [call( + namespace='ns', # same as the object's namespace + body=ANY, + )] + + event: V1Event_orig = postfn_mock.call_args_list[0][1]['body'] + assert event.type == 'type' + assert event.reason == 'reason' + assert event.message == 'message' + assert event.source.component == 'kopf' + assert event.involved_object['apiVersion'] == 'group/version' + assert event.involved_object['kind'] == 'kind' + assert event.involved_object['namespace'] == 'ns' + assert event.involved_object['name'] == 'name' + assert event.involved_object['uid'] == 'uid' + + +def test_type_is_v1_not_v1beta1(client_mock, resource): + client_mock.V1Event = V1Event_orig + client_mock.V1beta1Event = V1beta1Event_orig + + apicls_mock = client_mock.CoreV1Api + postfn_mock = apicls_mock.return_value.create_namespaced_event + + obj = {'apiVersion': 'group/version', + 'kind': 'kind', + 'metadata': {'namespace': 'ns', + 'name': 'name', + 'uid': 'uid'}} + post_event(obj=obj, type='type', reason='reason', message='message') + + event = postfn_mock.call_args_list[0][1]['body'] + assert isinstance(event, V1Event_orig) + assert not isinstance(event, V1beta1Event_orig) diff --git a/scripts/minikube-for-travis.sh b/tools/minikube-for-travis.sh similarity index 90% rename from scripts/minikube-for-travis.sh rename to tools/minikube-for-travis.sh index 8ed74121..b98c3331 100755 --- a/scripts/minikube-for-travis.sh +++ b/tools/minikube-for-travis.sh @@ -17,6 +17,7 @@ touch $KUBECONFIG sudo minikube start \ --vm-driver=none \ --extra-config=apiserver.authorization-mode=RBAC \ + --extra-config=apiserver.runtime-config=events.k8s.io/v1beta1=false \ --kubernetes-version=v${KUBERNETES_VERSION} sudo chown -R travis: /home/travis/.minikube/