Skip to content

Commit

Permalink
Merge pull request #894 from humio/mike/streamline_diff_field
Browse files Browse the repository at this point in the history
Refactor diff field
  • Loading branch information
SaaldjorMike authored Dec 19, 2024
2 parents e55f8a0 + b99c2e0 commit 7b9f212
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 69 deletions.
114 changes: 68 additions & 46 deletions controllers/humioaction_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"reflect"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)] = "<redacted>"
diffMap["ingestToken"] = "<redacted>"
}
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)] = "<redacted>"
diffMap["genieKey"] = "<redacted>"
}
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)] = "<redacted>"
diffMap["apiUrl"] = "<redacted>"
}
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)] = "<redacted>"
diffMap["url"] = "<redacted>"
}
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)] = "<redacted>"
diffMap["apiToken"] = "<redacted>"
}
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)] = "<redacted>"
diffMap["notifyUrl"] = "<redacted>"
}
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)] = "<redacted>"
diffMap["headers"] = "<redacted>"
}
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)] = "<redacted>"
diffMap["url"] = "<redacted>"
}
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()
}
2 changes: 1 addition & 1 deletion controllers/humioaggregatealert_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion controllers/humioalert_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 25 additions & 5 deletions controllers/humiocluster_pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion controllers/humiofilteralert_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion controllers/humioingesttoken_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion controllers/humioparser_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion controllers/humiorepository_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion controllers/humioscheduledsearch_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion controllers/humioview_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 0 additions & 10 deletions internal/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit 7b9f212

Please sign in to comment.