types/netmap: remove PrivateKey from NetworkMap
It's an unnecessary nuisance having it. We go out of our way to redact it in so many places when we don't even need it there anyway. Updates #12639 Change-Id: I5fc72e19e9cf36caeb42cf80ba430873f67167c3 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
98aadbaf54
commit
653d0738f9
@@ -0,0 +1,106 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package typewalk provides utilities to walk Go types using reflection.
|
||||
package typewalk
|
||||
|
||||
import (
|
||||
"iter"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Path describes a path via a type where a private key may be found,
|
||||
// along with a function to test whether a reflect.Value at that path is
|
||||
// non-zero.
|
||||
type Path struct {
|
||||
// Name is the path from the root type, suitable for using as a t.Run name.
|
||||
Name string
|
||||
|
||||
// Walk returns the reflect.Value at the end of the path, given a root
|
||||
// reflect.Value.
|
||||
Walk func(root reflect.Value) (leaf reflect.Value)
|
||||
}
|
||||
|
||||
// MatchingPaths returns a sequence of [Path] for all paths
|
||||
// within the given type that end in a type matching match.
|
||||
func MatchingPaths(rt reflect.Type, match func(reflect.Type) bool) iter.Seq[Path] {
|
||||
// valFromRoot is a function that, given a reflect.Value of the root struct,
|
||||
// returns the reflect.Value at some path within it.
|
||||
type valFromRoot func(reflect.Value) reflect.Value
|
||||
|
||||
return func(yield func(Path) bool) {
|
||||
var walk func(reflect.Type, valFromRoot)
|
||||
var path []string
|
||||
var done bool
|
||||
seen := map[reflect.Type]bool{}
|
||||
|
||||
walk = func(t reflect.Type, getV valFromRoot) {
|
||||
if seen[t] {
|
||||
return
|
||||
}
|
||||
seen[t] = true
|
||||
defer func() { seen[t] = false }()
|
||||
if done {
|
||||
return
|
||||
}
|
||||
if match(t) {
|
||||
if !yield(Path{
|
||||
Name: strings.Join(path, "."),
|
||||
Walk: getV,
|
||||
}) {
|
||||
done = true
|
||||
}
|
||||
return
|
||||
}
|
||||
switch t.Kind() {
|
||||
case reflect.Ptr, reflect.Slice, reflect.Array:
|
||||
walk(t.Elem(), func(root reflect.Value) reflect.Value {
|
||||
v := getV(root)
|
||||
return v.Elem()
|
||||
})
|
||||
case reflect.Struct:
|
||||
for i := range t.NumField() {
|
||||
sf := t.Field(i)
|
||||
fieldName := sf.Name
|
||||
if fieldName == "_" {
|
||||
continue
|
||||
}
|
||||
path = append(path, fieldName)
|
||||
walk(sf.Type, func(root reflect.Value) reflect.Value {
|
||||
return getV(root).FieldByName(fieldName)
|
||||
})
|
||||
path = path[:len(path)-1]
|
||||
if done {
|
||||
return
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
walk(t.Elem(), func(root reflect.Value) reflect.Value {
|
||||
v := getV(root)
|
||||
if v.Len() == 0 {
|
||||
return reflect.Zero(t.Elem())
|
||||
}
|
||||
iter := v.MapRange()
|
||||
iter.Next()
|
||||
return iter.Value()
|
||||
})
|
||||
if done {
|
||||
return
|
||||
}
|
||||
walk(t.Key(), func(root reflect.Value) reflect.Value {
|
||||
v := getV(root)
|
||||
if v.Len() == 0 {
|
||||
return reflect.Zero(t.Key())
|
||||
}
|
||||
iter := v.MapRange()
|
||||
iter.Next()
|
||||
return iter.Key()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
path = append(path, rt.Name())
|
||||
walk(rt, func(v reflect.Value) reflect.Value { return v })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user