1414package observability
1515
1616import (
17+ "context"
1718 "fmt"
1819 "strings"
1920
@@ -22,7 +23,10 @@ import (
2223 "github.com/aws/aws-node-termination-handler/pkg/monitor/scheduledevent"
2324 "github.com/aws/aws-node-termination-handler/pkg/monitor/spotitn"
2425 "github.com/aws/aws-node-termination-handler/pkg/monitor/sqsevent"
26+ "github.com/rs/zerolog/log"
2527 corev1 "k8s.io/api/core/v1"
28+ kErr "k8s.io/apimachinery/pkg/api/errors"
29+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2630 "k8s.io/client-go/kubernetes"
2731 "k8s.io/client-go/kubernetes/scheme"
2832 typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -70,7 +74,9 @@ const (
7074// K8sEventRecorder wraps a Kubernetes event recorder with some extra information
7175type K8sEventRecorder struct {
7276 annotations map [string ]string
77+ clientSet * kubernetes.Clientset
7378 enabled bool
79+ sqsMode bool
7480 record.EventRecorder
7581}
7682
@@ -81,8 +87,8 @@ func InitK8sEventRecorder(enabled bool, nodeName string, sqsMode bool, nodeMetad
8187 }
8288
8389 annotations := make (map [string ]string )
90+ annotations ["account-id" ] = nodeMetadata .AccountId
8491 if ! sqsMode {
85- annotations ["account-id" ] = nodeMetadata .AccountId
8692 annotations ["availability-zone" ] = nodeMetadata .AvailabilityZone
8793 annotations ["instance-id" ] = nodeMetadata .InstanceID
8894 annotations ["instance-life-cycle" ] = nodeMetadata .InstanceLifeCycle
@@ -117,7 +123,9 @@ func InitK8sEventRecorder(enabled bool, nodeName string, sqsMode bool, nodeMetad
117123
118124 return K8sEventRecorder {
119125 annotations : annotations ,
126+ clientSet : clientSet ,
120127 enabled : true ,
128+ sqsMode : sqsMode ,
121129 EventRecorder : broadcaster .NewRecorder (
122130 scheme .Scheme ,
123131 corev1.EventSource {
@@ -131,12 +139,29 @@ func InitK8sEventRecorder(enabled bool, nodeName string, sqsMode bool, nodeMetad
131139// Emit a Kubernetes event for the given node and with the given event type, reason and message
132140func (r K8sEventRecorder ) Emit (nodeName string , eventType , eventReason , eventMsgFmt string , eventMsgArgs ... interface {}) {
133141 if r .enabled {
134- node := & corev1.ObjectReference {
135- Kind : "Node" ,
136- Name : nodeName ,
137- Namespace : "default" ,
142+ var node * corev1.Node
143+ var annotations map [string ]string
144+ if r .sqsMode {
145+ var err error
146+ node , err = r .clientSet .CoreV1 ().Nodes ().Get (context .Background (), nodeName , metav1.GetOptions {})
147+ if err != nil {
148+ if kErr .IsNotFound (err ) {
149+ return
150+ }
151+ log .Err (err ).Msg ("Emitting Kubernetes event failed" )
152+ return
153+ }
154+ annotations = generateNodeAnnotations (node , r .annotations )
155+ } else {
156+ node = & corev1.Node {
157+ ObjectMeta : metav1.ObjectMeta {
158+ Name : nodeName ,
159+ Namespace : "default" ,
160+ },
161+ }
162+ annotations = r .annotations
138163 }
139- r .AnnotatedEventf (node , r . annotations , eventType , eventReason , eventMsgFmt , eventMsgArgs ... )
164+ r .AnnotatedEventf (node , annotations , eventType , eventReason , eventMsgFmt , eventMsgArgs ... )
140165 }
141166}
142167
@@ -168,3 +193,35 @@ func parseExtraAnnotations(annotations map[string]string, extraAnnotationsStr st
168193 }
169194 return annotations , nil
170195}
196+
197+ // Generate annotations for an event occurred on the given node
198+ func generateNodeAnnotations (node * corev1.Node , annotations map [string ]string ) map [string ]string {
199+ nodeAnnotations := make (map [string ]string )
200+ for k , v := range annotations {
201+ nodeAnnotations [k ] = v
202+ }
203+ nodeAnnotations ["availability-zone" ] = node .Labels ["topology.kubernetes.io/zone" ]
204+ nodeAnnotations ["instance-id" ] = node .Spec .ProviderID [strings .LastIndex (node .Spec .ProviderID , "/" )+ 1 :]
205+ nodeAnnotations ["instance-type" ] = node .Labels ["node.kubernetes.io/instance-type" ]
206+ nodeAnnotations ["local-hostname" ] = node .Name
207+ for _ , address := range node .Status .Addresses {
208+ // If there's more than one address of the same type, use the first one
209+ switch address .Type {
210+ case corev1 .NodeInternalIP :
211+ if _ , exist := annotations ["local-ipv4" ]; ! exist {
212+ nodeAnnotations ["local-ipv4" ] = address .Address
213+ }
214+ case corev1 .NodeExternalDNS :
215+ if _ , exist := annotations ["public-hostname" ]; ! exist {
216+ nodeAnnotations ["public-hostname" ] = address .Address
217+ }
218+ case corev1 .NodeExternalIP :
219+ if _ , exist := annotations ["public-ipv4" ]; ! exist {
220+ nodeAnnotations ["public-ipv4" ] = address .Address
221+ }
222+ }
223+ }
224+ nodeAnnotations ["region" ] = node .Labels ["topology.kubernetes.io/region" ]
225+
226+ return nodeAnnotations
227+ }
0 commit comments