This would be really helpful, as I'm coming from another language. In particular, how to come about the dialer param here: https://github.com/kubernetes/client-go/blob/75399f68c88d27167979821ac280936cfb13cfd6/tools/portforward/portforward.go#L111
You can take a look at how kubectl use the equivalent packages in the main repo: https://github.com/kubernetes/kubernetes/blob/v1.6.0-alpha.0/pkg/kubectl/cmd/portforward.go#L107
This is still unclear. Did you mean we shouldn't use client-go to execute a port-forward ? @caesarxuchao
@gtaylor Please try this to obtain the dialer :
import(
"flag"
"fmt"
"os"
"path/filepath"
"net/http"
"net/url"
"strings"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/portforward"
"k8s.io/client-go/transport/spdy"
"k8s.io/client-go/util/homedir"
)
...
var kubeconfig *string
if home := homedir.HomeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else {
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
}
flag.Parse()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err)
}
roundTripper, upgrader, err := spdy.RoundTripperFor(config)
if err != nil {
panic(err)
}
path := fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/portforward", "default", podName)
hostIP := strings.TrimLeft(config.Host, "htps:/")
serverURL := url.URL{Scheme: "https", Path: path, Host: hostIP}
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: roundTripper}, http.MethodPost, &serverURL)
What about stopChan, readyChan, out and errOut, you can initialize them like this:
import "bytes"
stopChan, readyChan := make(chan struct{}, 1), make(chan struct{}, 1)
out, errOut := new(bytes.Buffer), new(bytes.Buffer)
The usage is following (with error handling simplified, you would probably want to add more context to the error messages, and/or use log messages instead of panics):
forwarder, err := portforward.New(dialer, ports, stopChan, readyChan, out, errOut)
if err != nil {
panic(err)
}
go func() {
for range readyChan { // Kubernetes will close this channel when it has something to tell us.
}
if len(errOut.String()) != 0 {
panic(errOut.String())
} else if len(out.String()) != 0 {
fmt.Println(out.String())
}
}()
if err = forwarder.ForwardPorts(); err != nil { // Locks until stopChan is closed.
panic(err)
}
Just close the stopChan when you don't need this connection anymore.
I am getting an error while trying the above code as error upgrading connection: resource "test" not found
An article on the topic:
https://gianarb.it/blog/programmatically-kube-port-forward-in-go
recommended read: #796 if you find any dataraces. I used the safe buffer implementation for the following gist:
Most helpful comment
@gtaylor Please try this to obtain the
dialer:What about
stopChan,readyChan,outanderrOut, you can initialize them like this:The usage is following (with error handling simplified, you would probably want to add more context to the error messages, and/or use log messages instead of panics):
Just close the
stopChanwhen you don't need this connection anymore.