mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 15:05:27 +00:00
Merge pull request #12001 from uluyol/os-exp-hack
Add (stopgap) support for an experimental API prefix.
This commit is contained in:
commit
e58ea24d0b
@ -42,6 +42,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/record"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/nodecontroller"
|
||||
replicationControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication"
|
||||
explatest "github.com/GoogleCloudPlatform/kubernetes/pkg/expapi/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/cadvisor"
|
||||
@ -132,10 +133,14 @@ func startComponents(firstManifestURL, secondManifestURL, apiVersion string) (st
|
||||
|
||||
cl := client.NewOrDie(&client.Config{Host: apiServer.URL, Version: apiVersion})
|
||||
|
||||
etcdStorage, err := master.NewEtcdStorage(etcdClient, "", etcdtest.PathPrefix())
|
||||
etcdStorage, err := master.NewEtcdStorage(etcdClient, latest.InterfacesFor, latest.Version, etcdtest.PathPrefix())
|
||||
if err != nil {
|
||||
glog.Fatalf("Unable to get etcd storage: %v", err)
|
||||
}
|
||||
expEtcdStorage, err := master.NewEtcdStorage(etcdClient, explatest.InterfacesFor, explatest.Version, etcdtest.PathPrefix())
|
||||
if err != nil {
|
||||
glog.Fatalf("Unable to get etcd storage for experimental: %v", err)
|
||||
}
|
||||
|
||||
// Master
|
||||
host, port, err := net.SplitHostPort(strings.TrimLeft(apiServer.URL, "http://"))
|
||||
@ -155,11 +160,13 @@ func startComponents(firstManifestURL, secondManifestURL, apiVersion string) (st
|
||||
// Create a master and install handlers into mux.
|
||||
m := master.New(&master.Config{
|
||||
DatabaseStorage: etcdStorage,
|
||||
ExpDatabaseStorage: expEtcdStorage,
|
||||
KubeletClient: fakeKubeletClient{},
|
||||
EnableCoreControllers: true,
|
||||
EnableLogsSupport: false,
|
||||
EnableProfiling: true,
|
||||
APIPrefix: "/api",
|
||||
ExpAPIPrefix: "/experimental",
|
||||
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
|
||||
AdmissionControl: admit.NewAlwaysAdmit(),
|
||||
ReadWritePort: portNumber,
|
||||
|
@ -32,10 +32,13 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
|
||||
explatest "github.com/GoogleCloudPlatform/kubernetes/pkg/expapi/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
|
||||
@ -71,7 +74,9 @@ type APIServer struct {
|
||||
TLSPrivateKeyFile string
|
||||
CertDirectory string
|
||||
APIPrefix string
|
||||
ExpAPIPrefix string
|
||||
StorageVersion string
|
||||
ExpStorageVersion string
|
||||
CloudProvider string
|
||||
CloudConfigFile string
|
||||
EventTTL time.Duration
|
||||
@ -115,6 +120,7 @@ func NewAPIServer() *APIServer {
|
||||
APIRate: 10.0,
|
||||
APIBurst: 200,
|
||||
APIPrefix: "/api",
|
||||
ExpAPIPrefix: "/experimental",
|
||||
EventTTL: 1 * time.Hour,
|
||||
AuthorizationMode: "AlwaysAllow",
|
||||
AdmissionControl: "AlwaysAdmit",
|
||||
@ -172,6 +178,7 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&s.CertDirectory, "cert-dir", s.CertDirectory, "The directory where the TLS certs are located (by default /var/run/kubernetes). "+
|
||||
"If --tls-cert-file and --tls-private-key-file are provided, this flag will be ignored.")
|
||||
fs.StringVar(&s.APIPrefix, "api-prefix", s.APIPrefix, "The prefix for API requests on the server. Default '/api'.")
|
||||
fs.StringVar(&s.ExpAPIPrefix, "experimental-prefix", s.ExpAPIPrefix, "The prefix for experimental API requests on the server. Default '/experimental'.")
|
||||
fs.StringVar(&s.StorageVersion, "storage-version", s.StorageVersion, "The version to store resources with. Defaults to server preferred")
|
||||
fs.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider, "The provider for cloud services. Empty string for no provider.")
|
||||
fs.StringVar(&s.CloudConfigFile, "cloud-config", s.CloudConfigFile, "The path to the cloud provider configuration file. Empty string for no configuration file.")
|
||||
@ -217,7 +224,7 @@ func (s *APIServer) verifyClusterIPFlags() {
|
||||
}
|
||||
}
|
||||
|
||||
func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string, pathPrefix string) (etcdStorage storage.Interface, err error) {
|
||||
func newEtcd(etcdConfigFile string, etcdServerList util.StringList, interfacesFunc meta.VersionInterfacesFunc, defaultVersion, storageVersion, pathPrefix string) (etcdStorage storage.Interface, err error) {
|
||||
var client tools.EtcdClient
|
||||
if etcdConfigFile != "" {
|
||||
client, err = etcd.NewClientFromFile(etcdConfigFile)
|
||||
@ -237,7 +244,10 @@ func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersi
|
||||
client = etcdClient
|
||||
}
|
||||
|
||||
return master.NewEtcdStorage(client, storageVersion, pathPrefix)
|
||||
if storageVersion == "" {
|
||||
storageVersion = defaultVersion
|
||||
}
|
||||
return master.NewEtcdStorage(client, interfacesFunc, storageVersion, pathPrefix)
|
||||
}
|
||||
|
||||
// Run runs the specified APIServer. This should never exit.
|
||||
@ -292,6 +302,10 @@ func (s *APIServer) Run(_ []string) error {
|
||||
disableV1 := disableAllAPIs
|
||||
disableV1 = !s.getRuntimeConfigValue("api/v1", !disableV1)
|
||||
|
||||
// "experimental/v1={true|false} allows users to enable/disable the experimental API.
|
||||
// This takes preference over api/all, if specified.
|
||||
enableExp := s.getRuntimeConfigValue("experimental/v1", false)
|
||||
|
||||
// TODO: expose same flags as client.BindClientConfigFlags but for a server
|
||||
clientConfig := &client.Config{
|
||||
Host: net.JoinHostPort(s.InsecureBindAddress.String(), strconv.Itoa(s.InsecurePort)),
|
||||
@ -302,10 +316,14 @@ func (s *APIServer) Run(_ []string) error {
|
||||
glog.Fatalf("Invalid server address: %v", err)
|
||||
}
|
||||
|
||||
etcdStorage, err := newEtcd(s.EtcdConfigFile, s.EtcdServerList, s.StorageVersion, s.EtcdPathPrefix)
|
||||
etcdStorage, err := newEtcd(s.EtcdConfigFile, s.EtcdServerList, latest.InterfacesFor, latest.Version, s.StorageVersion, s.EtcdPathPrefix)
|
||||
if err != nil {
|
||||
glog.Fatalf("Invalid storage version or misconfigured etcd: %v", err)
|
||||
}
|
||||
expEtcdStorage, err := newEtcd(s.EtcdConfigFile, s.EtcdServerList, explatest.InterfacesFor, explatest.Version, s.ExpStorageVersion, s.EtcdPathPrefix)
|
||||
if err != nil {
|
||||
glog.Fatalf("Invalid experimental storage version or misconfigured etcd: %v", err)
|
||||
}
|
||||
|
||||
n := net.IPNet(s.ServiceClusterIPRange)
|
||||
|
||||
@ -360,7 +378,9 @@ func (s *APIServer) Run(_ []string) error {
|
||||
}
|
||||
}
|
||||
config := &master.Config{
|
||||
DatabaseStorage: etcdStorage,
|
||||
DatabaseStorage: etcdStorage,
|
||||
ExpDatabaseStorage: expEtcdStorage,
|
||||
|
||||
EventTTL: s.EventTTL,
|
||||
KubeletClient: kubeletClient,
|
||||
ServiceClusterIPRange: &n,
|
||||
@ -371,6 +391,7 @@ func (s *APIServer) Run(_ []string) error {
|
||||
EnableProfiling: s.EnableProfiling,
|
||||
EnableIndex: true,
|
||||
APIPrefix: s.APIPrefix,
|
||||
ExpAPIPrefix: s.ExpAPIPrefix,
|
||||
CorsAllowedOriginList: s.CorsAllowedOriginList,
|
||||
ReadWritePort: s.SecurePort,
|
||||
PublicAddress: net.IP(s.AdvertiseAddress),
|
||||
@ -379,6 +400,7 @@ func (s *APIServer) Run(_ []string) error {
|
||||
Authorizer: authorizer,
|
||||
AdmissionControl: admissionController,
|
||||
DisableV1: disableV1,
|
||||
EnableExp: enableExp,
|
||||
MasterServiceNamespace: s.MasterServiceNamespace,
|
||||
ClusterName: s.ClusterName,
|
||||
ExternalHost: s.ExternalHost,
|
||||
|
@ -30,12 +30,14 @@ import (
|
||||
|
||||
kubeletapp "github.com/GoogleCloudPlatform/kubernetes/cmd/kubelet/app"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/nodecontroller"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/servicecontroller"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication"
|
||||
explatest "github.com/GoogleCloudPlatform/kubernetes/pkg/expapi/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/cadvisor"
|
||||
kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
|
||||
@ -79,14 +81,19 @@ func (h *delegateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
func runApiServer(etcdClient tools.EtcdClient, addr net.IP, port int, masterServiceNamespace string) {
|
||||
handler := delegateHandler{}
|
||||
|
||||
etcdStorage, err := master.NewEtcdStorage(etcdClient, "", master.DefaultEtcdPathPrefix)
|
||||
etcdStorage, err := master.NewEtcdStorage(etcdClient, latest.InterfacesFor, latest.Version, master.DefaultEtcdPathPrefix)
|
||||
if err != nil {
|
||||
glog.Fatalf("Unable to get etcd storage: %v", err)
|
||||
}
|
||||
expEtcdStorage, err := master.NewEtcdStorage(etcdClient, explatest.InterfacesFor, explatest.Version, master.DefaultEtcdPathPrefix)
|
||||
if err != nil {
|
||||
glog.Fatalf("Unable to get etcd storage for experimental: %v", err)
|
||||
}
|
||||
|
||||
// Create a master and install handlers into mux.
|
||||
m := master.New(&master.Config{
|
||||
DatabaseStorage: etcdStorage,
|
||||
DatabaseStorage: etcdStorage,
|
||||
ExpDatabaseStorage: expEtcdStorage,
|
||||
KubeletClient: &client.HTTPKubeletClient{
|
||||
Client: http.DefaultClient,
|
||||
Config: &client.KubeletConfig{Port: 10250},
|
||||
@ -96,6 +103,7 @@ func runApiServer(etcdClient tools.EtcdClient, addr net.IP, port int, masterServ
|
||||
EnableSwaggerSupport: true,
|
||||
EnableProfiling: *enableProfiling,
|
||||
APIPrefix: "/api",
|
||||
ExpAPIPrefix: "/experimental",
|
||||
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
|
||||
|
||||
ReadWritePort: port,
|
||||
|
@ -63,6 +63,8 @@ var RESTMapper meta.RESTMapper
|
||||
// userResources is a group of resources mostly used by a kubectl user
|
||||
var userResources = []string{"rc", "svc", "pods", "pvc"}
|
||||
|
||||
const importPrefix = "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
|
||||
func init() {
|
||||
// Use the first API version in the list of registered versions as the latest.
|
||||
Version = registered.RegisteredVersions[0]
|
||||
@ -75,28 +77,14 @@ func init() {
|
||||
Versions = append(Versions, versions[i])
|
||||
}
|
||||
|
||||
mapper := meta.NewDefaultRESTMapper(
|
||||
versions,
|
||||
func(version string) (*meta.VersionInterfaces, bool) {
|
||||
interfaces, err := InterfacesFor(version)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return interfaces, true
|
||||
},
|
||||
)
|
||||
|
||||
// the list of kinds that are scoped at the root of the api hierarchy
|
||||
// if a kind is not enumerated here, it is assumed to have a namespace scope
|
||||
kindToRootScope := map[string]bool{
|
||||
"Node": true,
|
||||
"Minion": true,
|
||||
"Namespace": true,
|
||||
"PersistentVolume": true,
|
||||
}
|
||||
|
||||
// setup aliases for groups of resources
|
||||
mapper.AddResourceAlias("all", userResources...)
|
||||
rootScoped := util.NewStringSet(
|
||||
"Node",
|
||||
"Minion",
|
||||
"Namespace",
|
||||
"PersistentVolume",
|
||||
)
|
||||
|
||||
// these kinds should be excluded from the list of resources
|
||||
ignoredKinds := util.NewStringSet(
|
||||
@ -107,20 +95,11 @@ func init() {
|
||||
"PodExecOptions",
|
||||
"PodProxyOptions")
|
||||
|
||||
// enumerate all supported versions, get the kinds, and register with the mapper how to address our resources.
|
||||
for _, version := range versions {
|
||||
for kind := range api.Scheme.KnownTypes(version) {
|
||||
if ignoredKinds.Has(kind) {
|
||||
continue
|
||||
}
|
||||
scope := meta.RESTScopeNamespace
|
||||
if kindToRootScope[kind] {
|
||||
scope = meta.RESTScopeRoot
|
||||
}
|
||||
mapper.Add(scope, kind, version, false)
|
||||
}
|
||||
}
|
||||
mapper := api.NewDefaultRESTMapper(versions, InterfacesFor, importPrefix, ignoredKinds, rootScoped)
|
||||
// setup aliases for groups of resources
|
||||
mapper.AddResourceAlias("all", userResources...)
|
||||
RESTMapper = mapper
|
||||
api.RegisterRESTMapper(RESTMapper)
|
||||
}
|
||||
|
||||
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
|
||||
|
57
pkg/api/mapper.go
Normal file
57
pkg/api/mapper.go
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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 api
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
)
|
||||
|
||||
var RESTMapper meta.RESTMapper
|
||||
|
||||
func init() {
|
||||
RESTMapper = meta.MultiRESTMapper{}
|
||||
}
|
||||
|
||||
func RegisterRESTMapper(m meta.RESTMapper) {
|
||||
RESTMapper = append(RESTMapper.(meta.MultiRESTMapper), m)
|
||||
}
|
||||
|
||||
func NewDefaultRESTMapper(versions []string, interfacesFunc meta.VersionInterfacesFunc, importPathPrefix string,
|
||||
ignoredKinds, rootScoped util.StringSet) *meta.DefaultRESTMapper {
|
||||
|
||||
mapper := meta.NewDefaultRESTMapper(versions, interfacesFunc)
|
||||
// enumerate all supported versions, get the kinds, and register with the mapper how to address our resources.
|
||||
for _, version := range versions {
|
||||
for kind, oType := range Scheme.KnownTypes(version) {
|
||||
// TODO: Remove import path prefix check.
|
||||
// We check the import path prefix because we currently stuff both "api" and "experimental" objects
|
||||
// into the same group within Scheme since Scheme has no notion of groups yet.
|
||||
if !strings.HasPrefix(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) {
|
||||
continue
|
||||
}
|
||||
scope := meta.RESTScopeNamespace
|
||||
if rootScoped.Has(kind) {
|
||||
scope = meta.RESTScopeRoot
|
||||
}
|
||||
mapper.Add(scope, kind, version, false)
|
||||
}
|
||||
}
|
||||
return mapper
|
||||
}
|
@ -83,8 +83,8 @@ type DefaultRESTMapper struct {
|
||||
}
|
||||
|
||||
// VersionInterfacesFunc returns the appropriate codec, typer, and metadata accessor for a
|
||||
// given api version, or false if no such api version exists.
|
||||
type VersionInterfacesFunc func(apiVersion string) (*VersionInterfaces, bool)
|
||||
// given api version, or an error if no such api version exists.
|
||||
type VersionInterfacesFunc func(apiVersion string) (*VersionInterfaces, error)
|
||||
|
||||
// NewDefaultRESTMapper initializes a mapping between Kind and APIVersion
|
||||
// to a resource name and back based on the objects in a runtime.Scheme
|
||||
@ -226,8 +226,8 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM
|
||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", version, kind)
|
||||
}
|
||||
|
||||
interfaces, ok := m.interfacesFunc(version)
|
||||
if !ok {
|
||||
interfaces, err := m.interfacesFunc(version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the provided version %q has no relevant versions", version)
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package meta
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
@ -54,12 +55,14 @@ var validCodec = fakeCodec{}
|
||||
var validAccessor = resourceAccessor{}
|
||||
var validConvertor = fakeConvertor{}
|
||||
|
||||
func fakeInterfaces(version string) (*VersionInterfaces, bool) {
|
||||
return &VersionInterfaces{Codec: validCodec, ObjectConvertor: validConvertor, MetadataAccessor: validAccessor}, true
|
||||
func fakeInterfaces(version string) (*VersionInterfaces, error) {
|
||||
return &VersionInterfaces{Codec: validCodec, ObjectConvertor: validConvertor, MetadataAccessor: validAccessor}, nil
|
||||
}
|
||||
|
||||
func unmatchedVersionInterfaces(version string) (*VersionInterfaces, bool) {
|
||||
return nil, false
|
||||
var unmatchedErr = errors.New("no version")
|
||||
|
||||
func unmatchedVersionInterfaces(version string) (*VersionInterfaces, error) {
|
||||
return nil, unmatchedErr
|
||||
}
|
||||
|
||||
func TestRESTMapperVersionAndKindForResource(t *testing.T) {
|
||||
|
@ -88,16 +88,7 @@ func interfacesFor(version string) (*meta.VersionInterfaces, error) {
|
||||
}
|
||||
|
||||
func newMapper() *meta.DefaultRESTMapper {
|
||||
return meta.NewDefaultRESTMapper(
|
||||
versions,
|
||||
func(version string) (*meta.VersionInterfaces, bool) {
|
||||
interfaces, err := interfacesFor(version)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return interfaces, true
|
||||
},
|
||||
)
|
||||
return meta.NewDefaultRESTMapper(versions, interfacesFor)
|
||||
}
|
||||
|
||||
func addTestTypes() {
|
||||
|
19
pkg/expapi/deep_copy.go
Normal file
19
pkg/expapi/deep_copy.go
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
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 expapi
|
||||
|
||||
func addDeepCopyFuncs() {}
|
75
pkg/expapi/latest/latest.go
Normal file
75
pkg/expapi/latest/latest.go
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
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 latest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/registered"
|
||||
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/expapi"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/expapi/v1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
)
|
||||
|
||||
var (
|
||||
Version string
|
||||
Versions []string
|
||||
|
||||
accessor = meta.NewAccessor()
|
||||
Codec runtime.Codec
|
||||
SelfLinker = runtime.SelfLinker(accessor)
|
||||
RESTMapper meta.RESTMapper
|
||||
)
|
||||
|
||||
const importPrefix = "github.com/GoogleCloudPlatform/kubernetes/pkg/expapi"
|
||||
|
||||
func init() {
|
||||
Version = registered.RegisteredVersions[0]
|
||||
Codec = runtime.CodecFor(api.Scheme, Version)
|
||||
// Put the registered versions in Versions in reverse order.
|
||||
for i := len(registered.RegisteredVersions) - 1; i >= 0; i-- {
|
||||
Versions = append(Versions, registered.RegisteredVersions[i])
|
||||
}
|
||||
|
||||
// the list of kinds that are scoped at the root of the api hierarchy
|
||||
// if a kind is not enumerated here, it is assumed to have a namespace scope
|
||||
rootScoped := util.NewStringSet()
|
||||
|
||||
ignoredKinds := util.NewStringSet()
|
||||
|
||||
RESTMapper = api.NewDefaultRESTMapper(Versions, InterfacesFor, importPrefix, ignoredKinds, rootScoped)
|
||||
api.RegisterRESTMapper(RESTMapper)
|
||||
}
|
||||
|
||||
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
|
||||
// string, or an error if the version is not known.
|
||||
func InterfacesFor(version string) (*meta.VersionInterfaces, error) {
|
||||
switch version {
|
||||
case "v1":
|
||||
return &meta.VersionInterfaces{
|
||||
Codec: v1.Codec,
|
||||
ObjectConvertor: api.Scheme,
|
||||
MetadataAccessor: accessor,
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", "))
|
||||
}
|
||||
}
|
19
pkg/expapi/register.go
Normal file
19
pkg/expapi/register.go
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
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 expapi
|
||||
|
||||
func init() {}
|
29
pkg/expapi/types.go
Normal file
29
pkg/expapi/types.go
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file (together with pkg/expapi/v1/types.go) contain the experimental
|
||||
types in kubernetes. These API objects are experimental, meaning that the
|
||||
APIs may be broken at any time by the kubernetes team.
|
||||
|
||||
DISCLAIMER: The implementation of the experimental API group itself is
|
||||
a temporary one meant as a stopgap solution until kubernetes has proper
|
||||
support for multiple API groups. The transition may require changes
|
||||
beyond registration differences. In other words, experimental API group
|
||||
support is experimental.
|
||||
*/
|
||||
|
||||
package expapi
|
19
pkg/expapi/v1/conversion.go
Normal file
19
pkg/expapi/v1/conversion.go
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
func addConversionFuncs() {}
|
19
pkg/expapi/v1/deep_copy.go
Normal file
19
pkg/expapi/v1/deep_copy.go
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
func addDeepCopyFuncs() {}
|
19
pkg/expapi/v1/defaults.go
Normal file
19
pkg/expapi/v1/defaults.go
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
func addDefaultingFuncs() {}
|
30
pkg/expapi/v1/register.go
Normal file
30
pkg/expapi/v1/register.go
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
var Codec = runtime.CodecFor(api.Scheme, "v1")
|
||||
|
||||
func init() {
|
||||
addDeepCopyFuncs()
|
||||
addConversionFuncs()
|
||||
addDefaultingFuncs()
|
||||
}
|
17
pkg/expapi/v1/types.go
Normal file
17
pkg/expapi/v1/types.go
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
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 v1
|
@ -18,6 +18,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -64,6 +65,15 @@ func (*internalType) IsAnAPIObject() {}
|
||||
func (*externalType) IsAnAPIObject() {}
|
||||
func (*ExternalType2) IsAnAPIObject() {}
|
||||
|
||||
var versionErr = errors.New("not a version")
|
||||
|
||||
func versionErrIfFalse(b bool) error {
|
||||
if b {
|
||||
return nil
|
||||
}
|
||||
return versionErr
|
||||
}
|
||||
|
||||
func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName("", "Type", &internalType{})
|
||||
@ -73,12 +83,12 @@ func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
|
||||
|
||||
codec := runtime.CodecFor(scheme, "unlikelyversion")
|
||||
validVersion := testapi.Version()
|
||||
mapper := meta.NewDefaultRESTMapper([]string{"unlikelyversion", validVersion}, func(version string) (*meta.VersionInterfaces, bool) {
|
||||
mapper := meta.NewDefaultRESTMapper([]string{"unlikelyversion", validVersion}, func(version string) (*meta.VersionInterfaces, error) {
|
||||
return &meta.VersionInterfaces{
|
||||
Codec: runtime.CodecFor(scheme, version),
|
||||
ObjectConvertor: scheme,
|
||||
MetadataAccessor: meta.NewAccessor(),
|
||||
}, (version == validVersion || version == "unlikelyversion")
|
||||
}, versionErrIfFalse(version == validVersion || version == "unlikelyversion")
|
||||
})
|
||||
for _, version := range []string{"unlikelyversion", validVersion} {
|
||||
for kind := range scheme.KnownTypes(version) {
|
||||
|
@ -36,6 +36,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||
@ -43,6 +44,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/handlers"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
explatest "github.com/GoogleCloudPlatform/kubernetes/pkg/expapi/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
@ -89,22 +91,25 @@ const (
|
||||
|
||||
// Config is a structure used to configure a Master.
|
||||
type Config struct {
|
||||
DatabaseStorage storage.Interface
|
||||
EventTTL time.Duration
|
||||
MinionRegexp string
|
||||
KubeletClient client.KubeletClient
|
||||
DatabaseStorage storage.Interface
|
||||
ExpDatabaseStorage storage.Interface
|
||||
EventTTL time.Duration
|
||||
MinionRegexp string
|
||||
KubeletClient client.KubeletClient
|
||||
// allow downstream consumers to disable the core controller loops
|
||||
EnableCoreControllers bool
|
||||
EnableLogsSupport bool
|
||||
EnableUISupport bool
|
||||
// allow downstream consumers to disable swagger
|
||||
EnableSwaggerSupport bool
|
||||
// allow v1 to be conditionally disabled
|
||||
// allow api versions to be conditionally disabled
|
||||
DisableV1 bool
|
||||
EnableExp bool
|
||||
// allow downstream consumers to disable the index route
|
||||
EnableIndex bool
|
||||
EnableProfiling bool
|
||||
APIPrefix string
|
||||
ExpAPIPrefix string
|
||||
CorsAllowedOriginList util.StringList
|
||||
Authenticator authenticator.Request
|
||||
// TODO(roberthbailey): Remove once the server no longer supports http basic auth.
|
||||
@ -181,12 +186,14 @@ type Master struct {
|
||||
enableSwaggerSupport bool
|
||||
enableProfiling bool
|
||||
apiPrefix string
|
||||
expAPIPrefix string
|
||||
corsAllowedOriginList util.StringList
|
||||
authenticator authenticator.Request
|
||||
authorizer authorizer.Authorizer
|
||||
admissionControl admission.Interface
|
||||
masterCount int
|
||||
v1 bool
|
||||
exp bool
|
||||
requestContextMapper api.RequestContextMapper
|
||||
|
||||
// External host is the name that should be used in external (public internet) URLs for this master
|
||||
@ -227,11 +234,8 @@ type Master struct {
|
||||
|
||||
// NewEtcdStorage returns a storage.Interface for the provided arguments or an error if the version
|
||||
// is incorrect.
|
||||
func NewEtcdStorage(client tools.EtcdClient, version string, prefix string) (etcdStorage storage.Interface, err error) {
|
||||
if version == "" {
|
||||
version = latest.Version
|
||||
}
|
||||
versionInterfaces, err := latest.InterfacesFor(version)
|
||||
func NewEtcdStorage(client tools.EtcdClient, interfacesFunc meta.VersionInterfacesFunc, version, prefix string) (etcdStorage storage.Interface, err error) {
|
||||
versionInterfaces, err := interfacesFunc(version)
|
||||
if err != nil {
|
||||
return etcdStorage, err
|
||||
}
|
||||
@ -337,11 +341,13 @@ func New(c *Config) *Master {
|
||||
enableSwaggerSupport: c.EnableSwaggerSupport,
|
||||
enableProfiling: c.EnableProfiling,
|
||||
apiPrefix: c.APIPrefix,
|
||||
expAPIPrefix: c.ExpAPIPrefix,
|
||||
corsAllowedOriginList: c.CorsAllowedOriginList,
|
||||
authenticator: c.Authenticator,
|
||||
authorizer: c.Authorizer,
|
||||
admissionControl: c.AdmissionControl,
|
||||
v1: !c.DisableV1,
|
||||
exp: c.EnableExp,
|
||||
requestContextMapper: c.RequestContextMapper,
|
||||
|
||||
cacheTimeout: c.CacheTimeout,
|
||||
@ -566,6 +572,16 @@ func (m *Master) init(c *Config) {
|
||||
requestInfoResolver := &apiserver.APIRequestInfoResolver{util.NewStringSet(strings.TrimPrefix(defaultVersion.Root, "/")), defaultVersion.Mapper}
|
||||
apiserver.InstallServiceErrorHandler(m.handlerContainer, requestInfoResolver, apiVersions)
|
||||
|
||||
if m.exp {
|
||||
expVersion := m.expapi(c)
|
||||
if err := expVersion.InstallREST(m.handlerContainer); err != nil {
|
||||
glog.Fatalf("Unable to setup experimental api: %v", err)
|
||||
}
|
||||
apiserver.AddApiWebService(m.handlerContainer, c.ExpAPIPrefix, []string{expVersion.Version})
|
||||
expRequestInfoResolver := &apiserver.APIRequestInfoResolver{util.NewStringSet(strings.TrimPrefix(expVersion.Root, "/")), expVersion.Mapper}
|
||||
apiserver.InstallServiceErrorHandler(m.handlerContainer, expRequestInfoResolver, []string{expVersion.Version})
|
||||
}
|
||||
|
||||
// Register root handler.
|
||||
// We do not register this using restful Webservice since we do not want to surface this in api docs.
|
||||
// Allow master to be embedded in contexts which already have something registered at the root
|
||||
@ -760,6 +776,30 @@ func (m *Master) api_v1() *apiserver.APIGroupVersion {
|
||||
return version
|
||||
}
|
||||
|
||||
// expapi returns the resources and codec for the experimental api
|
||||
func (m *Master) expapi(c *Config) *apiserver.APIGroupVersion {
|
||||
storage := map[string]rest.Storage{}
|
||||
return &apiserver.APIGroupVersion{
|
||||
Root: m.expAPIPrefix,
|
||||
|
||||
Creater: api.Scheme,
|
||||
Convertor: api.Scheme,
|
||||
Typer: api.Scheme,
|
||||
|
||||
Mapper: explatest.RESTMapper,
|
||||
Codec: explatest.Codec,
|
||||
Linker: explatest.SelfLinker,
|
||||
Storage: storage,
|
||||
Version: explatest.Version,
|
||||
|
||||
Admit: m.admissionControl,
|
||||
Context: m.requestContextMapper,
|
||||
|
||||
ProxyDialerFn: m.dialer,
|
||||
MinRequestTimeout: m.minRequestTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
// findExternalAddress returns ExternalIP of provided node with fallback to LegacyHostIP.
|
||||
func findExternalAddress(node *api.Node) (string, error) {
|
||||
var fallback string
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
explatest "github.com/GoogleCloudPlatform/kubernetes/pkg/expapi/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
|
||||
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
|
||||
@ -33,6 +34,7 @@ func TestGetServersToValidate(t *testing.T) {
|
||||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"}
|
||||
config.DatabaseStorage = etcdstorage.NewEtcdStorage(fakeClient, latest.Codec, etcdtest.PathPrefix())
|
||||
config.ExpDatabaseStorage = etcdstorage.NewEtcdStorage(fakeClient, explatest.Codec, etcdtest.PathPrefix())
|
||||
|
||||
master.nodeRegistry = registrytest.NewMinionRegistry([]string{"node1", "node2"}, api.NodeResources{})
|
||||
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
)
|
||||
@ -138,7 +137,7 @@ func TestSyncNamespaceThatIsActive(t *testing.T) {
|
||||
|
||||
func TestRunStop(t *testing.T) {
|
||||
o := testclient.NewObjects(api.Scheme, api.Scheme)
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)}
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, api.RESTMapper)}
|
||||
nsMgr := NewNamespaceManager(client, 1*time.Second)
|
||||
|
||||
if nsMgr.StopEverything != nil {
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
|
||||
@ -238,7 +237,7 @@ func TestNewBuilder(t *testing.T) {
|
||||
o := testclient.NewObjects(api.Scheme, api.Scheme)
|
||||
o.Add(item.pv)
|
||||
o.Add(item.claim)
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)}
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, api.RESTMapper)}
|
||||
|
||||
plugMgr := volume.VolumePluginMgr{}
|
||||
plugMgr.InitPlugins(testProbeVolumePlugins(), newTestHost(t, client))
|
||||
@ -295,7 +294,7 @@ func TestNewBuilderClaimNotBound(t *testing.T) {
|
||||
o := testclient.NewObjects(api.Scheme, api.Scheme)
|
||||
o.Add(pv)
|
||||
o.Add(claim)
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)}
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, api.RESTMapper)}
|
||||
|
||||
plugMgr := volume.VolumePluginMgr{}
|
||||
plugMgr.InitPlugins(testProbeVolumePlugins(), newTestHost(t, client))
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
|
||||
@ -32,7 +31,7 @@ import (
|
||||
|
||||
func TestRunStop(t *testing.T) {
|
||||
o := testclient.NewObjects(api.Scheme, api.Scheme)
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)}
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, api.RESTMapper)}
|
||||
binder := NewPersistentVolumeClaimBinder(client, 1*time.Second)
|
||||
|
||||
if len(binder.stopChannels) != 0 {
|
||||
@ -119,7 +118,7 @@ func TestExampleObjects(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)}
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, api.RESTMapper)}
|
||||
|
||||
if reflect.TypeOf(scenario.expected) == reflect.TypeOf(&api.PersistentVolumeClaim{}) {
|
||||
pvc, err := client.PersistentVolumeClaims("ns").Get("doesntmatter")
|
||||
@ -179,7 +178,7 @@ func TestBindingWithExamples(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)}
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, api.RESTMapper)}
|
||||
|
||||
pv, err := client.PersistentVolumes().Get("any")
|
||||
pv.Spec.PersistentVolumeReclaimPolicy = api.PersistentVolumeReclaimRecycle
|
||||
@ -282,7 +281,7 @@ func TestMissingFromIndex(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)}
|
||||
client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, api.RESTMapper)}
|
||||
|
||||
pv, err := client.PersistentVolumes().Get("any")
|
||||
if err != nil {
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
|
||||
@ -48,11 +47,11 @@ type provision struct {
|
||||
}
|
||||
|
||||
func (p *provision) Admit(a admission.Attributes) (err error) {
|
||||
defaultVersion, kind, err := latest.RESTMapper.VersionAndKindForResource(a.GetResource())
|
||||
defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource())
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
mapping, err := latest.RESTMapper.RESTMapping(kind, defaultVersion)
|
||||
mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion)
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
|
||||
@ -49,11 +48,11 @@ type exists struct {
|
||||
}
|
||||
|
||||
func (e *exists) Admit(a admission.Attributes) (err error) {
|
||||
defaultVersion, kind, err := latest.RESTMapper.VersionAndKindForResource(a.GetResource())
|
||||
defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource())
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
mapping, err := latest.RESTMapper.RESTMapping(kind, defaultVersion)
|
||||
mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion)
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
|
||||
@ -59,11 +58,11 @@ func (l *lifecycle) Admit(a admission.Attributes) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
defaultVersion, kind, err := latest.RESTMapper.VersionAndKindForResource(a.GetResource())
|
||||
defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource())
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
mapping, err := latest.RESTMapper.RESTMapping(kind, defaultVersion)
|
||||
mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion)
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
|
||||
@ -42,7 +43,7 @@ func NewEtcdClient() *etcd.Client {
|
||||
}
|
||||
|
||||
func NewEtcdStorage() (storage.Interface, error) {
|
||||
return master.NewEtcdStorage(NewEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
|
||||
return master.NewEtcdStorage(NewEtcdClient(), latest.InterfacesFor, testapi.Version(), etcdtest.PathPrefix())
|
||||
}
|
||||
|
||||
func RequireEtcd() {
|
||||
|
@ -26,11 +26,13 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/record"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication"
|
||||
explatest "github.com/GoogleCloudPlatform/kubernetes/pkg/expapi/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
@ -128,19 +130,27 @@ func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Se
|
||||
var etcdStorage storage.Interface
|
||||
var err error
|
||||
if masterConfig == nil {
|
||||
etcdStorage, err = master.NewEtcdStorage(NewEtcdClient(), "", etcdtest.PathPrefix())
|
||||
etcdClient := NewEtcdClient()
|
||||
etcdStorage, err = master.NewEtcdStorage(etcdClient, latest.InterfacesFor, latest.Version, etcdtest.PathPrefix())
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to create etcd storage for master %v", err)
|
||||
}
|
||||
expEtcdStorage, err := master.NewEtcdStorage(etcdClient, explatest.InterfacesFor, explatest.Version, etcdtest.PathPrefix())
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to create etcd storage for master %v", err)
|
||||
}
|
||||
|
||||
masterConfig = &master.Config{
|
||||
DatabaseStorage: etcdStorage,
|
||||
KubeletClient: client.FakeKubeletClient{},
|
||||
EnableLogsSupport: false,
|
||||
EnableProfiling: true,
|
||||
EnableUISupport: false,
|
||||
APIPrefix: "/api",
|
||||
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
|
||||
AdmissionControl: admit.NewAlwaysAdmit(),
|
||||
DatabaseStorage: etcdStorage,
|
||||
ExpDatabaseStorage: expEtcdStorage,
|
||||
KubeletClient: client.FakeKubeletClient{},
|
||||
EnableLogsSupport: false,
|
||||
EnableProfiling: true,
|
||||
EnableUISupport: false,
|
||||
APIPrefix: "/api",
|
||||
ExpAPIPrefix: "/experimental",
|
||||
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
|
||||
AdmissionControl: admit.NewAlwaysAdmit(),
|
||||
}
|
||||
} else {
|
||||
etcdStorage = masterConfig.DatabaseStorage
|
||||
@ -258,20 +268,28 @@ func StartPods(numPods int, host string, restClient *client.Client) error {
|
||||
|
||||
// TODO: Merge this into startMasterOrDie.
|
||||
func RunAMaster(t *testing.T) (*master.Master, *httptest.Server) {
|
||||
etcdStorage, err := master.NewEtcdStorage(NewEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
|
||||
etcdClient := NewEtcdClient()
|
||||
etcdStorage, err := master.NewEtcdStorage(etcdClient, latest.InterfacesFor, testapi.Version(), etcdtest.PathPrefix())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
expEtcdStorage, err := master.NewEtcdStorage(etcdClient, explatest.InterfacesFor, explatest.Version, etcdtest.PathPrefix())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
m := master.New(&master.Config{
|
||||
DatabaseStorage: etcdStorage,
|
||||
KubeletClient: client.FakeKubeletClient{},
|
||||
EnableLogsSupport: false,
|
||||
EnableProfiling: true,
|
||||
EnableUISupport: false,
|
||||
APIPrefix: "/api",
|
||||
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
|
||||
AdmissionControl: admit.NewAlwaysAdmit(),
|
||||
DatabaseStorage: etcdStorage,
|
||||
ExpDatabaseStorage: expEtcdStorage,
|
||||
KubeletClient: client.FakeKubeletClient{},
|
||||
EnableLogsSupport: false,
|
||||
EnableProfiling: true,
|
||||
EnableUISupport: false,
|
||||
APIPrefix: "/api",
|
||||
ExpAPIPrefix: "/experimental",
|
||||
EnableExp: true,
|
||||
Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
|
||||
AdmissionControl: admit.NewAlwaysAdmit(),
|
||||
})
|
||||
|
||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
|
39
test/integration/master_test.go
Normal file
39
test/integration/master_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
// +build integration,!no-etcd
|
||||
|
||||
/*
|
||||
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 integration
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/test/integration/framework"
|
||||
)
|
||||
|
||||
func TestExperimentalPrefix(t *testing.T) {
|
||||
_, s := framework.RunAMaster(t)
|
||||
defer s.Close()
|
||||
|
||||
resp, err := http.Get(s.URL + "/experimental/")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error getting experimental prefix: %v", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("got status %v instead of 200 OK", resp.StatusCode)
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator/bearertoken"
|
||||
@ -340,7 +341,7 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
|
||||
deleteAllEtcdKeys()
|
||||
|
||||
// Etcd
|
||||
etcdStorage, err := master.NewEtcdStorage(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
|
||||
etcdStorage, err := master.NewEtcdStorage(newEtcdClient(), latest.InterfacesFor, testapi.Version(), etcdtest.PathPrefix())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
@ -67,7 +68,7 @@ func deleteAllEtcdKeys() {
|
||||
}
|
||||
|
||||
func runAMaster(t *testing.T) (*master.Master, *httptest.Server) {
|
||||
etcdStorage, err := master.NewEtcdStorage(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
|
||||
etcdStorage, err := master.NewEtcdStorage(newEtcdClient(), latest.InterfacesFor, testapi.Version(), etcdtest.PathPrefix())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user