github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/k8s/target.go (about) 1 package k8s 2 3 import ( 4 "context" 5 "fmt" 6 7 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 "k8s.io/apimachinery/pkg/labels" 9 10 "github.com/pkg/errors" 11 12 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 13 "github.com/tilt-dev/tilt/pkg/model" 14 ) 15 16 func MustTarget(name model.TargetName, yaml string) model.K8sTarget { 17 kt, err := NewTargetForYAML(name, yaml, nil) 18 if err != nil { 19 panic(fmt.Errorf("MustTarget: %v", err)) 20 } 21 return kt 22 } 23 24 func NewTargetForEntities(name model.TargetName, entities []K8sEntity, locators []ImageLocator) (model.K8sTarget, error) { 25 entities = SortedEntities(entities) 26 yaml, err := SerializeSpecYAML(entities) 27 if err != nil { 28 return model.K8sTarget{}, err 29 } 30 31 applySpec := v1alpha1.KubernetesApplySpec{ 32 Cluster: v1alpha1.ClusterNameDefault, 33 DiscoveryStrategy: v1alpha1.KubernetesDiscoveryStrategyDefault, 34 YAML: yaml, 35 } 36 37 for _, locator := range locators { 38 if LocatorMatchesOne(locator, entities) { 39 applySpec.ImageLocators = append(applySpec.ImageLocators, locator.ToSpec()) 40 } 41 } 42 43 target, err := NewTarget(name, applySpec, model.PodReadinessIgnore, nil) 44 if err != nil { 45 return model.K8sTarget{}, err 46 } 47 return target, nil 48 } 49 50 func NewTargetForYAML(name model.TargetName, yaml string, locators []ImageLocator) (model.K8sTarget, error) { 51 entities, err := ParseYAMLFromString(yaml) 52 if err != nil { 53 return model.K8sTarget{}, err 54 } 55 return NewTargetForEntities(name, entities, locators) 56 } 57 58 func NewTarget( 59 name model.TargetName, 60 applySpec v1alpha1.KubernetesApplySpec, 61 podReadinessMode model.PodReadinessMode, 62 links []model.Link) (model.K8sTarget, error) { 63 64 kapp := &v1alpha1.KubernetesApply{Spec: applySpec} 65 err := kapp.Validate(context.TODO()) 66 if err != nil { 67 return model.K8sTarget{}, err.ToAggregate() 68 } 69 70 return model.K8sTarget{ 71 KubernetesApplySpec: applySpec, 72 Name: name, 73 PodReadinessMode: podReadinessMode, 74 Links: links, 75 }, nil 76 } 77 78 func ParseImageLocators(locators []v1alpha1.KubernetesImageLocator) ([]ImageLocator, error) { 79 result := []ImageLocator{} 80 for _, locator := range locators { 81 selector, err := ParseObjectSelector(locator.ObjectSelector) 82 if err != nil { 83 return nil, errors.Wrap(err, "parsing image locator") 84 } 85 86 if locator.Object != nil { 87 parsedLocator, err := NewJSONPathImageObjectLocator(selector, locator.Path, locator.Object.RepoField, locator.Object.TagField) 88 if err != nil { 89 return nil, errors.Wrap(err, "parsing image locator") 90 } 91 result = append(result, parsedLocator) 92 } else { 93 parsedLocator, err := NewJSONPathImageLocator(selector, locator.Path) 94 if err != nil { 95 return nil, errors.Wrap(err, "parsing image locator") 96 } 97 result = append(result, parsedLocator) 98 } 99 } 100 return result, nil 101 } 102 103 // PortForwardTemplateSpec creates a port-forward template if necessary. Returns nil if no port-forwards. 104 func PortForwardTemplateSpec(forwards []model.PortForward) *v1alpha1.PortForwardTemplateSpec { 105 if len(forwards) == 0 { 106 return nil 107 } 108 109 res := make([]v1alpha1.Forward, len(forwards)) 110 for i, fwd := range forwards { 111 res[i] = v1alpha1.Forward{ 112 LocalPort: int32(fwd.LocalPort), 113 ContainerPort: int32(fwd.ContainerPort), 114 Host: fwd.Host, 115 Name: fwd.Name, 116 Path: fwd.PathForAppend(), 117 } 118 } 119 return &v1alpha1.PortForwardTemplateSpec{ 120 Forwards: res, 121 } 122 } 123 124 func SetsAsLabelSelectors(sets []labels.Set) []metav1.LabelSelector { 125 var extraSelectors []metav1.LabelSelector 126 for _, s := range sets { 127 extraSelectors = append(extraSelectors, *metav1.SetAsLabelSelector(s)) 128 } 129 return extraSelectors 130 }