entry is a helper function that checks the json tags to make sure all fields are tracked. And no excess fields are tracked.
(v any, f map[string]Action)
| 489 | // entry is a helper function that checks the json tags to make sure all fields |
| 490 | // are tracked. And no excess fields are tracked. |
| 491 | func entry(v any, f map[string]Action) (string, map[string]Action) { |
| 492 | vt := reflect.TypeOf(v) |
| 493 | for vt.Kind() == reflect.Ptr { |
| 494 | vt = vt.Elem() |
| 495 | } |
| 496 | |
| 497 | // This should never happen because audit.Audible only allows structs in |
| 498 | // its union. |
| 499 | if vt.Kind() != reflect.Struct { |
| 500 | panic(fmt.Sprintf("audit table entry value must be a struct, got %T", v)) |
| 501 | } |
| 502 | |
| 503 | name := structName(vt) |
| 504 | |
| 505 | // Use the flattenStructFields to recurse anonymously embedded structs |
| 506 | vv := reflect.ValueOf(v) |
| 507 | diffs, err := flattenStructFields(vv, vv) |
| 508 | if err != nil { |
| 509 | panic(fmt.Sprintf("audit table entry type %T failed to flatten", v)) |
| 510 | } |
| 511 | |
| 512 | fcpy := make(map[string]Action, len(f)) |
| 513 | for k, v := range f { |
| 514 | fcpy[k] = v |
| 515 | } |
| 516 | for _, d := range diffs { |
| 517 | jsonTag := d.FieldType.Tag.Get("json") |
| 518 | if jsonTag == "-" { |
| 519 | // This field is explicitly ignored. |
| 520 | continue |
| 521 | } |
| 522 | jsonTag = strings.TrimSuffix(jsonTag, ",omitempty") |
| 523 | if _, ok := fcpy[jsonTag]; !ok { |
| 524 | _, _ = fmt.Fprintf(os.Stderr, "ERROR: Audit table entry missing action for field %q in type %q\nPlease update the auditable resource types in: %s\n", d.FieldType.Name, name, self()) |
| 525 | //nolint:revive |
| 526 | os.Exit(1) |
| 527 | } |
| 528 | delete(fcpy, jsonTag) |
| 529 | } |
| 530 | |
| 531 | // If there are any fields left in fcpy, they are extra fields that don't |
| 532 | // exist in the struct. Don't track them. |
| 533 | if len(fcpy) > 0 { |
| 534 | panic(fmt.Sprintf("audit table entry has extra actions for type %q: %v", name, fcpy)) |
| 535 | } |
| 536 | |
| 537 | return structName(vt), f |
| 538 | } |
| 539 | |
| 540 | func (t Action) String() string { |
| 541 | return string(t) |
no test coverage detected