in pkg/util/kubernetes/portforward.go [38:121]
func PortForward(ctx context.Context, c client.Client, ns, labelSelector string, localPort, remotePort uint, stdOut, stdErr io.Writer) error {
log.InitForCmd()
var forwardPod *corev1.Pod
forwardCtx, forwardCtxCancel := context.WithCancel(ctx)
defer forwardCtxCancel()
setupPortForward := func(pod *corev1.Pod) error {
if forwardPod == nil && podReady(pod) {
forwardPod = pod
log.Debugf("Setting up Port Forward for pod with name: %q\n", forwardPod.Name)
if _, err := portFowardPod(forwardCtx, c.GetConfig(), ns, forwardPod.Name, localPort, remotePort, stdOut, stdErr); err != nil {
return err
}
}
return nil
}
log.Debugf("First attempt to bootstrap Port Forward with LabelSelector: %v\n", labelSelector)
list, err := bootstrapPortForward(ctx, c, ns, labelSelector, setupPortForward)
if err != nil {
return err
}
log.Debugf("Instantiating pod event watcher with LabelSelector: %v and ResourceVersion: %v in namespace: %v\n", labelSelector, list.ResourceVersion, ns)
watcher, err := c.CoreV1().Pods(ns).Watch(ctx, metav1.ListOptions{
LabelSelector: labelSelector,
ResourceVersion: list.ResourceVersion,
})
if err != nil {
return err
}
events := watcher.ResultChan()
for {
select {
case <-ctx.Done():
return nil
case e, ok := <-events:
if !ok {
return nil
}
switch e.Type {
case watch.Added:
pod, ok := e.Object.(*corev1.Pod)
if !ok {
return fmt.Errorf("type assertion failed: %v", e.Object)
}
log.Debugf("Handling watch.Added event for pod with name: %v\n", pod.Name)
if err := setupPortForward(pod); err != nil {
return err
}
case watch.Modified:
pod, ok := e.Object.(*corev1.Pod)
if !ok {
return fmt.Errorf("type assertion failed: %v", e.Object)
}
log.Debugf("Handling watch.Modified event for pod with name: %v\n", pod.Name)
if err := setupPortForward(pod); err != nil {
return err
}
case watch.Deleted:
log.Debugf("Handling watch.Deleted event\n")
if forwardPod != nil && e.Object != nil {
deletedPod, ok := e.Object.(*corev1.Pod)
if !ok {
return fmt.Errorf("type assertion failed: %v", e.Object)
}
log.Debugf("Handling watch.Deleted event for pod with name: %v while Port Forward was active for pod with name: %v\n", deletedPod.Name, forwardPod.Name)
if deletedPod.Name == forwardPod.Name {
forwardPod = nil
log.Debugf("Handling watch.Deleted event, since the pod with Port Forward enabled has been deleted we try to bootstrap Port Forward with LabelSelector: %v\n", labelSelector)
_, err := bootstrapPortForward(ctx, c, ns, labelSelector, setupPortForward)
if err != nil {
return err
}
}
}
}
}
}
}