Skip to content

Commit a2f1f44

Browse files
committed
Adds npipe support for Windows connections
Signed-off-by: Justin Terry (VM) <[email protected]>
1 parent 9ea0f6c commit a2f1f44

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

pkg/kubelet/util/util.go

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package util
1919
import (
2020
"fmt"
2121
"net/url"
22+
"strings"
2223

2324
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2425
)
@@ -32,13 +33,24 @@ func FromApiserverCache(opts *metav1.GetOptions) {
3233
func parseEndpoint(endpoint string) (string, string, error) {
3334
u, err := url.Parse(endpoint)
3435
if err != nil {
36+
// Check that endpoint wasn't passed in the form \\.\pipe
37+
if strings.HasPrefix(endpoint, "\\\\.\\pipe") {
38+
return "npipe", endpoint, nil
39+
}
3540
return "", "", err
3641
}
3742

3843
if u.Scheme == "tcp" {
3944
return "tcp", u.Host, nil
4045
} else if u.Scheme == "unix" {
4146
return "unix", u.Path, nil
47+
} else if u.Scheme == "npipe" {
48+
host := u.Host
49+
if host == "" {
50+
host = "."
51+
}
52+
// u.Path will always have a leading / or it will be empty from the Parse.
53+
return "npipe", fmt.Sprintf("\\\\%s%s", host, strings.Replace(u.Path, "/", "\\", -1)), nil
4254
} else if u.Scheme == "" {
4355
return "", "", fmt.Errorf("Using %q as endpoint is deprecated, please consider using full url format", endpoint)
4456
} else {

pkg/kubelet/util/util_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,21 @@ func TestParseEndpoint(t *testing.T) {
3939
expectedProtocol: "tcp",
4040
expectedAddr: "localhost:15880",
4141
},
42+
{
43+
endpoint: "npipe://./pipe/mypipe",
44+
expectedProtocol: "npipe",
45+
expectedAddr: "\\\\.\\pipe\\mypipe",
46+
},
47+
{
48+
endpoint: "npipe:/pipe/mypipe2",
49+
expectedProtocol: "npipe",
50+
expectedAddr: "\\\\.\\pipe\\mypipe2",
51+
},
52+
{
53+
endpoint: "\\\\.\\pipe\\mypipe3",
54+
expectedProtocol: "npipe",
55+
expectedAddr: "\\\\.\\pipe\\mypipe3",
56+
},
4257
{
4358
endpoint: "tcp1://abc",
4459
expectedProtocol: "tcp1",

pkg/kubelet/util/util_windows.go

+22-7
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,42 @@ import (
2222
"fmt"
2323
"net"
2424
"time"
25+
26+
"github.com/Microsoft/go-winio"
2527
)
2628

2729
const (
28-
tcpProtocol = "tcp"
30+
tcpProtocol = "tcp"
31+
npipeProtocol = "npipe"
2932
)
3033

3134
func CreateListener(endpoint string) (net.Listener, error) {
3235
protocol, addr, err := parseEndpoint(endpoint)
3336
if err != nil {
3437
return nil, err
3538
}
36-
if protocol != tcpProtocol {
37-
return nil, fmt.Errorf("only support tcp endpoint")
39+
switch protocol {
40+
case tcpProtocol:
41+
return net.Listen(protocol, addr)
42+
case npipeProtocol:
43+
return winio.ListenPipe(addr, nil)
44+
default:
45+
return nil, fmt.Errorf("only support tcp or npipe endpoint")
3846
}
39-
40-
return net.Listen(protocol, addr)
4147
}
4248

4349
func GetAddressAndDialer(endpoint string) (string, func(addr string, timeout time.Duration) (net.Conn, error), error) {
4450
protocol, addr, err := parseEndpoint(endpoint)
4551
if err != nil {
4652
return "", nil, err
4753
}
48-
if protocol != tcpProtocol {
49-
return "", nil, fmt.Errorf("only support tcp endpoint")
54+
switch protocol {
55+
case tcpProtocol:
56+
return addr, dial, nil
57+
case npipeProtocol:
58+
return addr, dialPipe, nil
59+
default:
60+
return "", nil, fmt.Errorf("only support tcp or npipe endpoint")
5061
}
5162

5263
return addr, dial, nil
@@ -55,3 +66,7 @@ func GetAddressAndDialer(endpoint string) (string, func(addr string, timeout tim
5566
func dial(addr string, timeout time.Duration) (net.Conn, error) {
5667
return net.DialTimeout(tcpProtocol, addr, timeout)
5768
}
69+
70+
func dialPipe(addr string, timeout time.Duration) (net.Conn, error) {
71+
return winio.DialPipe(addr, &timeout)
72+
}

0 commit comments

Comments
 (0)