-
Notifications
You must be signed in to change notification settings - Fork 0
/
portforward.go
executable file
·103 lines (88 loc) · 2.47 KB
/
portforward.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
Copyright (c) 2019 VMware, Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package portforward
import (
"io"
"net/http"
"net/url"
"k8s.io/client-go/rest"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/portforward"
"k8s.io/client-go/transport/spdy"
)
// Options contains all the options for running a port-forward
// <snip> from pkg/kubectl/cmd/portforward/portforward.go <snip>
type Options struct {
Config *restclient.Config
RESTClient rest.Interface
Address []string
Ports []string
PortForwarder portForwarder
StopChannel <-chan struct{}
ReadyChannel chan struct{}
PortsChannel chan []ForwardedPort
}
type portForwarder interface {
ForwardPorts(method string, url *url.URL, opts Options) error
}
type DefaultPortForwarder struct {
IOStreams
}
// IOStreams provides the standard names for iostreams. This is useful for embedding and for unit testing.
// Inconsistent and different names make it hard to read and review code
type IOStreams struct {
// In think, os.Stdin
In io.Reader
// Out think, os.Stdout
Out io.Writer
// ErrOut think, os.Stderr
ErrOut io.Writer
}
type ForwardedPort struct {
Local uint16
Remote uint16
}
func (f *DefaultPortForwarder) ForwardPorts(method string, url *url.URL, opts Options) error {
transport, upgrader, err := spdy.RoundTripperFor(opts.Config)
if err != nil {
return err
}
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
fw, err := portforward.NewOnAddresses(dialer, opts.Address, opts.Ports, opts.StopChannel, opts.ReadyChannel, f.Out, f.ErrOut)
if err != nil {
return err
}
// Wait for resolved ports to become available and send them on up
localPortsHandler(fw, opts)
// Forward and block
return fw.ForwardPorts()
}
// </snip> from pkg/kubectl/cmd/portforward/portforward.go </snip>
// localPortsHandler manages passing up the resolved local ports from the forwarder when
// they become available via the PortsChannel.
func localPortsHandler(fw *portforward.PortForwarder, opts Options) {
if fw == nil {
return
}
if opts.ReadyChannel != nil && opts.PortsChannel != nil {
go func() {
select {
case <-opts.ReadyChannel:
ports, err := fw.GetPorts()
if err != nil {
return // TODO
}
fp := make([]ForwardedPort, len(ports))
for i := range ports {
fp[i].Local = ports[i].Local
fp[i].Remote = ports[i].Remote
}
opts.PortsChannel <- fp
case <-opts.StopChannel:
return
}
}()
}
}