2015-11-16 21:46:00 +00:00
|
|
|
/*
|
|
|
|
Copyright 2015 The Kubernetes Authors All rights reserved.
|
|
|
|
|
|
|
|
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 genericapiserver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
2015-12-22 21:22:28 +00:00
|
|
|
"net/http/httptest"
|
2015-11-16 21:46:00 +00:00
|
|
|
"testing"
|
|
|
|
|
2015-12-22 21:22:28 +00:00
|
|
|
"k8s.io/kubernetes/pkg/api"
|
|
|
|
"k8s.io/kubernetes/pkg/api/rest"
|
2016-01-13 22:40:56 +00:00
|
|
|
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
2015-12-22 21:22:28 +00:00
|
|
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
2015-11-16 21:46:00 +00:00
|
|
|
"k8s.io/kubernetes/pkg/apiserver"
|
|
|
|
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
2016-01-06 15:56:41 +00:00
|
|
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
2015-11-16 21:46:00 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
// setUp is a convience function for setting up for (most) tests.
|
|
|
|
func setUp(t *testing.T) (GenericAPIServer, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
|
|
|
|
etcdServer := etcdtesting.NewEtcdTestClientServer(t)
|
|
|
|
|
|
|
|
genericapiserver := GenericAPIServer{}
|
|
|
|
config := Config{}
|
|
|
|
config.PublicAddress = net.ParseIP("192.168.10.4")
|
|
|
|
|
|
|
|
return genericapiserver, etcdServer, config, assert.New(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestNew verifies that the New function returns a GenericAPIServer
|
|
|
|
// using the configuration properly.
|
|
|
|
func TestNew(t *testing.T) {
|
|
|
|
_, etcdserver, config, assert := setUp(t)
|
|
|
|
defer etcdserver.Terminate(t)
|
|
|
|
|
|
|
|
config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil }
|
|
|
|
config.ProxyTLSClientConfig = &tls.Config{}
|
|
|
|
|
|
|
|
s := New(&config)
|
|
|
|
|
|
|
|
// Verify many of the variables match their config counterparts
|
|
|
|
assert.Equal(s.enableLogsSupport, config.EnableLogsSupport)
|
|
|
|
assert.Equal(s.enableUISupport, config.EnableUISupport)
|
|
|
|
assert.Equal(s.enableSwaggerSupport, config.EnableSwaggerSupport)
|
|
|
|
assert.Equal(s.enableProfiling, config.EnableProfiling)
|
2015-12-22 21:22:28 +00:00
|
|
|
assert.Equal(s.APIPrefix, config.APIPrefix)
|
|
|
|
assert.Equal(s.APIGroupPrefix, config.APIGroupPrefix)
|
2015-11-16 21:46:00 +00:00
|
|
|
assert.Equal(s.corsAllowedOriginList, config.CorsAllowedOriginList)
|
|
|
|
assert.Equal(s.authenticator, config.Authenticator)
|
|
|
|
assert.Equal(s.authorizer, config.Authorizer)
|
|
|
|
assert.Equal(s.AdmissionControl, config.AdmissionControl)
|
|
|
|
assert.Equal(s.ApiGroupVersionOverrides, config.APIGroupVersionOverrides)
|
|
|
|
assert.Equal(s.RequestContextMapper, config.RequestContextMapper)
|
|
|
|
assert.Equal(s.cacheTimeout, config.CacheTimeout)
|
|
|
|
assert.Equal(s.externalHost, config.ExternalHost)
|
|
|
|
assert.Equal(s.ClusterIP, config.PublicAddress)
|
|
|
|
assert.Equal(s.PublicReadWritePort, config.ReadWritePort)
|
|
|
|
assert.Equal(s.ServiceReadWriteIP, config.ServiceReadWriteIP)
|
|
|
|
|
|
|
|
// These functions should point to the same memory location
|
2016-01-06 15:56:41 +00:00
|
|
|
serverDialer, _ := utilnet.Dialer(s.ProxyTransport)
|
2015-11-16 21:46:00 +00:00
|
|
|
serverDialerFunc := fmt.Sprintf("%p", serverDialer)
|
|
|
|
configDialerFunc := fmt.Sprintf("%p", config.ProxyDialer)
|
|
|
|
assert.Equal(serverDialerFunc, configDialerFunc)
|
|
|
|
|
|
|
|
assert.Equal(s.ProxyTransport.(*http.Transport).TLSClientConfig, config.ProxyTLSClientConfig)
|
|
|
|
}
|
|
|
|
|
2015-12-22 21:22:28 +00:00
|
|
|
// Verifies that AddGroupVersions works as expected.
|
|
|
|
func TestInstallAPIGroups(t *testing.T) {
|
|
|
|
_, etcdserver, config, assert := setUp(t)
|
|
|
|
defer etcdserver.Terminate(t)
|
|
|
|
|
|
|
|
config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil }
|
|
|
|
config.ProxyTLSClientConfig = &tls.Config{}
|
|
|
|
config.APIPrefix = "/apiPrefix"
|
|
|
|
config.APIGroupPrefix = "/apiGroupPrefix"
|
2015-12-21 05:21:26 +00:00
|
|
|
config.Serializer = api.Codecs
|
2015-12-22 21:22:28 +00:00
|
|
|
|
|
|
|
s := New(&config)
|
2016-01-13 22:40:56 +00:00
|
|
|
apiGroupMeta := registered.GroupOrDie(api.GroupName)
|
|
|
|
extensionsGroupMeta := registered.GroupOrDie(extensions.GroupName)
|
2015-12-22 21:22:28 +00:00
|
|
|
apiGroupsInfo := []APIGroupInfo{
|
|
|
|
{
|
|
|
|
// legacy group version
|
|
|
|
GroupMeta: *apiGroupMeta,
|
|
|
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
|
|
|
|
IsLegacyGroup: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// extensions group version
|
|
|
|
GroupMeta: *extensionsGroupMeta,
|
|
|
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
|
|
|
|
OptionsExternalVersion: &apiGroupMeta.GroupVersion,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
s.InstallAPIGroups(apiGroupsInfo)
|
|
|
|
|
2016-01-10 22:39:32 +00:00
|
|
|
// TODO: Close() this server when fix #19254
|
2015-12-22 21:22:28 +00:00
|
|
|
server := httptest.NewServer(s.HandlerContainer.ServeMux)
|
|
|
|
validPaths := []string{
|
|
|
|
// "/api"
|
|
|
|
config.APIPrefix,
|
|
|
|
// "/api/v1"
|
|
|
|
config.APIPrefix + "/" + apiGroupMeta.GroupVersion.Version,
|
|
|
|
// "/apis/extensions"
|
|
|
|
config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.Group,
|
|
|
|
// "/apis/extensions/v1beta1"
|
|
|
|
config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.String(),
|
|
|
|
}
|
|
|
|
for _, path := range validPaths {
|
|
|
|
_, err := http.Get(server.URL + path)
|
|
|
|
if !assert.NoError(err) {
|
|
|
|
t.Errorf("unexpected error: %v, for path: %s", err, path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:46:00 +00:00
|
|
|
// TestNewHandlerContainer verifies that NewHandlerContainer uses the
|
|
|
|
// mux provided
|
|
|
|
func TestNewHandlerContainer(t *testing.T) {
|
|
|
|
assert := assert.New(t)
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
container := NewHandlerContainer(mux)
|
|
|
|
assert.Equal(mux, container.ServeMux, "ServerMux's do not match")
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestHandleWithAuth verifies HandleWithAuth adds the path
|
|
|
|
// to the MuxHelper.RegisteredPaths.
|
|
|
|
func TestHandleWithAuth(t *testing.T) {
|
|
|
|
server, etcdserver, _, assert := setUp(t)
|
|
|
|
defer etcdserver.Terminate(t)
|
|
|
|
|
|
|
|
mh := apiserver.MuxHelper{Mux: http.NewServeMux()}
|
|
|
|
server.MuxHelper = &mh
|
|
|
|
handler := func(r http.ResponseWriter, w *http.Request) { w.Write(nil) }
|
|
|
|
server.HandleWithAuth("/test", http.HandlerFunc(handler))
|
|
|
|
|
|
|
|
assert.Contains(server.MuxHelper.RegisteredPaths, "/test", "Path not found in MuxHelper")
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestHandleFuncWithAuth verifies HandleFuncWithAuth adds the path
|
|
|
|
// to the MuxHelper.RegisteredPaths.
|
|
|
|
func TestHandleFuncWithAuth(t *testing.T) {
|
|
|
|
server, etcdserver, _, assert := setUp(t)
|
|
|
|
defer etcdserver.Terminate(t)
|
|
|
|
|
|
|
|
mh := apiserver.MuxHelper{Mux: http.NewServeMux()}
|
|
|
|
server.MuxHelper = &mh
|
|
|
|
handler := func(r http.ResponseWriter, w *http.Request) { w.Write(nil) }
|
|
|
|
server.HandleFuncWithAuth("/test", handler)
|
|
|
|
|
|
|
|
assert.Contains(server.MuxHelper.RegisteredPaths, "/test", "Path not found in MuxHelper")
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestInstallSwaggerAPI verifies that the swagger api is added
|
|
|
|
// at the proper endpoint.
|
|
|
|
func TestInstallSwaggerAPI(t *testing.T) {
|
|
|
|
server, etcdserver, _, assert := setUp(t)
|
|
|
|
defer etcdserver.Terminate(t)
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
server.HandlerContainer = NewHandlerContainer(mux)
|
|
|
|
|
|
|
|
// Ensure swagger isn't installed without the call
|
|
|
|
ws := server.HandlerContainer.RegisteredWebServices()
|
|
|
|
if !assert.Equal(len(ws), 0) {
|
|
|
|
for x := range ws {
|
|
|
|
assert.NotEqual("/swaggerapi", ws[x].RootPath(), "SwaggerAPI was installed without a call to InstallSwaggerAPI()")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Install swagger and test
|
|
|
|
server.InstallSwaggerAPI()
|
|
|
|
ws = server.HandlerContainer.RegisteredWebServices()
|
|
|
|
if assert.NotEqual(0, len(ws), "SwaggerAPI not installed.") {
|
|
|
|
assert.Equal("/swaggerapi/", ws[0].RootPath(), "SwaggerAPI did not install to the proper path. %s != /swaggerapi", ws[0].RootPath())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Empty externalHost verification
|
|
|
|
mux = http.NewServeMux()
|
|
|
|
server.HandlerContainer = NewHandlerContainer(mux)
|
|
|
|
server.externalHost = ""
|
|
|
|
server.ClusterIP = net.IPv4(10, 10, 10, 10)
|
|
|
|
server.PublicReadWritePort = 1010
|
|
|
|
server.InstallSwaggerAPI()
|
|
|
|
if assert.NotEqual(0, len(ws), "SwaggerAPI not installed.") {
|
|
|
|
assert.Equal("/swaggerapi/", ws[0].RootPath(), "SwaggerAPI did not install to the proper path. %s != /swaggerapi", ws[0].RootPath())
|
|
|
|
}
|
|
|
|
}
|