Commit 59820827 authored by Nikhil Jindal's avatar Nikhil Jindal

Merge pull request #20513 from nikhiljindal/apiserverExampleTest

Adding test for apiserver example
parents 318b11d4 c7beb907
......@@ -171,7 +171,10 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
masterConfig.CacheTimeout = 2 * time.Second
// Create a master and install handlers into mux.
m := master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
glog.Fatalf("Error in bringing up the master: %v", err)
}
handler.delegate = m.Handler
// Scheduler
......
......@@ -401,7 +401,10 @@ func Run(s *options.APIServer) error {
Tunneler: tunneler,
}
m := master.New(config)
m, err := master.New(config)
if err != nil {
return err
}
m.Run(s.ServerRunOptions)
return nil
}
......
......@@ -39,6 +39,12 @@ API objects. Some relevant issues:
This code here is to examplify what it takes to write your own API server.
To start this example api server, run:
```
$ go run examples/apiserver/server/main.go
```
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/apiserver/README.md?pixel)]()
......
......@@ -14,12 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main
package apiserver
import (
"github.com/golang/glog"
"fmt"
"k8s.io/kubernetes/cmd/libs/go2idl/client-gen/testdata/apis/testgroup/v1"
testgroupetcd "k8s.io/kubernetes/examples/apiserver/rest"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apimachinery"
"k8s.io/kubernetes/pkg/apimachinery/registered"
......@@ -44,23 +46,27 @@ func newStorageDestinations(groupName string, groupMeta *apimachinery.GroupMeta)
return &storageDestinations, nil
}
func main() {
func Run() error {
config := genericapiserver.Config{
EnableIndex: true,
APIPrefix: "/api",
APIGroupPrefix: "/apis",
Serializer: api.Codecs,
}
s, err := genericapiserver.New(&config)
if err != nil {
return fmt.Errorf("Error in bringing up the server: %v", err)
}
s := genericapiserver.New(&config)
groupVersion := v1.SchemeGroupVersion
groupName := groupVersion.Group
groupMeta, err := registered.Group(groupName)
if err != nil {
glog.Fatalf("%v", err)
return fmt.Errorf("%v", err)
}
storageDestinations, err := newStorageDestinations(groupName, groupMeta)
if err != nil {
glog.Fatalf("Unable to init etcd: %v", err)
return fmt.Errorf("Unable to init etcd: %v", err)
}
restStorageMap := map[string]rest.Storage{
"testtypes": testgroupetcd.NewREST(storageDestinations.Get(groupName, "testtype"), s.StorageDecorator()),
......@@ -70,9 +76,12 @@ func main() {
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
groupVersion.Version: restStorageMap,
},
Scheme: api.Scheme,
NegotiatedSerializer: api.Codecs,
}
if err := s.InstallAPIGroups([]genericapiserver.APIGroupInfo{apiGroupInfo}); err != nil {
glog.Fatalf("Error in installing API: %v", err)
return fmt.Errorf("Error in installing API: %v", err)
}
s.Run(genericapiserver.NewServerRunOptions())
return nil
}
/*
Copyright 2016 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 apiserver
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"testing"
"time"
"k8s.io/kubernetes/cmd/libs/go2idl/client-gen/testdata/apis/testgroup/v1"
"github.com/stretchr/testify/assert"
"k8s.io/kubernetes/pkg/api/unversioned"
)
var serverIP = "http://localhost:8080"
var groupVersion = v1.SchemeGroupVersion
func TestRun(t *testing.T) {
go func() {
if err := Run(); err != nil {
t.Fatalf("Error in bringing up the server: %v", err)
}
}()
if err := waitForApiserverUp(); err != nil {
t.Fatalf("%v", err)
}
testAPIGroup(t)
testAPIResourceList(t)
}
func waitForApiserverUp() error {
for start := time.Now(); time.Since(start) < time.Minute; time.Sleep(5 * time.Second) {
_, err := http.Get(serverIP)
if err == nil {
return nil
}
}
return fmt.Errorf("waiting for apiserver timed out")
}
func readResponse(serverURL string) ([]byte, error) {
response, err := http.Get(serverURL)
if err != nil {
return nil, fmt.Errorf("Error in fetching %s: %v", serverURL, err)
}
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("Error reading response from %s: %v", serverURL, err)
}
return contents, nil
}
func testAPIGroup(t *testing.T) {
serverURL := serverIP + "/apis/testgroup"
contents, err := readResponse(serverURL)
if err != nil {
t.Fatalf("%v", err)
}
var apiGroup unversioned.APIGroup
err = json.Unmarshal(contents, &apiGroup)
if err != nil {
t.Fatalf("Error in unmarshalling response from server %s: %v", serverURL, err)
}
assert.Equal(t, apiGroup.APIVersion, groupVersion.Version)
assert.Equal(t, apiGroup.Name, groupVersion.Group)
assert.Equal(t, 1, len(apiGroup.Versions))
assert.Equal(t, apiGroup.Versions[0].GroupVersion, groupVersion.String())
assert.Equal(t, apiGroup.Versions[0].Version, groupVersion.Version)
assert.Equal(t, apiGroup.Versions[0], apiGroup.PreferredVersion)
}
func testAPIResourceList(t *testing.T) {
serverURL := serverIP + "/apis/testgroup/v1"
contents, err := readResponse(serverURL)
if err != nil {
t.Fatalf("%v", err)
}
var apiResourceList unversioned.APIResourceList
err = json.Unmarshal(contents, &apiResourceList)
if err != nil {
t.Fatalf("Error in unmarshalling response from server %s: %v", serverURL, err)
}
assert.Equal(t, apiResourceList.APIVersion, groupVersion.Version)
assert.Equal(t, apiResourceList.GroupVersion, groupVersion.String())
assert.Equal(t, 1, len(apiResourceList.APIResources))
assert.Equal(t, apiResourceList.APIResources[0].Name, "testtypes")
assert.True(t, apiResourceList.APIResources[0].Namespaced)
}
/*
Copyright 2016 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 main
import (
"k8s.io/kubernetes/examples/apiserver"
"github.com/golang/glog"
)
func main() {
if err := apiserver.Run(); err != nil {
glog.Fatalf("Error in bringing up the server: %v", err)
}
}
......@@ -379,7 +379,10 @@ func setDefaults(c *Config) {
// If the caller wants to add additional endpoints not using the GenericAPIServer's
// auth, then the caller should create a handler for those endpoints, which delegates the
// any unhandled paths to "Handler".
func New(c *Config) *GenericAPIServer {
func New(c *Config) (*GenericAPIServer, error) {
if c.Serializer == nil {
return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil")
}
setDefaults(c)
s := &GenericAPIServer{
......@@ -433,7 +436,7 @@ func New(c *Config) *GenericAPIServer {
s.init(c)
return s
return s, nil
}
func (s *GenericAPIServer) NewRequestInfoResolver() *apiserver.RequestInfoResolver {
......
......@@ -54,8 +54,12 @@ func TestNew(t *testing.T) {
config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil }
config.ProxyTLSClientConfig = &tls.Config{}
config.Serializer = api.Codecs
s := New(&config)
s, err := New(&config)
if err != nil {
t.Fatalf("Error in bringing up the server: %v", err)
}
// Verify many of the variables match their config counterparts
assert.Equal(s.enableLogsSupport, config.EnableLogsSupport)
......@@ -96,7 +100,11 @@ func TestInstallAPIGroups(t *testing.T) {
config.APIGroupPrefix = "/apiGroupPrefix"
config.Serializer = api.Codecs
s := New(&config)
s, err := New(&config)
if err != nil {
t.Fatalf("Error in bringing up the server: %v", err)
}
apiGroupMeta := registered.GroupOrDie(api.GroupName)
extensionsGroupMeta := registered.GroupOrDie(extensions.GroupName)
apiGroupsInfo := []APIGroupInfo{
......
......@@ -134,12 +134,15 @@ type thirdPartyEntry struct {
// Certain config fields will be set to a default value if unset.
// Certain config fields must be specified, including:
// KubeletClient
func New(c *Config) *Master {
func New(c *Config) (*Master, error) {
if c.KubeletClient == nil {
glog.Fatalf("Master.New() called with config.KubeletClient == nil")
return nil, fmt.Errorf("Master.New() called with config.KubeletClient == nil")
}
s := genericapiserver.New(c.Config)
s, err := genericapiserver.New(c.Config)
if err != nil {
return nil, err
}
m := &Master{
GenericAPIServer: s,
......@@ -158,7 +161,7 @@ func New(c *Config) *Master {
m.NewBootstrapController().Start()
}
return m
return m, nil
}
func resetMetrics(w http.ResponseWriter, req *http.Request) {
......
......@@ -89,7 +89,11 @@ func newMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *ass
config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil }
config.ProxyTLSClientConfig = &tls.Config{}
master := New(&config)
master, err := New(&config)
if err != nil {
t.Fatalf("Error in bringing up the master: %v", err)
}
return master, etcdserver, config, assert
}
......
......@@ -45,7 +45,10 @@ func mustSetupScheduler() (schedulerConfigFactory *factory.ConfigFactory, destro
var m *master.Master
masterConfig := framework.NewIntegrationTestMasterConfig()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
panic("error in brining up the master: " + err.Error())
}
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
......
......@@ -394,7 +394,10 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
// defer s.Close()
masterConfig := framework.NewIntegrationTestMasterConfig()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
transport := http.DefaultTransport
previousResourceVersion := make(map[string]float64)
......@@ -498,7 +501,10 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.Authorizer = apiserver.NewAlwaysDenyAuthorizer()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
transport := http.DefaultTransport
......@@ -555,7 +561,10 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
masterConfig.Authenticator = getTestTokenAuth()
masterConfig.Authorizer = allowAliceAuthorizer{}
masterConfig.AdmissionControl = admit.NewAlwaysAdmit()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
previousResourceVersion := make(map[string]float64)
transport := http.DefaultTransport
......@@ -630,7 +639,10 @@ func TestBobIsForbidden(t *testing.T) {
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.Authenticator = getTestTokenAuth()
masterConfig.Authorizer = allowAliceAuthorizer{}
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
transport := http.DefaultTransport
......@@ -679,7 +691,10 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.Authenticator = getTestTokenAuth()
masterConfig.Authorizer = allowAliceAuthorizer{}
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
transport := http.DefaultTransport
......@@ -753,7 +768,10 @@ func TestAuthorizationAttributeDetermination(t *testing.T) {
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.Authenticator = getTestTokenAuth()
masterConfig.Authorizer = trackingAuthorizer
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
transport := http.DefaultTransport
......@@ -822,7 +840,10 @@ func TestNamespaceAuthorization(t *testing.T) {
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.Authenticator = getTestTokenAuth()
masterConfig.Authorizer = a
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
previousResourceVersion := make(map[string]float64)
transport := http.DefaultTransport
......@@ -925,7 +946,10 @@ func TestKindAuthorization(t *testing.T) {
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.Authenticator = getTestTokenAuth()
masterConfig.Authorizer = a
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
previousResourceVersion := make(map[string]float64)
transport := http.DefaultTransport
......@@ -1016,7 +1040,10 @@ func TestReadOnlyAuthorization(t *testing.T) {
masterConfig.Authenticator = getTestTokenAuth()
masterConfig.Authorizer = a
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
transport := http.DefaultTransport
......
......@@ -195,7 +195,10 @@ func TestSchedulerExtender(t *testing.T) {
// defer s.Close()
masterConfig := framework.NewIntegrationTestMasterConfig()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
restClient := client.NewOrDie(&client.Config{Host: s.URL, ContentConfig: client.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}})
......
......@@ -135,7 +135,11 @@ func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Se
masterConfig.EnableProfiling = true
masterConfig.EnableSwaggerSupport = true
}
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
glog.Fatalf("error in bringing up the master: %v", err)
}
return m, s
}
......@@ -289,7 +293,11 @@ func StartPods(numPods int, host string, restClient *client.Client) error {
func RunAMaster(t *testing.T) (*master.Master, *httptest.Server) {
masterConfig := NewMasterConfig()
masterConfig.EnableProfiling = true
m := master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
// TODO: Return error.
glog.Fatalf("error in bringing up the master: %v", err)
}
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
......
......@@ -62,7 +62,10 @@ func TestUnschedulableNodes(t *testing.T) {
// defer s.Close()
masterConfig := framework.NewIntegrationTestMasterConfig()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("Error in bringing up the master: %v", err)
}
restClient := client.NewOrDie(&client.Config{Host: s.URL, ContentConfig: client.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}})
......@@ -286,7 +289,11 @@ func TestMultiScheduler(t *testing.T) {
// defer s.Close()
masterConfig := framework.NewIntegrationTestMasterConfig()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("Error in bringing up the master: %v", err)
}
/*
This integration tests the multi-scheduler feature in the following way:
1. create a default scheduler
......@@ -461,7 +468,10 @@ func TestAllocatable(t *testing.T) {
defer s.Close()
masterConfig := framework.NewIntegrationTestMasterConfig()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("Error in bringing up the master: %v", err)
}
// 1. create and start default-scheduler
restClient := client.NewOrDie(&client.Config{Host: s.URL, ContentConfig: client.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}})
......
......@@ -53,7 +53,10 @@ func TestSecrets(t *testing.T) {
// defer s.Close()
masterConfig := framework.NewIntegrationTestMasterConfig()
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("Error in bringing up the master: %v", err)
}
framework.DeleteAllEtcdKeys()
client := client.NewOrDie(&client.Config{Host: s.URL, ContentConfig: client.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}})
......
......@@ -409,7 +409,10 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, client.C
masterConfig.AdmissionControl = serviceAccountAdmission
// Create a master and install handlers into mux.
m = master.New(masterConfig)
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("Error in bringing up the master: %v", err)
}
// Start the service account and service account token controllers
tokenController := serviceaccountcontroller.NewTokensController(rootClientset, serviceaccountcontroller.TokensControllerOptions{TokenGenerator: serviceaccount.JWTTokenGenerator(serviceAccountKey)})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment