mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 05:03:09 +00:00
Merge pull request #34551 from deads2k/api-23-remove-legacy-prefixy
Automatic merge from submit-queue Change legacy API resource registration Updates the legacy API resource registration to emphasize its different-ness and to simplify supporting objects. The option has to remain in the genericapiserverconfig for multiple prefixes to enable cases where composers/extenders had composed additional groupless APIs. See OpenShift as an example. However this is now transparent to "normal" composers. @ncdc since sttts is out.
This commit is contained in:
commit
dd529f3c4a
@ -61,12 +61,11 @@ func installCoreAPIs(s *options.ServerRunOptions, g *genericapiserver.GenericAPI
|
|||||||
v1.SchemeGroupVersion.Version: coreResources,
|
v1.SchemeGroupVersion.Version: coreResources,
|
||||||
},
|
},
|
||||||
OptionsExternalVersion: ®istered.GroupOrDie(core.GroupName).GroupVersion,
|
OptionsExternalVersion: ®istered.GroupOrDie(core.GroupName).GroupVersion,
|
||||||
IsLegacyGroup: true,
|
|
||||||
Scheme: core.Scheme,
|
Scheme: core.Scheme,
|
||||||
ParameterCodec: core.ParameterCodec,
|
ParameterCodec: core.ParameterCodec,
|
||||||
NegotiatedSerializer: core.Codecs,
|
NegotiatedSerializer: core.Codecs,
|
||||||
}
|
}
|
||||||
if err := g.InstallAPIGroup(&apiGroupInfo); err != nil {
|
if err := g.InstallLegacyAPIGroup(genericapiserver.LegacyAPIPrefix, &apiGroupInfo); err != nil {
|
||||||
glog.Fatalf("Error in registering group version: %+v.\n Error: %v\n", apiGroupInfo, err)
|
glog.Fatalf("Error in registering group version: %+v.\n Error: %v\n", apiGroupInfo, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,11 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// LegacyAPIPrefix is where the the legacy APIs will be located
|
||||||
|
LegacyAPIPrefix = "/api"
|
||||||
|
)
|
||||||
|
|
||||||
// Config is a structure used to configure a GenericAPIServer.
|
// Config is a structure used to configure a GenericAPIServer.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Destination for audit logs
|
// Destination for audit logs
|
||||||
@ -73,7 +78,6 @@ type Config struct {
|
|||||||
EnableProfiling bool
|
EnableProfiling bool
|
||||||
EnableVersion bool
|
EnableVersion bool
|
||||||
EnableGarbageCollection bool
|
EnableGarbageCollection bool
|
||||||
APIPrefix string
|
|
||||||
APIGroupPrefix string
|
APIGroupPrefix string
|
||||||
CorsAllowedOriginList []string
|
CorsAllowedOriginList []string
|
||||||
Authenticator authenticator.Request
|
Authenticator authenticator.Request
|
||||||
@ -168,6 +172,10 @@ type Config struct {
|
|||||||
|
|
||||||
// Build the handler chains by decorating the apiHandler.
|
// Build the handler chains by decorating the apiHandler.
|
||||||
BuildHandlerChainsFunc func(apiHandler http.Handler, c *Config) (secure, insecure http.Handler)
|
BuildHandlerChainsFunc func(apiHandler http.Handler, c *Config) (secure, insecure http.Handler)
|
||||||
|
|
||||||
|
// LegacyAPIGroupPrefixes is used to set up URL parsing for authorization and for validating requests
|
||||||
|
// to InstallLegacyAPIGroup
|
||||||
|
LegacyAPIGroupPrefixes sets.String
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServingInfo struct {
|
type ServingInfo struct {
|
||||||
@ -227,7 +235,6 @@ func NewConfig(options *options.ServerRunOptions) *Config {
|
|||||||
|
|
||||||
return &Config{
|
return &Config{
|
||||||
APIGroupPrefix: options.APIGroupPrefix,
|
APIGroupPrefix: options.APIGroupPrefix,
|
||||||
APIPrefix: options.APIPrefix,
|
|
||||||
CorsAllowedOriginList: options.CorsAllowedOriginList,
|
CorsAllowedOriginList: options.CorsAllowedOriginList,
|
||||||
AuditWriter: auditWriter,
|
AuditWriter: auditWriter,
|
||||||
EnableGarbageCollection: options.EnableGarbageCollection,
|
EnableGarbageCollection: options.EnableGarbageCollection,
|
||||||
@ -261,8 +268,9 @@ func NewConfig(options *options.ServerRunOptions) *Config {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MaxRequestsInFlight: options.MaxRequestsInFlight,
|
MaxRequestsInFlight: options.MaxRequestsInFlight,
|
||||||
LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(longRunningRE, map[string]string{"watch": "true"}),
|
LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(longRunningRE, map[string]string{"watch": "true"}),
|
||||||
|
LegacyAPIGroupPrefixes: sets.NewString(LegacyAPIPrefix),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,13 +371,13 @@ func (c completedConfig) New() (*GenericAPIServer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s := &GenericAPIServer{
|
s := &GenericAPIServer{
|
||||||
ServiceClusterIPRange: c.ServiceClusterIPRange,
|
ServiceClusterIPRange: c.ServiceClusterIPRange,
|
||||||
LoopbackClientConfig: c.LoopbackClientConfig,
|
LoopbackClientConfig: c.LoopbackClientConfig,
|
||||||
legacyAPIPrefix: c.APIPrefix,
|
apiPrefix: c.APIGroupPrefix,
|
||||||
apiPrefix: c.APIGroupPrefix,
|
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
|
||||||
admissionControl: c.AdmissionControl,
|
admissionControl: c.AdmissionControl,
|
||||||
requestContextMapper: c.RequestContextMapper,
|
requestContextMapper: c.RequestContextMapper,
|
||||||
Serializer: c.Serializer,
|
Serializer: c.Serializer,
|
||||||
|
|
||||||
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
|
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
|
||||||
enableSwaggerSupport: c.EnableSwaggerSupport,
|
enableSwaggerSupport: c.EnableSwaggerSupport,
|
||||||
@ -498,8 +506,15 @@ func DefaultAndValidateRunOptions(options *options.ServerRunOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewRequestInfoResolver(c *Config) *request.RequestInfoFactory {
|
func NewRequestInfoResolver(c *Config) *request.RequestInfoFactory {
|
||||||
|
apiPrefixes := sets.NewString(strings.Trim(c.APIGroupPrefix, "/")) // all possible API prefixes
|
||||||
|
legacyAPIPrefixes := sets.String{} // APIPrefixes that won't have groups (legacy)
|
||||||
|
for legacyAPIPrefix := range c.LegacyAPIGroupPrefixes {
|
||||||
|
apiPrefixes.Insert(strings.Trim(legacyAPIPrefix, "/"))
|
||||||
|
legacyAPIPrefixes.Insert(strings.Trim(legacyAPIPrefix, "/"))
|
||||||
|
}
|
||||||
|
|
||||||
return &request.RequestInfoFactory{
|
return &request.RequestInfoFactory{
|
||||||
APIPrefixes: sets.NewString(strings.Trim(c.APIPrefix, "/"), strings.Trim(c.APIGroupPrefix, "/")), // all possible API prefixes
|
APIPrefixes: apiPrefixes,
|
||||||
GrouplessAPIPrefixes: sets.NewString(strings.Trim(c.APIPrefix, "/")), // APIPrefixes that won't have groups (legacy)
|
GrouplessAPIPrefixes: legacyAPIPrefixes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ import (
|
|||||||
certutil "k8s.io/kubernetes/pkg/util/cert"
|
certutil "k8s.io/kubernetes/pkg/util/cert"
|
||||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
|
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
|
||||||
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Info about an API group.
|
// Info about an API group.
|
||||||
@ -56,8 +57,6 @@ type APIGroupInfo struct {
|
|||||||
GroupMeta apimachinery.GroupMeta
|
GroupMeta apimachinery.GroupMeta
|
||||||
// Info about the resources in this group. Its a map from version to resource to the storage.
|
// Info about the resources in this group. Its a map from version to resource to the storage.
|
||||||
VersionedResourcesStorageMap map[string]map[string]rest.Storage
|
VersionedResourcesStorageMap map[string]map[string]rest.Storage
|
||||||
// True, if this is the legacy group ("/v1").
|
|
||||||
IsLegacyGroup bool
|
|
||||||
// OptionsExternalVersion controls the APIVersion used for common objects in the
|
// OptionsExternalVersion controls the APIVersion used for common objects in the
|
||||||
// schema like api.Status, api.DeleteOptions, and api.ListOptions. Other implementors may
|
// schema like api.Status, api.DeleteOptions, and api.ListOptions. Other implementors may
|
||||||
// define a version "v1beta1" but want to use the Kubernetes "v1" internal objects.
|
// define a version "v1beta1" but want to use the Kubernetes "v1" internal objects.
|
||||||
@ -102,13 +101,13 @@ type GenericAPIServer struct {
|
|||||||
// TODO eventually we should be able to factor this out to take place during initialization.
|
// TODO eventually we should be able to factor this out to take place during initialization.
|
||||||
enableSwaggerSupport bool
|
enableSwaggerSupport bool
|
||||||
|
|
||||||
// legacyAPIPrefix is the prefix used for legacy API groups that existed before we had API groups
|
|
||||||
// usuallly /api
|
|
||||||
legacyAPIPrefix string
|
|
||||||
|
|
||||||
// apiPrefix is the prefix where API groups live, usually /apis
|
// apiPrefix is the prefix where API groups live, usually /apis
|
||||||
apiPrefix string
|
apiPrefix string
|
||||||
|
|
||||||
|
// legacyAPIGroupPrefixes is used to set up URL parsing for authorization and for validating requests
|
||||||
|
// to InstallLegacyAPIGroup
|
||||||
|
legacyAPIGroupPrefixes sets.String
|
||||||
|
|
||||||
// admissionControl is used to build the RESTStorage that backs an API Group.
|
// admissionControl is used to build the RESTStorage that backs an API Group.
|
||||||
admissionControl admission.Interface
|
admissionControl admission.Interface
|
||||||
|
|
||||||
@ -294,18 +293,9 @@ func (s *GenericAPIServer) Run() {
|
|||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exposes the given api group in the API.
|
// installAPIResources is a private method for installing the REST storage backing each api groupversionresource
|
||||||
func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
|
func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo) error {
|
||||||
apiPrefix := s.apiPrefix
|
|
||||||
if apiGroupInfo.IsLegacyGroup {
|
|
||||||
apiPrefix = s.legacyAPIPrefix
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install REST handlers for all the versions in this group.
|
|
||||||
apiVersions := []string{}
|
|
||||||
for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions {
|
for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions {
|
||||||
apiVersions = append(apiVersions, groupVersion.Version)
|
|
||||||
|
|
||||||
apiGroupVersion, err := s.getAPIGroupVersion(apiGroupInfo, groupVersion, apiPrefix)
|
apiGroupVersion, err := s.getAPIGroupVersion(apiGroupInfo, groupVersion, apiPrefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -318,51 +308,77 @@ func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
|
|||||||
return fmt.Errorf("Unable to setup API %v: %v", apiGroupInfo, err)
|
return fmt.Errorf("Unable to setup API %v: %v", apiGroupInfo, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Install the version handler.
|
|
||||||
if apiGroupInfo.IsLegacyGroup {
|
|
||||||
// Add a handler at /api to enumerate the supported api versions.
|
|
||||||
apiserver.AddApiWebService(s.Serializer, s.HandlerContainer.Container, apiPrefix, func(req *restful.Request) *unversioned.APIVersions {
|
|
||||||
apiVersionsForDiscovery := unversioned.APIVersions{
|
|
||||||
ServerAddressByClientCIDRs: s.getServerAddressByClientCIDRs(req.Request),
|
|
||||||
Versions: apiVersions,
|
|
||||||
}
|
|
||||||
return &apiVersionsForDiscovery
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// Do not register empty group or empty version. Doing so claims /apis/ for the wrong entity to be returned.
|
|
||||||
// Catching these here places the error much closer to its origin
|
|
||||||
if len(apiGroupInfo.GroupMeta.GroupVersion.Group) == 0 {
|
|
||||||
return fmt.Errorf("cannot register handler with an empty group for %#v", *apiGroupInfo)
|
|
||||||
}
|
|
||||||
if len(apiGroupInfo.GroupMeta.GroupVersion.Version) == 0 {
|
|
||||||
return fmt.Errorf("cannot register handler with an empty version for %#v", *apiGroupInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a handler at /apis/<groupName> to enumerate all versions supported by this group.
|
return nil
|
||||||
apiVersionsForDiscovery := []unversioned.GroupVersionForDiscovery{}
|
}
|
||||||
for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions {
|
|
||||||
// Check the config to make sure that we elide versions that don't have any resources
|
|
||||||
if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
apiVersionsForDiscovery = append(apiVersionsForDiscovery, unversioned.GroupVersionForDiscovery{
|
|
||||||
GroupVersion: groupVersion.String(),
|
|
||||||
Version: groupVersion.Version,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
preferedVersionForDiscovery := unversioned.GroupVersionForDiscovery{
|
|
||||||
GroupVersion: apiGroupInfo.GroupMeta.GroupVersion.String(),
|
|
||||||
Version: apiGroupInfo.GroupMeta.GroupVersion.Version,
|
|
||||||
}
|
|
||||||
apiGroup := unversioned.APIGroup{
|
|
||||||
Name: apiGroupInfo.GroupMeta.GroupVersion.Group,
|
|
||||||
Versions: apiVersionsForDiscovery,
|
|
||||||
PreferredVersion: preferedVersionForDiscovery,
|
|
||||||
}
|
|
||||||
|
|
||||||
s.AddAPIGroupForDiscovery(apiGroup)
|
func (s *GenericAPIServer) InstallLegacyAPIGroup(apiPrefix string, apiGroupInfo *APIGroupInfo) error {
|
||||||
s.HandlerContainer.Add(apiserver.NewGroupWebService(s.Serializer, apiPrefix+"/"+apiGroup.Name, apiGroup))
|
if !s.legacyAPIGroupPrefixes.Has(apiPrefix) {
|
||||||
|
return fmt.Errorf("%q is not in the allowed legacy API prefixes: %v", apiPrefix, s.legacyAPIGroupPrefixes.List())
|
||||||
}
|
}
|
||||||
|
if err := s.installAPIResources(apiPrefix, apiGroupInfo); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup discovery
|
||||||
|
apiVersions := []string{}
|
||||||
|
for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions {
|
||||||
|
apiVersions = append(apiVersions, groupVersion.Version)
|
||||||
|
}
|
||||||
|
// Install the version handler.
|
||||||
|
// Add a handler at /<apiPrefix> to enumerate the supported api versions.
|
||||||
|
apiserver.AddApiWebService(s.Serializer, s.HandlerContainer.Container, apiPrefix, func(req *restful.Request) *unversioned.APIVersions {
|
||||||
|
apiVersionsForDiscovery := unversioned.APIVersions{
|
||||||
|
ServerAddressByClientCIDRs: s.getServerAddressByClientCIDRs(req.Request),
|
||||||
|
Versions: apiVersions,
|
||||||
|
}
|
||||||
|
return &apiVersionsForDiscovery
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exposes the given api group in the API.
|
||||||
|
func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
|
||||||
|
// Do not register empty group or empty version. Doing so claims /apis/ for the wrong entity to be returned.
|
||||||
|
// Catching these here places the error much closer to its origin
|
||||||
|
if len(apiGroupInfo.GroupMeta.GroupVersion.Group) == 0 {
|
||||||
|
return fmt.Errorf("cannot register handler with an empty group for %#v", *apiGroupInfo)
|
||||||
|
}
|
||||||
|
if len(apiGroupInfo.GroupMeta.GroupVersion.Version) == 0 {
|
||||||
|
return fmt.Errorf("cannot register handler with an empty version for %#v", *apiGroupInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.installAPIResources(s.apiPrefix, apiGroupInfo); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup discovery
|
||||||
|
// Install the version handler.
|
||||||
|
// Add a handler at /apis/<groupName> to enumerate all versions supported by this group.
|
||||||
|
apiVersionsForDiscovery := []unversioned.GroupVersionForDiscovery{}
|
||||||
|
for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions {
|
||||||
|
// Check the config to make sure that we elide versions that don't have any resources
|
||||||
|
if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
apiVersionsForDiscovery = append(apiVersionsForDiscovery, unversioned.GroupVersionForDiscovery{
|
||||||
|
GroupVersion: groupVersion.String(),
|
||||||
|
Version: groupVersion.Version,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
preferedVersionForDiscovery := unversioned.GroupVersionForDiscovery{
|
||||||
|
GroupVersion: apiGroupInfo.GroupMeta.GroupVersion.String(),
|
||||||
|
Version: apiGroupInfo.GroupMeta.GroupVersion.Version,
|
||||||
|
}
|
||||||
|
apiGroup := unversioned.APIGroup{
|
||||||
|
Name: apiGroupInfo.GroupMeta.GroupVersion.Group,
|
||||||
|
Versions: apiVersionsForDiscovery,
|
||||||
|
PreferredVersion: preferedVersionForDiscovery,
|
||||||
|
}
|
||||||
|
|
||||||
|
s.AddAPIGroupForDiscovery(apiGroup)
|
||||||
|
s.HandlerContainer.Add(apiserver.NewGroupWebService(s.Serializer, s.apiPrefix+"/"+apiGroup.Name, apiGroup))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ import (
|
|||||||
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||||
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
||||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@ -55,7 +56,7 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
|
|||||||
config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil }
|
config.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil }
|
||||||
config.ProxyTLSClientConfig = &tls.Config{}
|
config.ProxyTLSClientConfig = &tls.Config{}
|
||||||
config.Serializer = api.Codecs
|
config.Serializer = api.Codecs
|
||||||
config.APIPrefix = "/api"
|
config.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||||
config.APIGroupPrefix = "/apis"
|
config.APIGroupPrefix = "/apis"
|
||||||
|
|
||||||
return etcdServer, config, assert.New(t)
|
return etcdServer, config, assert.New(t)
|
||||||
@ -79,7 +80,7 @@ func TestNew(t *testing.T) {
|
|||||||
|
|
||||||
// Verify many of the variables match their config counterparts
|
// Verify many of the variables match their config counterparts
|
||||||
assert.Equal(s.enableSwaggerSupport, config.EnableSwaggerSupport)
|
assert.Equal(s.enableSwaggerSupport, config.EnableSwaggerSupport)
|
||||||
assert.Equal(s.legacyAPIPrefix, config.APIPrefix)
|
assert.Equal(s.legacyAPIGroupPrefixes, config.LegacyAPIGroupPrefixes)
|
||||||
assert.Equal(s.apiPrefix, config.APIGroupPrefix)
|
assert.Equal(s.apiPrefix, config.APIGroupPrefix)
|
||||||
assert.Equal(s.admissionControl, config.AdmissionControl)
|
assert.Equal(s.admissionControl, config.AdmissionControl)
|
||||||
assert.Equal(s.RequestContextMapper(), config.RequestContextMapper)
|
assert.Equal(s.RequestContextMapper(), config.RequestContextMapper)
|
||||||
@ -105,7 +106,7 @@ func TestInstallAPIGroups(t *testing.T) {
|
|||||||
etcdserver, config, assert := setUp(t)
|
etcdserver, config, assert := setUp(t)
|
||||||
defer etcdserver.Terminate(t)
|
defer etcdserver.Terminate(t)
|
||||||
|
|
||||||
config.APIPrefix = "/apiPrefix"
|
config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix")
|
||||||
config.APIGroupPrefix = "/apiGroupPrefix"
|
config.APIGroupPrefix = "/apiGroupPrefix"
|
||||||
|
|
||||||
s, err := config.Complete().New()
|
s, err := config.Complete().New()
|
||||||
@ -115,15 +116,15 @@ func TestInstallAPIGroups(t *testing.T) {
|
|||||||
|
|
||||||
apiGroupMeta := registered.GroupOrDie(api.GroupName)
|
apiGroupMeta := registered.GroupOrDie(api.GroupName)
|
||||||
extensionsGroupMeta := registered.GroupOrDie(extensions.GroupName)
|
extensionsGroupMeta := registered.GroupOrDie(extensions.GroupName)
|
||||||
|
s.InstallLegacyAPIGroup("/apiPrefix", &APIGroupInfo{
|
||||||
|
// legacy group version
|
||||||
|
GroupMeta: *apiGroupMeta,
|
||||||
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
|
||||||
|
ParameterCodec: api.ParameterCodec,
|
||||||
|
NegotiatedSerializer: api.Codecs,
|
||||||
|
})
|
||||||
|
|
||||||
apiGroupsInfo := []APIGroupInfo{
|
apiGroupsInfo := []APIGroupInfo{
|
||||||
{
|
|
||||||
// legacy group version
|
|
||||||
GroupMeta: *apiGroupMeta,
|
|
||||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
|
|
||||||
IsLegacyGroup: true,
|
|
||||||
ParameterCodec: api.ParameterCodec,
|
|
||||||
NegotiatedSerializer: api.Codecs,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
// extensions group version
|
// extensions group version
|
||||||
GroupMeta: *extensionsGroupMeta,
|
GroupMeta: *extensionsGroupMeta,
|
||||||
@ -141,9 +142,9 @@ func TestInstallAPIGroups(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
validPaths := []string{
|
validPaths := []string{
|
||||||
// "/api"
|
// "/api"
|
||||||
config.APIPrefix,
|
config.LegacyAPIGroupPrefixes.List()[0],
|
||||||
// "/api/v1"
|
// "/api/v1"
|
||||||
config.APIPrefix + "/" + apiGroupMeta.GroupVersion.Version,
|
config.LegacyAPIGroupPrefixes.List()[0] + "/" + apiGroupMeta.GroupVersion.Version,
|
||||||
// "/apis/extensions"
|
// "/apis/extensions"
|
||||||
config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.Group,
|
config.APIGroupPrefix + "/" + extensionsGroupMeta.GroupVersion.Group,
|
||||||
// "/apis/extensions/v1beta1"
|
// "/apis/extensions/v1beta1"
|
||||||
@ -224,7 +225,7 @@ func TestNotRestRoutesHaveAuth(t *testing.T) {
|
|||||||
|
|
||||||
authz := mockAuthorizer{}
|
authz := mockAuthorizer{}
|
||||||
|
|
||||||
config.APIPrefix = "/apiPrefix"
|
config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix")
|
||||||
config.APIGroupPrefix = "/apiGroupPrefix"
|
config.APIGroupPrefix = "/apiGroupPrefix"
|
||||||
config.Authorizer = &authz
|
config.Authorizer = &authz
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ var AuthorizationModeChoices = []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABA
|
|||||||
// ServerRunOptions contains the options while running a generic api server.
|
// ServerRunOptions contains the options while running a generic api server.
|
||||||
type ServerRunOptions struct {
|
type ServerRunOptions struct {
|
||||||
APIGroupPrefix string
|
APIGroupPrefix string
|
||||||
APIPrefix string
|
|
||||||
AdmissionControl string
|
AdmissionControl string
|
||||||
AdmissionControlConfigFile string
|
AdmissionControlConfigFile string
|
||||||
AdvertiseAddress net.IP
|
AdvertiseAddress net.IP
|
||||||
@ -125,7 +124,6 @@ type ServerRunOptions struct {
|
|||||||
func NewServerRunOptions() *ServerRunOptions {
|
func NewServerRunOptions() *ServerRunOptions {
|
||||||
return &ServerRunOptions{
|
return &ServerRunOptions{
|
||||||
APIGroupPrefix: "/apis",
|
APIGroupPrefix: "/apis",
|
||||||
APIPrefix: "/api",
|
|
||||||
AdmissionControl: "AlwaysAdmit",
|
AdmissionControl: "AlwaysAdmit",
|
||||||
AnonymousAuth: true,
|
AnonymousAuth: true,
|
||||||
AuthorizationMode: "AlwaysAllow",
|
AuthorizationMode: "AlwaysAllow",
|
||||||
|
@ -135,8 +135,6 @@ type Master struct {
|
|||||||
|
|
||||||
// nodeClient is used to back the tunneler
|
// nodeClient is used to back the tunneler
|
||||||
nodeClient coreclient.NodeInterface
|
nodeClient coreclient.NodeInterface
|
||||||
|
|
||||||
restOptionsFactory restOptionsFactory
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// thirdPartyEntry combines objects storage and API group into one struct
|
// thirdPartyEntry combines objects storage and API group into one struct
|
||||||
@ -209,31 +207,33 @@ func (c completedConfig) New() (*Master, error) {
|
|||||||
nodeClient: coreclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig).Nodes(),
|
nodeClient: coreclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig).Nodes(),
|
||||||
|
|
||||||
disableThirdPartyControllerForTesting: c.disableThirdPartyControllerForTesting,
|
disableThirdPartyControllerForTesting: c.disableThirdPartyControllerForTesting,
|
||||||
|
}
|
||||||
|
|
||||||
restOptionsFactory: restOptionsFactory{
|
restOptionsFactory := restOptionsFactory{
|
||||||
deleteCollectionWorkers: c.DeleteCollectionWorkers,
|
deleteCollectionWorkers: c.DeleteCollectionWorkers,
|
||||||
enableGarbageCollection: c.GenericConfig.EnableGarbageCollection,
|
enableGarbageCollection: c.GenericConfig.EnableGarbageCollection,
|
||||||
storageFactory: c.StorageFactory,
|
storageFactory: c.StorageFactory,
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.EnableWatchCache {
|
if c.EnableWatchCache {
|
||||||
m.restOptionsFactory.storageDecorator = registry.StorageWithCacher
|
restOptionsFactory.storageDecorator = registry.StorageWithCacher
|
||||||
} else {
|
} else {
|
||||||
m.restOptionsFactory.storageDecorator = generic.UndecoratedStorage
|
restOptionsFactory.storageDecorator = generic.UndecoratedStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
// install legacy rest storage
|
// install legacy rest storage
|
||||||
// because of other hacks, this always has to come first
|
if c.GenericConfig.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) {
|
||||||
legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{
|
legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{
|
||||||
StorageFactory: c.StorageFactory,
|
StorageFactory: c.StorageFactory,
|
||||||
ProxyTransport: s.ProxyTransport,
|
ProxyTransport: s.ProxyTransport,
|
||||||
KubeletClient: c.KubeletClient,
|
KubeletClient: c.KubeletClient,
|
||||||
EventTTL: c.EventTTL,
|
EventTTL: c.EventTTL,
|
||||||
ServiceClusterIPRange: c.GenericConfig.ServiceClusterIPRange,
|
ServiceClusterIPRange: c.GenericConfig.ServiceClusterIPRange,
|
||||||
ServiceNodePortRange: c.GenericConfig.ServiceNodePortRange,
|
ServiceNodePortRange: c.GenericConfig.ServiceNodePortRange,
|
||||||
ComponentStatusServerFunc: func() map[string]apiserver.Server { return getServersToValidate(c.StorageFactory) },
|
ComponentStatusServerFunc: func() map[string]apiserver.Server { return getServersToValidate(c.StorageFactory) },
|
||||||
LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
|
LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
|
||||||
|
}
|
||||||
|
m.InstallLegacyAPI(c.Config, restOptionsFactory.NewFor, legacyRESTStorageProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add some hardcoded storage for now. Append to the map.
|
// Add some hardcoded storage for now. Append to the map.
|
||||||
@ -253,13 +253,31 @@ func (c completedConfig) New() (*Master, error) {
|
|||||||
c.RESTStorageProviders[policy.GroupName] = policyrest.RESTStorageProvider{}
|
c.RESTStorageProviders[policy.GroupName] = policyrest.RESTStorageProvider{}
|
||||||
c.RESTStorageProviders[rbac.GroupName] = &rbacrest.RESTStorageProvider{AuthorizerRBACSuperUser: c.GenericConfig.AuthorizerRBACSuperUser}
|
c.RESTStorageProviders[rbac.GroupName] = &rbacrest.RESTStorageProvider{AuthorizerRBACSuperUser: c.GenericConfig.AuthorizerRBACSuperUser}
|
||||||
c.RESTStorageProviders[storage.GroupName] = storagerest.RESTStorageProvider{}
|
c.RESTStorageProviders[storage.GroupName] = storagerest.RESTStorageProvider{}
|
||||||
m.InstallAPIs(c.Config, legacyRESTStorageProvider)
|
m.InstallAPIs(c.Config, restOptionsFactory.NewFor)
|
||||||
|
|
||||||
m.InstallGeneralEndpoints(c.Config)
|
m.InstallGeneralEndpoints(c.Config)
|
||||||
|
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Master) InstallLegacyAPI(c *Config, restOptionsGetter genericapiserver.RESTOptionsGetter, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) {
|
||||||
|
legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter)
|
||||||
|
if err != nil {
|
||||||
|
glog.Fatalf("Error building core storage: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.EnableCoreControllers {
|
||||||
|
bootstrapController := c.NewBootstrapController(legacyRESTStorage)
|
||||||
|
if err := m.GenericAPIServer.AddPostStartHook("bootstrap-controller", bootstrapController.PostStartHook); err != nil {
|
||||||
|
glog.Fatalf("Error registering PostStartHook %q: %v", "bootstrap-controller", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.LegacyAPIPrefix, &apiGroupInfo); err != nil {
|
||||||
|
glog.Fatalf("Error in registering group versions: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO this needs to be refactored so we have a way to add general health checks to genericapiserver
|
// TODO this needs to be refactored so we have a way to add general health checks to genericapiserver
|
||||||
// TODO profiling should be generic
|
// TODO profiling should be generic
|
||||||
func (m *Master) InstallGeneralEndpoints(c *Config) {
|
func (m *Master) InstallGeneralEndpoints(c *Config) {
|
||||||
@ -283,30 +301,9 @@ func (m *Master) InstallGeneralEndpoints(c *Config) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Master) InstallAPIs(c *Config, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) {
|
func (m *Master) InstallAPIs(c *Config, restOptionsGetter genericapiserver.RESTOptionsGetter) {
|
||||||
restOptionsGetter := func(resource unversioned.GroupResource) generic.RESTOptions {
|
|
||||||
return m.restOptionsFactory.NewFor(resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
apiGroupsInfo := []genericapiserver.APIGroupInfo{}
|
apiGroupsInfo := []genericapiserver.APIGroupInfo{}
|
||||||
|
|
||||||
// Install v1 unless disabled.
|
|
||||||
if c.GenericConfig.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) {
|
|
||||||
legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter)
|
|
||||||
if err != nil {
|
|
||||||
glog.Fatalf("Error building core storage: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.EnableCoreControllers {
|
|
||||||
bootstrapController := c.NewBootstrapController(legacyRESTStorage)
|
|
||||||
if err := m.GenericAPIServer.AddPostStartHook("bootstrap-controller", bootstrapController.PostStartHook); err != nil {
|
|
||||||
glog.Fatalf("Error registering PostStartHook %q: %v", "bootstrap-controller", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install third party resource support if requested
|
// Install third party resource support if requested
|
||||||
// TODO seems like this bit ought to be unconditional and the REST API is controlled by the config
|
// TODO seems like this bit ought to be unconditional and the REST API is controlled by the config
|
||||||
if c.GenericConfig.APIResourceConfigSource.ResourceEnabled(extensionsapiv1beta1.SchemeGroupVersion.WithResource("thirdpartyresources")) {
|
if c.GenericConfig.APIResourceConfigSource.ResourceEnabled(extensionsapiv1beta1.SchemeGroupVersion.WithResource("thirdpartyresources")) {
|
||||||
|
@ -92,7 +92,7 @@ func setUp(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.
|
|||||||
config.GenericConfig.PublicAddress = net.ParseIP("192.168.10.4")
|
config.GenericConfig.PublicAddress = net.ParseIP("192.168.10.4")
|
||||||
config.GenericConfig.Serializer = api.Codecs
|
config.GenericConfig.Serializer = api.Codecs
|
||||||
config.KubeletClient = client.FakeKubeletClient{}
|
config.KubeletClient = client.FakeKubeletClient{}
|
||||||
config.GenericConfig.APIPrefix = "/api"
|
config.GenericConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||||
config.GenericConfig.APIGroupPrefix = "/apis"
|
config.GenericConfig.APIGroupPrefix = "/apis"
|
||||||
config.GenericConfig.APIResourceConfigSource = DefaultAPIResourceConfigSource()
|
config.GenericConfig.APIResourceConfigSource = DefaultAPIResourceConfigSource()
|
||||||
config.GenericConfig.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil }
|
config.GenericConfig.ProxyDialer = func(network, addr string) (net.Conn, error) { return nil, nil }
|
||||||
|
@ -96,11 +96,10 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter generi
|
|||||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||||
GroupMeta: *registered.GroupOrDie(api.GroupName),
|
GroupMeta: *registered.GroupOrDie(api.GroupName),
|
||||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
|
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
|
||||||
IsLegacyGroup: true,
|
Scheme: api.Scheme,
|
||||||
Scheme: api.Scheme,
|
ParameterCodec: api.ParameterCodec,
|
||||||
ParameterCodec: api.ParameterCodec,
|
NegotiatedSerializer: api.Codecs,
|
||||||
NegotiatedSerializer: api.Codecs,
|
SubresourceGroupVersionKind: map[string]unversioned.GroupVersionKind{},
|
||||||
SubresourceGroupVersionKind: map[string]unversioned.GroupVersionKind{},
|
|
||||||
}
|
}
|
||||||
if autoscalingGroupVersion := (unversioned.GroupVersion{Group: "autoscaling", Version: "v1"}); registered.IsEnabledVersion(autoscalingGroupVersion) {
|
if autoscalingGroupVersion := (unversioned.GroupVersion{Group: "autoscaling", Version: "v1"}); registered.IsEnabledVersion(autoscalingGroupVersion) {
|
||||||
apiGroupInfo.SubresourceGroupVersionKind["replicationcontrollers/scale"] = autoscalingGroupVersion.WithKind("Scale")
|
apiGroupInfo.SubresourceGroupVersionKind["replicationcontrollers/scale"] = autoscalingGroupVersion.WithKind("Scale")
|
||||||
|
@ -61,6 +61,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/storage/storagebackend"
|
"k8s.io/kubernetes/pkg/storage/storagebackend"
|
||||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
"k8s.io/kubernetes/pkg/watch"
|
"k8s.io/kubernetes/pkg/watch"
|
||||||
"k8s.io/kubernetes/plugin/pkg/admission/admit"
|
"k8s.io/kubernetes/plugin/pkg/admission/admit"
|
||||||
@ -348,7 +349,7 @@ func NewMasterConfig() *master.Config {
|
|||||||
return &master.Config{
|
return &master.Config{
|
||||||
GenericConfig: &genericapiserver.Config{
|
GenericConfig: &genericapiserver.Config{
|
||||||
APIResourceConfigSource: master.DefaultAPIResourceConfigSource(),
|
APIResourceConfigSource: master.DefaultAPIResourceConfigSource(),
|
||||||
APIPrefix: "/api",
|
LegacyAPIGroupPrefixes: sets.NewString("/api"),
|
||||||
APIGroupPrefix: "/apis",
|
APIGroupPrefix: "/apis",
|
||||||
Authorizer: authorizer.NewAlwaysAllowAuthorizer(),
|
Authorizer: authorizer.NewAlwaysAllowAuthorizer(),
|
||||||
AdmissionControl: admit.NewAlwaysAdmit(),
|
AdmissionControl: admit.NewAlwaysAdmit(),
|
||||||
|
Loading…
Reference in New Issue
Block a user