github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/k8s/state.go (about) 1 package k8s 2 3 import ( 4 "fmt" 5 "strings" 6 7 "go.starlark.net/starlark" 8 v1 "k8s.io/api/core/v1" 9 10 "github.com/tilt-dev/tilt/internal/k8s" 11 ) 12 13 const fmtDuplicateYAMLDetectedError = `Duplicate YAML: %s 14 Ignore this error with k8s_yaml(..., allow_duplicates=True) 15 YAML originally registered at: %s` 16 17 func DuplicateYAMLDetectedError(id, stackTrace string) error { 18 indentedTrace := strings.Join(strings.Split(stackTrace, "\n"), "\n ") 19 return fmt.Errorf(fmtDuplicateYAMLDetectedError, id, indentedTrace) 20 } 21 22 type ObjectSpec struct { 23 // The resource spec 24 Entity k8s.K8sEntity 25 26 // The stack trace where this resource was registered. 27 // Helpful for reporting duplicates. 28 StackTrace string 29 } 30 31 // Keeps track of all the Kubernetes objects registered during Tiltfile Execution. 32 type State struct { 33 ObjectSpecRefs []v1.ObjectReference 34 ObjectSpecIndex map[v1.ObjectReference]ObjectSpec 35 } 36 37 func NewState() *State { 38 return &State{ 39 ObjectSpecIndex: make(map[v1.ObjectReference]ObjectSpec), 40 } 41 } 42 43 func (s *State) Entities() []k8s.K8sEntity { 44 result := make([]k8s.K8sEntity, len(s.ObjectSpecIndex)) 45 for i, ref := range s.ObjectSpecRefs { 46 result[i] = s.ObjectSpecIndex[ref].Entity 47 } 48 return result 49 } 50 51 func (s *State) EntityCount() int { 52 return len(s.ObjectSpecIndex) 53 } 54 55 func (s *State) Append(t *starlark.Thread, entities []k8s.K8sEntity, dupesOK bool) error { 56 stackTrace := t.CallStack().String() 57 for _, e := range entities { 58 ref := e.ToObjectReference() 59 old, exists := s.ObjectSpecIndex[ref] 60 if exists && !dupesOK { 61 humanRef := "" 62 if ref.Namespace == "" { 63 humanRef = fmt.Sprintf("%s %s", ref.Kind, ref.Name) 64 } else { 65 humanRef = fmt.Sprintf("%s %s (Namespace: %s)", ref.Kind, ref.Name, ref.Namespace) 66 } 67 return DuplicateYAMLDetectedError(humanRef, old.StackTrace) 68 } 69 70 if !exists { 71 s.ObjectSpecRefs = append(s.ObjectSpecRefs, ref) 72 } 73 s.ObjectSpecIndex[ref] = ObjectSpec{ 74 Entity: e, 75 StackTrace: stackTrace, 76 } 77 } 78 return nil 79 }