git subrepo clone (merge) https://github.com/kubernetes-incubator/metrics-server.git metrics-server

subrepo:
  subdir:   "metrics-server"
  merged:   "92d8412"
upstream:
  origin:   "https://github.com/kubernetes-incubator/metrics-server.git"
  branch:   "master"
  commit:   "92d8412"
git-subrepo:
  version:  "0.4.0"
  origin:   "???"
  commit:   "???"
diff --git a/metrics-server/vendor/k8s.io/apiserver/pkg/server/serve.go b/metrics-server/vendor/k8s.io/apiserver/pkg/server/serve.go
new file mode 100644
index 0000000..7cfc103
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apiserver/pkg/server/serve.go
@@ -0,0 +1,214 @@
+/*
+Copyright 2016 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package server
+
+import (
+	"context"
+	"crypto/tls"
+	"crypto/x509"
+	"fmt"
+	"net"
+	"net/http"
+	"strings"
+	"time"
+
+	"github.com/golang/glog"
+	"golang.org/x/net/http2"
+
+	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+	"k8s.io/apimachinery/pkg/util/validation"
+)
+
+const (
+	defaultKeepAlivePeriod = 3 * time.Minute
+)
+
+// serveSecurely runs the secure http server. It fails only if certificates cannot
+// be loaded or the initial listen call fails. The actual server loop (stoppable by closing
+// stopCh) runs in a go routine, i.e. serveSecurely does not block.
+func (s *SecureServingInfo) Serve(handler http.Handler, shutdownTimeout time.Duration, stopCh <-chan struct{}) error {
+	if s.Listener == nil {
+		return fmt.Errorf("listener must not be nil")
+	}
+
+	secureServer := &http.Server{
+		Addr:           s.Listener.Addr().String(),
+		Handler:        handler,
+		MaxHeaderBytes: 1 << 20,
+		TLSConfig: &tls.Config{
+			NameToCertificate: s.SNICerts,
+			// Can't use SSLv3 because of POODLE and BEAST
+			// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
+			// Can't use TLSv1.1 because of RC4 cipher usage
+			MinVersion: tls.VersionTLS12,
+			// enable HTTP2 for go's 1.7 HTTP Server
+			NextProtos: []string{"h2", "http/1.1"},
+		},
+	}
+
+	if s.MinTLSVersion > 0 {
+		secureServer.TLSConfig.MinVersion = s.MinTLSVersion
+	}
+	if len(s.CipherSuites) > 0 {
+		secureServer.TLSConfig.CipherSuites = s.CipherSuites
+	}
+
+	if s.Cert != nil {
+		secureServer.TLSConfig.Certificates = []tls.Certificate{*s.Cert}
+	}
+
+	// append all named certs. Otherwise, the go tls stack will think no SNI processing
+	// is necessary because there is only one cert anyway.
+	// Moreover, if ServerCert.CertFile/ServerCert.KeyFile are not set, the first SNI
+	// cert will become the default cert. That's what we expect anyway.
+	for _, c := range s.SNICerts {
+		secureServer.TLSConfig.Certificates = append(secureServer.TLSConfig.Certificates, *c)
+	}
+
+	if s.ClientCA != nil {
+		// Populate PeerCertificates in requests, but don't reject connections without certificates
+		// This allows certificates to be validated by authenticators, while still allowing other auth types
+		secureServer.TLSConfig.ClientAuth = tls.RequestClientCert
+		// Specify allowed CAs for client certificates
+		secureServer.TLSConfig.ClientCAs = s.ClientCA
+	}
+
+	if s.HTTP2MaxStreamsPerConnection > 0 {
+		http2.ConfigureServer(secureServer, &http2.Server{
+			MaxConcurrentStreams: uint32(s.HTTP2MaxStreamsPerConnection),
+		})
+	}
+
+	glog.Infof("Serving securely on %s", secureServer.Addr)
+	return RunServer(secureServer, s.Listener, shutdownTimeout, stopCh)
+}
+
+// RunServer listens on the given port if listener is not given,
+// then spawns a go-routine continuously serving
+// until the stopCh is closed. This function does not block.
+// TODO: make private when insecure serving is gone from the kube-apiserver
+func RunServer(
+	server *http.Server,
+	ln net.Listener,
+	shutDownTimeout time.Duration,
+	stopCh <-chan struct{},
+) error {
+	if ln == nil {
+		return fmt.Errorf("listener must not be nil")
+	}
+
+	// Shutdown server gracefully.
+	go func() {
+		<-stopCh
+		ctx, cancel := context.WithTimeout(context.Background(), shutDownTimeout)
+		server.Shutdown(ctx)
+		cancel()
+	}()
+
+	go func() {
+		defer utilruntime.HandleCrash()
+
+		var listener net.Listener
+		listener = tcpKeepAliveListener{ln.(*net.TCPListener)}
+		if server.TLSConfig != nil {
+			listener = tls.NewListener(listener, server.TLSConfig)
+		}
+
+		err := server.Serve(listener)
+
+		msg := fmt.Sprintf("Stopped listening on %s", ln.Addr().String())
+		select {
+		case <-stopCh:
+			glog.Info(msg)
+		default:
+			panic(fmt.Sprintf("%s due to error: %v", msg, err))
+		}
+	}()
+
+	return nil
+}
+
+type NamedTLSCert struct {
+	TLSCert tls.Certificate
+
+	// names is a list of domain patterns: fully qualified domain names, possibly prefixed with
+	// wildcard segments.
+	Names []string
+}
+
+// getNamedCertificateMap returns a map of *tls.Certificate by name. It's is
+// suitable for use in tls.Config#NamedCertificates. Returns an error if any of the certs
+// cannot be loaded. Returns nil if len(certs) == 0
+func GetNamedCertificateMap(certs []NamedTLSCert) (map[string]*tls.Certificate, error) {
+	// register certs with implicit names first, reverse order such that earlier trump over the later
+	byName := map[string]*tls.Certificate{}
+	for i := len(certs) - 1; i >= 0; i-- {
+		if len(certs[i].Names) > 0 {
+			continue
+		}
+		cert := &certs[i].TLSCert
+
+		// read names from certificate common names and DNS names
+		if len(cert.Certificate) == 0 {
+			return nil, fmt.Errorf("empty SNI certificate, skipping")
+		}
+		x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
+		if err != nil {
+			return nil, fmt.Errorf("parse error for SNI certificate: %v", err)
+		}
+		cn := x509Cert.Subject.CommonName
+		if cn == "*" || len(validation.IsDNS1123Subdomain(strings.TrimPrefix(cn, "*."))) == 0 {
+			byName[cn] = cert
+		}
+		for _, san := range x509Cert.DNSNames {
+			byName[san] = cert
+		}
+		// intentionally all IPs in the cert are ignored as SNI forbids passing IPs
+		// to select a cert. Before go 1.6 the tls happily passed IPs as SNI values.
+	}
+
+	// register certs with explicit names last, overwriting every of the implicit ones,
+	// again in reverse order.
+	for i := len(certs) - 1; i >= 0; i-- {
+		namedCert := &certs[i]
+		for _, name := range namedCert.Names {
+			byName[name] = &certs[i].TLSCert
+		}
+	}
+
+	return byName, nil
+}
+
+// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
+// connections. It's used by ListenAndServe and ListenAndServeTLS so
+// dead TCP connections (e.g. closing laptop mid-download) eventually
+// go away.
+//
+// Copied from Go 1.7.2 net/http/server.go
+type tcpKeepAliveListener struct {
+	*net.TCPListener
+}
+
+func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
+	tc, err := ln.AcceptTCP()
+	if err != nil {
+		return nil, err
+	}
+	tc.SetKeepAlive(true)
+	tc.SetKeepAlivePeriod(defaultKeepAlivePeriod)
+	return tc, nil
+}