Ctrl K
ComunidadGuías…

pkg/configrefs/reflector.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package configrefs

import (
	"cmp"
	"slices"
	"strings"

	"github.com/skyhook-io/radar/pkg/resourceid"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/validation"
)

const reflectorPrefix = "reflector.v1.k8s.emberstack.com/"

type Ref struct{ Kind, Namespace, Name string }

func (r Ref) Key() string { return resourceid.ResourceKey("", r.Kind, r.Namespace, r.Name) }

type Object struct {
	Ref
	Annotations map[string]string
}

func Metadata(kind string, obj metav1.Object) Object {
	return Object{Ref: Ref{kind, obj.GetNamespace(), obj.GetName()}, Annotations: obj.GetAnnotations()}
}

type Reflection struct{ Source, Mirror Ref }

type Reflections struct {
	Links      []Reflection
	Sources    map[Ref]bool
	Automatic  map[Ref]bool
	Unresolved map[Ref]bool
}

// BuildReflections resolves declared dependencies only between observed endpoints.
// It does not assert that the controller has synchronized their contents.
func BuildReflections(objects []Object) Reflections {
	result := Reflections{Sources: map[Ref]bool{}, Automatic: map[Ref]bool{}, Unresolved: map[Ref]bool{}}
	observed := map[Ref]bool{}
	for _, o := range objects {
		if o.Kind == "Secret" || o.Kind == "ConfigMap" {
			observed[o.Ref] = true
		}
	}
	seen := map[Reflection]bool{}
	for _, o := range objects {
		if !observed[o.Ref] {
			continue
		}
		if strings.EqualFold(o.Annotations[reflectorPrefix+"reflection-allowed"], "true") {
			result.Sources[o.Ref] = true
		}
		ns, name, ok := strings.Cut(o.Annotations[reflectorPrefix+"reflects"], "/")
		if !ok || len(validation.IsDNS1123Label(ns)) != 0 || len(validation.IsDNS1123Subdomain(name)) != 0 {
			continue
		}
		source := Ref{o.Kind, ns, name}
		if source == o.Ref {
			continue
		}
		if !observed[source] {
			result.Unresolved[o.Ref] = true
			continue
		}
		link := Reflection{Source: source, Mirror: o.Ref}
		result.Sources[source] = true
		if !seen[link] {
			result.Links = append(result.Links, link)
			seen[link] = true
		}
		if strings.EqualFold(o.Annotations[reflectorPrefix+"auto-reflects"], "true") {
			result.Automatic[o.Ref] = true
		}
	}
	slices.SortFunc(result.Links, func(a, b Reflection) int {
		if c := cmp.Compare(a.Source.Key(), b.Source.Key()); c != 0 {
			return c
		}
		return cmp.Compare(a.Mirror.Key(), b.Mirror.Key())
	})
	return result
}

func (r Reflections) PropagateUse(used map[Ref]bool) {
	parents := map[Ref][]Ref{}
	for _, link := range r.Links {
		parents[link.Mirror] = append(parents[link.Mirror], link.Source)
	}
	queue := make([]Ref, 0, len(used))
	for ref, yes := range used {
		if yes {
			queue = append(queue, ref)
		}
	}
	for i := 0; i < len(queue); i++ {
		for _, parent := range parents[queue[i]] {
			if !used[parent] {
				used[parent] = true
				queue = append(queue, parent)
			}
		}
	}
}