Skip to content

Commit

Permalink
fix: etcd client terseness
Browse files Browse the repository at this point in the history
These changes surface the connection error that occurs inside the etcd
client when a misconfiguration occurs (such as invalid TLS certificates,
or an `address` that does not match one of the valid SANs).
  • Loading branch information
sethp-nr committed Feb 28, 2020
1 parent 1435eed commit 5f1af73
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 13 deletions.
39 changes: 35 additions & 4 deletions controlplane/kubeadm/internal/proxy/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,32 @@ limitations under the License.
package proxy

import (
"fmt"
"io"
"io/ioutil"
"net"
"time"

"k8s.io/apimachinery/pkg/util/httpstream"
"k8s.io/apimachinery/pkg/util/runtime"
)

// Conn is a Kubernetes API server proxied type of net/conn
type Conn struct {
stream httpstream.Stream
errChan chan error
readDeadline time.Time
writeDeadline time.Time
}

// Read from the connection
func (c Conn) Read(b []byte) (n int, err error) {
return c.stream.Read(b)
select {
case err := <-c.errChan:
return 0, err
default:
return c.stream.Read(b)
}
}

// Close the underlying proxied connection
Expand All @@ -42,7 +52,12 @@ func (c Conn) Close() error {

// Write to the connection
func (c Conn) Write(b []byte) (n int, err error) {
return c.stream.Write(b)
select {
case err := <-c.errChan:
return 0, err
default:
return c.stream.Write(b)
}
}

// Return a fake address representing the proxied connection
Expand Down Expand Up @@ -77,8 +92,24 @@ func (c Conn) SetReadDeadline(t time.Time) error {

// NewConn creates a new net/conn interface based on an underlying Kubernetes
// API server proxy connection
func NewConn(stream httpstream.Stream) Conn {
func NewConn(stream httpstream.Stream, errorStream httpstream.Stream) Conn {
errChan := make(chan error)

go func() {
defer runtime.HandleCrash()

message, err := ioutil.ReadAll(errorStream)
switch {
case err != nil && err != io.EOF:
errChan <- fmt.Errorf("error reading from error stream: %s", err)
case len(message) > 0:
errChan <- fmt.Errorf("read error from stream: %s", string(message))
}
close(errChan)
}()

return Conn{
stream: stream,
stream: stream,
errChan: errChan,
}
}
4 changes: 2 additions & 2 deletions controlplane/kubeadm/internal/proxy/dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (d *Dialer) DialContextWithAddr(ctx context.Context, addr string) (net.Conn

// DialContext creates proxied port-forwarded connections.
// ctx is currently unused, but fulfils the type signature used by GRPC.
func (d *Dialer) DialContext(_ context.Context, network string, addr string) (net.Conn, error) {
func (d *Dialer) DialContext(_ context.Context, network string, _ string) (net.Conn, error) {
req := d.clientset.CoreV1().RESTClient().
Post().
Resource(d.proxy.Kind).
Expand Down Expand Up @@ -117,7 +117,7 @@ func (d *Dialer) DialContext(_ context.Context, network string, addr string) (ne
return nil, errors.Wrap(err, "error creating forwarding stream")
}

c := NewConn(dataStream)
c := NewConn(dataStream, errorStream)

return c, nil
}
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ require (
sigs.k8s.io/controller-runtime v0.5.0
sigs.k8s.io/yaml v1.1.0
)

replace google.golang.org/grpc => github.com/sethp-nr/grpc-go v0.0.0-20200228215221-53b5c65ead5f
Loading

0 comments on commit 5f1af73

Please sign in to comment.