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  }