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  }