Merge pull request #84277 from liggitt/beta-aggregator-discovery

Do not list apiextensions.k8s.io/v1beta1 in discovery when disabled
This commit is contained in:
Kubernetes Prow Robot 2019-10-24 11:56:44 -07:00 committed by GitHub
commit 02ee2421f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 25 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package apiserver package apiserver
import ( import (
"fmt"
"net/http" "net/http"
"time" "time"
@ -190,9 +191,18 @@ func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.Deleg
return nil, err return nil, err
} }
enabledVersions := sets.NewString()
for v := range apiGroupInfo.VersionedResourcesStorageMap {
enabledVersions.Insert(v)
}
if !enabledVersions.Has(v1.SchemeGroupVersion.Version) {
return nil, fmt.Errorf("API group/version %s must be enabled", v1.SchemeGroupVersion.String())
}
apisHandler := &apisHandler{ apisHandler := &apisHandler{
codecs: aggregatorscheme.Codecs, codecs: aggregatorscheme.Codecs,
lister: s.lister, lister: s.lister,
discoveryGroup: discoveryGroup(enabledVersions),
} }
s.GenericAPIServer.Handler.NonGoRestfulMux.Handle("/apis", apisHandler) s.GenericAPIServer.Handler.NonGoRestfulMux.Handle("/apis", apisHandler)
s.GenericAPIServer.Handler.NonGoRestfulMux.UnlistedHandle("/apis/", apisHandler) s.GenericAPIServer.Handler.NonGoRestfulMux.UnlistedHandle("/apis/", apisHandler)

View File

@ -24,6 +24,7 @@ import (
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
@ -36,33 +37,41 @@ import (
// apisHandler serves the `/apis` endpoint. // apisHandler serves the `/apis` endpoint.
// This is registered as a filter so that it never collides with any explicitly registered endpoints // This is registered as a filter so that it never collides with any explicitly registered endpoints
type apisHandler struct { type apisHandler struct {
codecs serializer.CodecFactory codecs serializer.CodecFactory
lister listers.APIServiceLister lister listers.APIServiceLister
discoveryGroup metav1.APIGroup
} }
var discoveryGroup = metav1.APIGroup{ func discoveryGroup(enabledVersions sets.String) metav1.APIGroup {
Name: apiregistrationv1api.GroupName, retval := metav1.APIGroup{
Versions: []metav1.GroupVersionForDiscovery{ Name: apiregistrationv1api.GroupName,
{ Versions: []metav1.GroupVersionForDiscovery{
{
GroupVersion: apiregistrationv1api.SchemeGroupVersion.String(),
Version: apiregistrationv1api.SchemeGroupVersion.Version,
},
},
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: apiregistrationv1api.SchemeGroupVersion.String(), GroupVersion: apiregistrationv1api.SchemeGroupVersion.String(),
Version: apiregistrationv1api.SchemeGroupVersion.Version, Version: apiregistrationv1api.SchemeGroupVersion.Version,
}, },
{ }
if enabledVersions.Has(apiregistrationv1beta1api.SchemeGroupVersion.Version) {
retval.Versions = append(retval.Versions, metav1.GroupVersionForDiscovery{
GroupVersion: apiregistrationv1beta1api.SchemeGroupVersion.String(), GroupVersion: apiregistrationv1beta1api.SchemeGroupVersion.String(),
Version: apiregistrationv1beta1api.SchemeGroupVersion.Version, Version: apiregistrationv1beta1api.SchemeGroupVersion.Version,
}, })
}, }
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: apiregistrationv1api.SchemeGroupVersion.String(), return retval
Version: apiregistrationv1api.SchemeGroupVersion.Version,
},
} }
func (r *apisHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { func (r *apisHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
discoveryGroupList := &metav1.APIGroupList{ discoveryGroupList := &metav1.APIGroupList{
// always add OUR api group to the list first. Since we'll never have a registered APIService for it // always add OUR api group to the list first. Since we'll never have a registered APIService for it
// and since this is the crux of the API, having this first will give our names priority. It's good to be king. // and since this is the crux of the API, having this first will give our names priority. It's good to be king.
Groups: []metav1.APIGroup{discoveryGroup}, Groups: []metav1.APIGroup{r.discoveryGroup},
} }
apiServices, err := r.lister.List(labels.Everything()) apiServices, err := r.lister.List(labels.Everything())

View File

@ -27,6 +27,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
apiregistration "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" apiregistration "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
@ -37,21 +38,35 @@ import (
func TestAPIs(t *testing.T) { func TestAPIs(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
enabled sets.String
apiservices []*apiregistration.APIService apiservices []*apiregistration.APIService
expected *metav1.APIGroupList expected *metav1.APIGroupList
}{ }{
{ {
name: "empty", name: "empty",
enabled: sets.NewString("v1", "v1beta1"),
apiservices: []*apiregistration.APIService{}, apiservices: []*apiregistration.APIService{},
expected: &metav1.APIGroupList{ expected: &metav1.APIGroupList{
TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"}, TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"},
Groups: []metav1.APIGroup{ Groups: []metav1.APIGroup{
discoveryGroup, discoveryGroup(sets.NewString("v1", "v1beta1")),
}, },
}, },
}, },
{ {
name: "simple add", name: "v1 only",
enabled: sets.NewString("v1"),
apiservices: []*apiregistration.APIService{},
expected: &metav1.APIGroupList{
TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"},
Groups: []metav1.APIGroup{
discoveryGroup(sets.NewString("v1")),
},
},
},
{
name: "simple add",
enabled: sets.NewString("v1", "v1beta1"),
apiservices: []*apiregistration.APIService{ apiservices: []*apiregistration.APIService{
{ {
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"}, ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
@ -91,7 +106,7 @@ func TestAPIs(t *testing.T) {
expected: &metav1.APIGroupList{ expected: &metav1.APIGroupList{
TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"}, TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"},
Groups: []metav1.APIGroup{ Groups: []metav1.APIGroup{
discoveryGroup, discoveryGroup(sets.NewString("v1", "v1beta1")),
{ {
Name: "foo", Name: "foo",
Versions: []metav1.GroupVersionForDiscovery{ Versions: []metav1.GroupVersionForDiscovery{
@ -122,7 +137,8 @@ func TestAPIs(t *testing.T) {
}, },
}, },
{ {
name: "sorting", name: "sorting",
enabled: sets.NewString("v1", "v1beta1"),
apiservices: []*apiregistration.APIService{ apiservices: []*apiregistration.APIService{
{ {
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"}, ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
@ -198,7 +214,7 @@ func TestAPIs(t *testing.T) {
expected: &metav1.APIGroupList{ expected: &metav1.APIGroupList{
TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"}, TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"},
Groups: []metav1.APIGroup{ Groups: []metav1.APIGroup{
discoveryGroup, discoveryGroup(sets.NewString("v1", "v1beta1")),
{ {
Name: "foo", Name: "foo",
Versions: []metav1.GroupVersionForDiscovery{ Versions: []metav1.GroupVersionForDiscovery{
@ -237,7 +253,8 @@ func TestAPIs(t *testing.T) {
}, },
}, },
{ {
name: "unavailable service", name: "unavailable service",
enabled: sets.NewString("v1", "v1beta1"),
apiservices: []*apiregistration.APIService{ apiservices: []*apiregistration.APIService{
{ {
ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"}, ObjectMeta: metav1.ObjectMeta{Name: "v1.foo"},
@ -260,7 +277,7 @@ func TestAPIs(t *testing.T) {
expected: &metav1.APIGroupList{ expected: &metav1.APIGroupList{
TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"}, TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"},
Groups: []metav1.APIGroup{ Groups: []metav1.APIGroup{
discoveryGroup, discoveryGroup(sets.NewString("v1", "v1beta1")),
{ {
Name: "foo", Name: "foo",
Versions: []metav1.GroupVersionForDiscovery{ Versions: []metav1.GroupVersionForDiscovery{
@ -282,8 +299,9 @@ func TestAPIs(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
handler := &apisHandler{ handler := &apisHandler{
codecs: aggregatorscheme.Codecs, codecs: aggregatorscheme.Codecs,
lister: listers.NewAPIServiceLister(indexer), lister: listers.NewAPIServiceLister(indexer),
discoveryGroup: discoveryGroup(tc.enabled),
} }
for _, o := range tc.apiservices { for _, o := range tc.apiservices {
indexer.Add(o) indexer.Add(o)