diff --git a/controllers/humioaction_controller.go b/controllers/humioaction_controller.go index 38cb4b8c..975679cd 100644 --- a/controllers/humioaction_controller.go +++ b/controllers/humioaction_controller.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "reflect" "time" "github.com/go-logr/logr" @@ -182,7 +183,7 @@ func (r *HumioActionReconciler) reconcileHumioAction(ctx context.Context, client if asExpected, diffKeysAndValues := actionAlreadyAsExpected(expectedAction, curAction); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) err = r.HumioClient.UpdateAction(ctx, client, req, ha) if err != nil { @@ -318,163 +319,184 @@ func (r *HumioActionReconciler) logErrorAndReturn(err error, msg string) error { // if the details from GraphQL already matches what is in the desired state of the custom resource. // If they do not match, a map is returned with details on what the diff is. func actionAlreadyAsExpected(expectedAction humiographql.ActionDetails, currentAction humiographql.ActionDetails) (bool, map[string]string) { - keyValues := map[string]string{} + diffMap := map[string]string{} + actionType := "unknown" switch e := (expectedAction).(type) { case *humiographql.ActionDetailsEmailAction: switch c := (currentAction).(type) { case *humiographql.ActionDetailsEmailAction: + actionType = getTypeString(e) if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { - keyValues[fmt.Sprintf("%T.name", e)] = diff + diffMap["name"] = diff } if diff := cmp.Diff(c.GetRecipients(), e.GetRecipients()); diff != "" { - keyValues[fmt.Sprintf("%T.recipients", e)] = diff + diffMap["recipients"] = diff } if diff := cmp.Diff(c.GetSubjectTemplate(), e.GetSubjectTemplate()); diff != "" { - keyValues[fmt.Sprintf("%T.subjectTemplate", e)] = diff + diffMap["subjectTemplate"] = diff } if diff := cmp.Diff(c.GetEmailBodyTemplate(), e.GetEmailBodyTemplate()); diff != "" { - keyValues[fmt.Sprintf("%T.bodyTemplate", e)] = diff + diffMap["bodyTemplate"] = diff } if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { - keyValues[fmt.Sprintf("%T.useProxy", e)] = diff + diffMap["useProxy"] = diff } default: - keyValues["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) + diffMap["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) } case *humiographql.ActionDetailsHumioRepoAction: switch c := (currentAction).(type) { case *humiographql.ActionDetailsHumioRepoAction: + actionType = getTypeString(e) if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { - keyValues[fmt.Sprintf("%T.name", e)] = diff + diffMap["name"] = diff } if diff := cmp.Diff(c.GetIngestToken(), e.GetIngestToken()); diff != "" { - keyValues[fmt.Sprintf("%T.ingestToken", e)] = "" + diffMap["ingestToken"] = "" } default: - keyValues["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) + diffMap["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) } case *humiographql.ActionDetailsOpsGenieAction: switch c := (currentAction).(type) { case *humiographql.ActionDetailsOpsGenieAction: + actionType = getTypeString(e) if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { - keyValues[fmt.Sprintf("%T.name", e)] = diff + diffMap["name"] = diff } if diff := cmp.Diff(c.GetApiUrl(), e.GetApiUrl()); diff != "" { - keyValues[fmt.Sprintf("%T.apiUrl", e)] = diff + diffMap["apiUrl"] = diff } if diff := cmp.Diff(c.GetGenieKey(), e.GetGenieKey()); diff != "" { - keyValues[fmt.Sprintf("%T.genieKey", e)] = "" + diffMap["genieKey"] = "" } if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { - keyValues[fmt.Sprintf("%T.useProxy", e)] = diff + diffMap["useProxy"] = diff } default: - keyValues["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) + diffMap["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) } case *humiographql.ActionDetailsPagerDutyAction: switch c := (currentAction).(type) { case *humiographql.ActionDetailsPagerDutyAction: + actionType = getTypeString(e) if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { - keyValues[fmt.Sprintf("%T.name", e)] = diff + diffMap["name"] = diff } if diff := cmp.Diff(c.GetRoutingKey(), e.GetRoutingKey()); diff != "" { - keyValues[fmt.Sprintf("%T.apiUrl", e)] = "" + diffMap["apiUrl"] = "" } if diff := cmp.Diff(c.GetSeverity(), e.GetSeverity()); diff != "" { - keyValues[fmt.Sprintf("%T.genieKey", e)] = diff + diffMap["genieKey"] = diff } if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { - keyValues[fmt.Sprintf("%T.useProxy", e)] = diff + diffMap["useProxy"] = diff } default: - keyValues["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) + diffMap["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) } case *humiographql.ActionDetailsSlackAction: switch c := (currentAction).(type) { case *humiographql.ActionDetailsSlackAction: + actionType = getTypeString(e) if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { - keyValues[fmt.Sprintf("%T.name", e)] = diff + diffMap["name"] = diff } if diff := cmp.Diff(c.GetFields(), e.GetFields()); diff != "" { - keyValues[fmt.Sprintf("%T.fields", e)] = diff + diffMap["fields"] = diff } if diff := cmp.Diff(c.GetUrl(), e.GetUrl()); diff != "" { - keyValues[fmt.Sprintf("%T.url", e)] = "" + diffMap["url"] = "" } if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { - keyValues[fmt.Sprintf("%T.useProxy", e)] = diff + diffMap["useProxy"] = diff } default: - keyValues["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) + diffMap["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) } case *humiographql.ActionDetailsSlackPostMessageAction: switch c := (currentAction).(type) { case *humiographql.ActionDetailsSlackPostMessageAction: + actionType = getTypeString(e) if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { - keyValues[fmt.Sprintf("%T.name", e)] = diff + diffMap["name"] = diff } if diff := cmp.Diff(c.GetApiToken(), e.GetApiToken()); diff != "" { - keyValues[fmt.Sprintf("%T.apiToken", e)] = "" + diffMap["apiToken"] = "" } if diff := cmp.Diff(c.GetChannels(), e.GetChannels()); diff != "" { - keyValues[fmt.Sprintf("%T.channels", e)] = diff + diffMap["channels"] = diff } if diff := cmp.Diff(c.GetFields(), e.GetFields()); diff != "" { - keyValues[fmt.Sprintf("%T.fields", e)] = diff + diffMap["fields"] = diff } if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { - keyValues[fmt.Sprintf("%T.useProxy", e)] = diff + diffMap["useProxy"] = diff } default: - keyValues["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) + diffMap["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) } case *humiographql.ActionDetailsVictorOpsAction: switch c := (currentAction).(type) { case *humiographql.ActionDetailsVictorOpsAction: + actionType = getTypeString(e) if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { - keyValues[fmt.Sprintf("%T.name", e)] = diff + diffMap["name"] = diff } if diff := cmp.Diff(c.GetMessageType(), e.GetMessageType()); diff != "" { - keyValues[fmt.Sprintf("%T.messageType", e)] = diff + diffMap["messageType"] = diff } if diff := cmp.Diff(c.GetNotifyUrl(), e.GetNotifyUrl()); diff != "" { - keyValues[fmt.Sprintf("%T.notifyUrl", e)] = "" + diffMap["notifyUrl"] = "" } if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { - keyValues[fmt.Sprintf("%T.useProxy", e)] = diff + diffMap["useProxy"] = diff } default: - keyValues["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) + diffMap["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) } case *humiographql.ActionDetailsWebhookAction: switch c := (currentAction).(type) { case *humiographql.ActionDetailsWebhookAction: + actionType = getTypeString(e) if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { - keyValues[fmt.Sprintf("%T.name", e)] = diff + diffMap["name"] = diff } if diff := cmp.Diff(c.GetWebhookBodyTemplate(), e.GetWebhookBodyTemplate()); diff != "" { - keyValues[fmt.Sprintf("%T.bodyTemplate", e)] = diff + diffMap["bodyTemplate"] = diff } if diff := cmp.Diff(c.GetHeaders(), e.GetHeaders()); diff != "" { - keyValues[fmt.Sprintf("%T.headers", e)] = "" + diffMap["headers"] = "" } if diff := cmp.Diff(c.GetMethod(), e.GetMethod()); diff != "" { - keyValues[fmt.Sprintf("%T.method", e)] = diff + diffMap["method"] = diff } if diff := cmp.Diff(c.GetUrl(), e.GetUrl()); diff != "" { - keyValues[fmt.Sprintf("%T.url", e)] = "" + diffMap["url"] = "" } if diff := cmp.Diff(c.GetIgnoreSSL(), e.GetIgnoreSSL()); diff != "" { - keyValues[fmt.Sprintf("%T.ignoreSSL", e)] = diff + diffMap["ignoreSSL"] = diff } if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { - keyValues[fmt.Sprintf("%T.useProxy", e)] = diff + diffMap["useProxy"] = diff } default: - keyValues["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) + diffMap["wrongType"] = fmt.Sprintf("expected type %T but current is %T", e, c) } } - return len(keyValues) == 0, keyValues + diffMapWithTypePrefix := map[string]string{} + for k, v := range diffMap { + diffMapWithTypePrefix[fmt.Sprintf("%s.%s", actionType, k)] = v + } + return len(diffMapWithTypePrefix) == 0, diffMapWithTypePrefix +} + +func getTypeString(arg interface{}) string { + t := reflect.TypeOf(arg) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t.String() } diff --git a/controllers/humioaggregatealert_controller.go b/controllers/humioaggregatealert_controller.go index e73f2eea..5371a351 100644 --- a/controllers/humioaggregatealert_controller.go +++ b/controllers/humioaggregatealert_controller.go @@ -179,7 +179,7 @@ func (r *HumioAggregateAlertReconciler) reconcileHumioAggregateAlert(ctx context if asExpected, diffKeysAndValues := aggregateAlertAlreadyAsExpected(haa, curAggregateAlert); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) updateErr := r.HumioClient.UpdateAggregateAlert(ctx, client, req, haa) if updateErr != nil { diff --git a/controllers/humioalert_controller.go b/controllers/humioalert_controller.go index 9bfd527a..e0d5c80d 100644 --- a/controllers/humioalert_controller.go +++ b/controllers/humioalert_controller.go @@ -166,7 +166,7 @@ func (r *HumioAlertReconciler) reconcileHumioAlert(ctx context.Context, client * if asExpected, diffKeysAndValues := alertAlreadyAsExpected(ha, curAlert); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) err = r.HumioClient.UpdateAlert(ctx, client, req, ha) if err != nil { diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index 68fa9137..0acdb7b8 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -720,23 +720,43 @@ func (r *HumioClusterReconciler) podsMatch(hnp *HumioNodePool, pod corev1.Pod, d sanitizedDesiredPod := sanitizePod(hnp, desiredPodCopy) podSpecDiff := cmp.Diff(sanitizedCurrentPod.Spec, sanitizedDesiredPod.Spec) if !specMatches { - r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", PodHashAnnotation, pod.Annotations[PodHashAnnotation], desiredPod.Annotations[PodHashAnnotation]), "podSpecDiff", podSpecDiff) + r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", + PodHashAnnotation, + pod.Annotations[PodHashAnnotation], desiredPod.Annotations[PodHashAnnotation]), + "diff", podSpecDiff, + ) return false } if !revisionMatches { - r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", PodRevisionAnnotation, pod.Annotations[PodRevisionAnnotation], desiredPod.Annotations[PodRevisionAnnotation]), "podSpecDiff", podSpecDiff) + r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", + PodRevisionAnnotation, + pod.Annotations[PodRevisionAnnotation], desiredPod.Annotations[PodRevisionAnnotation]), + "diff", podSpecDiff, + ) return false } if !bootstrapTokenAnnotationMatches { - r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", BootstrapTokenHashAnnotation, pod.Annotations[BootstrapTokenHashAnnotation], desiredPod.Annotations[BootstrapTokenHashAnnotation]), "podSpecDiff", podSpecDiff) + r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", + BootstrapTokenHashAnnotation, + pod.Annotations[BootstrapTokenHashAnnotation], desiredPod.Annotations[BootstrapTokenHashAnnotation]), + "diff", podSpecDiff, + ) return false } if !envVarSourceMatches { - r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", envVarSourceHashAnnotation, pod.Annotations[envVarSourceHashAnnotation], desiredPod.Annotations[envVarSourceHashAnnotation]), "podSpecDiff", podSpecDiff) + r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", + envVarSourceHashAnnotation, + pod.Annotations[envVarSourceHashAnnotation], desiredPod.Annotations[envVarSourceHashAnnotation]), + "diff", podSpecDiff, + ) return false } if !certHashAnnotationMatches { - r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", certHashAnnotation, pod.Annotations[certHashAnnotation], desiredPod.Annotations[certHashAnnotation]), "podSpecDiff", podSpecDiff) + r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", + certHashAnnotation, + pod.Annotations[certHashAnnotation], desiredPod.Annotations[certHashAnnotation]), + "diff", podSpecDiff, + ) return false } return true diff --git a/controllers/humiofilteralert_controller.go b/controllers/humiofilteralert_controller.go index 429bae2f..d260703a 100644 --- a/controllers/humiofilteralert_controller.go +++ b/controllers/humiofilteralert_controller.go @@ -177,7 +177,7 @@ func (r *HumioFilterAlertReconciler) reconcileHumioFilterAlert(ctx context.Conte if asExpected, diffKeysAndValues := filterAlertAlreadyAsExpected(hfa, curFilterAlert); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) updateErr := r.HumioClient.UpdateFilterAlert(ctx, client, req, hfa) if updateErr != nil { diff --git a/controllers/humioingesttoken_controller.go b/controllers/humioingesttoken_controller.go index f10f24df..014592b1 100644 --- a/controllers/humioingesttoken_controller.go +++ b/controllers/humioingesttoken_controller.go @@ -159,7 +159,7 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req if asExpected, diffKeysAndValues := ingestTokenAlreadyAsExpected(hit, curToken); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) err = r.HumioClient.UpdateIngestToken(ctx, humioHttpClient, req, hit) if err != nil { diff --git a/controllers/humioparser_controller.go b/controllers/humioparser_controller.go index 3d46a456..580f2f45 100644 --- a/controllers/humioparser_controller.go +++ b/controllers/humioparser_controller.go @@ -157,7 +157,7 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) if asExpected, diffKeysAndValues := parserAlreadyAsExpected(hp, curParser); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) err = r.HumioClient.UpdateParser(ctx, humioHttpClient, req, hp) if err != nil { diff --git a/controllers/humiorepository_controller.go b/controllers/humiorepository_controller.go index f50865fc..6236518c 100644 --- a/controllers/humiorepository_controller.go +++ b/controllers/humiorepository_controller.go @@ -156,7 +156,7 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ if asExpected, diffKeysAndValues := repositoryAlreadyAsExpected(hr, curRepository); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) err = r.HumioClient.UpdateRepository(ctx, humioHttpClient, req, hr) if err != nil { diff --git a/controllers/humioscheduledsearch_controller.go b/controllers/humioscheduledsearch_controller.go index 81a2f2d6..e10881d3 100644 --- a/controllers/humioscheduledsearch_controller.go +++ b/controllers/humioscheduledsearch_controller.go @@ -166,7 +166,7 @@ func (r *HumioScheduledSearchReconciler) reconcileHumioScheduledSearch(ctx conte if asExpected, diffKeysAndValues := scheduledSearchAlreadyAsExpected(hss, curScheduledSearch); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) updateErr := r.HumioClient.UpdateScheduledSearch(ctx, client, req, hss) if updateErr != nil { diff --git a/controllers/humioview_controller.go b/controllers/humioview_controller.go index 9fde2323..b5e69d46 100644 --- a/controllers/humioview_controller.go +++ b/controllers/humioview_controller.go @@ -156,7 +156,7 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if asExpected, diffKeysAndValues := viewAlreadyAsExpected(hv, curView); !asExpected { r.Log.Info("information differs, triggering update", - helpers.MapToAnySlice(diffKeysAndValues)..., + "diff", diffKeysAndValues, ) updateErr := r.HumioClient.UpdateView(ctx, humioHttpClient, req, hv) if updateErr != nil { diff --git a/internal/helpers/helpers.go b/internal/helpers/helpers.go index e82a675c..3ade7ae9 100644 --- a/internal/helpers/helpers.go +++ b/internal/helpers/helpers.go @@ -184,13 +184,3 @@ func GetE2ELicenseFromEnvVar() string { func PreserveKindCluster() bool { return os.Getenv("PRESERVE_KIND_CLUSTER") == "true" } - -// MapToAnySlice converts a given map[string]string and converts it to []any. -// This is useful when e.g. passing on key-value pairs to a logger. -func MapToAnySlice(m map[string]string) []any { - result := make([]any, 0, len(m)*2) - for k, v := range m { - result = append(result, k, v) - } - return result -}