Add implementation plan for CLI and configuration test coverage

This commit is contained in:
2026-07-18 10:14:02 -05:00
parent 3c35124db4
commit 50191ee694
3 changed files with 715 additions and 8 deletions

View File

@@ -1,6 +1,7 @@
package config
import (
"reflect"
"strings"
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
@@ -126,17 +127,47 @@ func redactOptions(values map[string]any) map[string]any {
}
func redactOptionValue(value any) any {
switch typed := value.(type) {
case map[string]any:
return redactOptions(typed)
case []any:
items := make([]any, len(typed))
for i, item := range typed {
items[i] = redactOptionValue(item)
if value == nil {
return nil
}
reflected := reflect.ValueOf(value)
switch reflected.Kind() {
case reflect.Map:
if reflected.Type().Key().Kind() != reflect.String {
return value
}
if reflected.IsNil() {
return nil
}
out := make(map[string]any, reflected.Len())
iterator := reflected.MapRange()
for iterator.Next() {
key := iterator.Key().String()
if sensitiveConfigKey(key) {
out[key] = "[REDACTED]"
continue
}
out[key] = redactOptionValue(iterator.Value().Interface())
}
return out
case reflect.Slice:
if reflected.IsNil() {
return nil
}
if reflected.Type().Elem().Kind() == reflect.Uint8 {
out := reflect.MakeSlice(reflected.Type(), reflected.Len(), reflected.Len())
reflect.Copy(out, reflected)
return out.Interface()
}
fallthrough
case reflect.Array:
items := make([]any, reflected.Len())
for i := 0; i < reflected.Len(); i++ {
items[i] = redactOptionValue(reflected.Index(i).Interface())
}
return items
default:
return typed
return value
}
}

View File

@@ -117,6 +117,40 @@ func TestRedactedEffectiveConfigPayloadDoesNotAliasSource(t *testing.T) {
assertRedactionTestBindingUnchanged(t, effective.ResolvedPipeline.Input, "effective")
}
func TestRedactedResolvedPipelinePayloadHandlesTypedOptionContainers(t *testing.T) {
type optionMap map[string]string
type optionList []optionMap
typed := optionList{{
"api_key": "typed-container-secret",
"safe": "typed-container-safe",
}}
effective := EffectiveConfig{ResolvedPipeline: pipeline.ResolvedPipeline{
Input: pipeline.ModuleBinding{Options: map[string]any{"nested": typed}},
}}
payload := effective.RedactedResolvedPipelinePayload()
nested, ok := payload.Input.Options["nested"].([]any)
if !ok || len(nested) != 1 {
t.Fatalf("redacted typed list = %#v", payload.Input.Options["nested"])
}
item, ok := nested[0].(map[string]any)
if !ok {
t.Fatalf("redacted typed map = %#v", nested[0])
}
if got := item["api_key"]; got != "[REDACTED]" {
t.Fatalf("redacted api_key = %v", got)
}
if got := item["safe"]; got != "typed-container-safe" {
t.Fatalf("safe option = %v", got)
}
item["safe"] = "mutated"
if got := typed[0]["safe"]; got != "typed-container-safe" {
t.Fatalf("source typed map mutated through redacted payload: %q", got)
}
}
func redactionTestBinding(name string) pipeline.ModuleBinding {
return pipeline.ModuleBinding{
Module: "safe-" + name,