Merge pull request #1746 from hmrm/refactor-kubelet-access
Refactor kubelet access and add SSL
This commit is contained in:
@@ -21,6 +21,7 @@ package client
|
||||
type FlagSet interface {
|
||||
StringVar(p *string, name, value, usage string)
|
||||
BoolVar(p *bool, name string, value bool, usage string)
|
||||
UintVar(p *uint, name string, value uint, usage string)
|
||||
}
|
||||
|
||||
// BindClientConfigFlags registers a standard set of CLI flags for connecting to a Kubernetes API server.
|
||||
@@ -30,5 +31,13 @@ func BindClientConfigFlags(flags FlagSet, config *Config) {
|
||||
flags.BoolVar(&config.Insecure, "insecure_skip_tls_verify", config.Insecure, "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.")
|
||||
flags.StringVar(&config.CertFile, "client_certificate", config.CertFile, "Path to a client key file for TLS.")
|
||||
flags.StringVar(&config.KeyFile, "client_key", config.KeyFile, "Path to a client key file for TLS.")
|
||||
flags.StringVar(&config.CAFile, "certificate_authority", config.CAFile, "Path to a cert. file for the certificate authority")
|
||||
flags.StringVar(&config.CAFile, "certificate_authority", config.CAFile, "Path to a cert. file for the certificate authority.")
|
||||
}
|
||||
|
||||
func BindKubeletClientConfigFlags(flags FlagSet, config *KubeletConfig) {
|
||||
flags.BoolVar(&config.EnableHttps, "kubelet_https", config.EnableHttps, "Use https for kubelet connections")
|
||||
flags.UintVar(&config.Port, "kubelet_port", config.Port, "Kubelet port")
|
||||
flags.StringVar(&config.CertFile, "kubelet_client_certificate", config.CertFile, "Path to a client key file for TLS.")
|
||||
flags.StringVar(&config.KeyFile, "kubelet_client_key", config.KeyFile, "Path to a client key file for TLS.")
|
||||
flags.StringVar(&config.CAFile, "kubelet_certificate_authority", config.CAFile, "Path to a cert. file for the certificate authority.")
|
||||
}
|
||||
|
@@ -61,6 +61,19 @@ type Config struct {
|
||||
Transport http.RoundTripper
|
||||
}
|
||||
|
||||
type KubeletConfig struct {
|
||||
// ToDo: Add support for different kubelet instances exposing different ports
|
||||
Port uint
|
||||
EnableHttps bool
|
||||
|
||||
// TLS Configuration, only applies if EnableHttps is true.
|
||||
CertFile string
|
||||
// TLS Configuration, only applies if EnableHttps is true.
|
||||
KeyFile string
|
||||
// TLS Configuration, only applies if EnableHttps is true.
|
||||
CAFile string
|
||||
}
|
||||
|
||||
// New creates a Kubernetes client for the given config. This client works with pods,
|
||||
// replication controllers and services. It allows operations such as list, get, update
|
||||
// and delete on these objects. An error is returned if the provided configuration
|
||||
|
@@ -26,11 +26,23 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/health"
|
||||
)
|
||||
|
||||
// ErrPodInfoNotAvailable may be returned when the requested pod info is not available.
|
||||
var ErrPodInfoNotAvailable = errors.New("no pod info available")
|
||||
|
||||
// KubeletClient is an interface for all kubelet functionality
|
||||
type KubeletClient interface {
|
||||
KubeletHealthChecker
|
||||
PodInfoGetter
|
||||
}
|
||||
|
||||
// KubeletHealthchecker is an interface for healthchecking kubelets
|
||||
type KubeletHealthChecker interface {
|
||||
HealthCheck(host string) (health.Status, error)
|
||||
}
|
||||
|
||||
// PodInfoGetter is an interface for things that can get information about a pod's containers.
|
||||
// Injectable for easy testing.
|
||||
type PodInfoGetter interface {
|
||||
@@ -39,19 +51,50 @@ type PodInfoGetter interface {
|
||||
GetPodInfo(host, podNamespace, podID string) (api.PodInfo, error)
|
||||
}
|
||||
|
||||
// HTTPPodInfoGetter is the default implementation of PodInfoGetter, accesses the kubelet over HTTP.
|
||||
type HTTPPodInfoGetter struct {
|
||||
Client *http.Client
|
||||
Port uint
|
||||
// HTTPKubeletClient is the default implementation of PodInfoGetter and KubeletHealthchecker, accesses the kubelet over HTTP.
|
||||
type HTTPKubeletClient struct {
|
||||
Client *http.Client
|
||||
Port uint
|
||||
EnableHttps bool
|
||||
}
|
||||
|
||||
func NewKubeletClient(config *KubeletConfig) (KubeletClient, error) {
|
||||
transport := http.DefaultTransport
|
||||
if config.CAFile != "" {
|
||||
t, err := NewClientCertTLSTransport(config.CertFile, config.KeyFile, config.CAFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transport = t
|
||||
}
|
||||
|
||||
c := &http.Client{Transport: transport}
|
||||
return &HTTPKubeletClient{
|
||||
Client: c,
|
||||
Port: config.Port,
|
||||
EnableHttps: config.EnableHttps,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *HTTPKubeletClient) url(host string) string {
|
||||
scheme := "http://"
|
||||
if c.EnableHttps {
|
||||
scheme = "https://"
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%s%s",
|
||||
scheme,
|
||||
net.JoinHostPort(host, strconv.FormatUint(uint64(c.Port), 10)))
|
||||
}
|
||||
|
||||
// GetPodInfo gets information about the specified pod.
|
||||
func (c *HTTPPodInfoGetter) GetPodInfo(host, podNamespace, podID string) (api.PodInfo, error) {
|
||||
func (c *HTTPKubeletClient) GetPodInfo(host, podNamespace, podID string) (api.PodInfo, error) {
|
||||
request, err := http.NewRequest(
|
||||
"GET",
|
||||
fmt.Sprintf(
|
||||
"http://%s/podInfo?podID=%s&podNamespace=%s",
|
||||
net.JoinHostPort(host, strconv.FormatUint(uint64(c.Port), 10)),
|
||||
"%s/podInfo?podID=%s&podNamespace=%s",
|
||||
c.url(host),
|
||||
podID,
|
||||
podNamespace),
|
||||
nil)
|
||||
@@ -79,7 +122,11 @@ func (c *HTTPPodInfoGetter) GetPodInfo(host, podNamespace, podID string) (api.Po
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// FakePodInfoGetter is a fake implementation of PodInfoGetter. It is useful for testing.
|
||||
func (c *HTTPKubeletClient) HealthCheck(host string) (health.Status, error) {
|
||||
return health.DoHTTPCheck(fmt.Sprintf("%s/healthz", c.url(host)), c.Client)
|
||||
}
|
||||
|
||||
// FakeKubeletClient is a fake implementation of PodInfoGetter. It is useful for testing.
|
||||
type FakePodInfoGetter struct {
|
||||
data api.PodInfo
|
||||
err error
|
@@ -29,7 +29,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
)
|
||||
|
||||
func TestHTTPPodInfoGetter(t *testing.T) {
|
||||
func TestHTTPKubeletClient(t *testing.T) {
|
||||
expectObj := api.PodInfo{
|
||||
"myID": api.ContainerStatus{},
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func TestHTTPPodInfoGetter(t *testing.T) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
podInfoGetter := &HTTPPodInfoGetter{
|
||||
podInfoGetter := &HTTPKubeletClient{
|
||||
Client: http.DefaultClient,
|
||||
Port: uint(port),
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func TestHTTPPodInfoGetter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPPodInfoGetterNotFound(t *testing.T) {
|
||||
func TestHTTPKubeletClientNotFound(t *testing.T) {
|
||||
expectObj := api.PodInfo{
|
||||
"myID": api.ContainerStatus{},
|
||||
}
|
||||
@@ -98,7 +98,7 @@ func TestHTTPPodInfoGetterNotFound(t *testing.T) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
podInfoGetter := &HTTPPodInfoGetter{
|
||||
podInfoGetter := &HTTPKubeletClient{
|
||||
Client: http.DefaultClient,
|
||||
Port: uint(port),
|
||||
}
|
Reference in New Issue
Block a user