Commit d10743d9 authored by Darren Shepherd's avatar Darren Shepherd

Add custom listpath to disable aggregation

parent 056129ec
......@@ -157,6 +157,8 @@ func CreateServerChain(runOptions *options.ServerRunOptions, stopCh <-chan struc
return nil, nil, err
}
apiExtensionsServer.GenericAPIServer.DiscoveryGroupManager = kubeAPIServer.GenericAPIServer.DiscoveryGroupManager
// This will wire up openapi for extension api server
apiExtensionsServer.GenericAPIServer.PrepareRun()
......@@ -438,7 +440,6 @@ func BuildGenericConfig(
if err != nil {
lastErr = fmt.Errorf("failed to initialize admission: %v", err)
}
return
}
......
......@@ -180,6 +180,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
delegate: delegateHandler,
}
crdHandler := NewCustomResourceDefinitionHandler(
s.GenericAPIServer,
versionDiscoveryHandler,
groupDiscoveryHandler,
s.GenericAPIServer.RequestContextMapper(),
......
......@@ -25,6 +25,8 @@ import (
"sync/atomic"
"time"
"k8s.io/apiserver/pkg/server"
"github.com/golang/glog"
apiequality "k8s.io/apimachinery/pkg/api/equality"
......@@ -81,6 +83,9 @@ type crdHandler struct {
delegate http.Handler
restOptionsGetter generic.RESTOptionsGetter
admission admission.Interface
genericAPIServer *server.GenericAPIServer
addRoot sync.Once
}
// crdInfo stores enough information to serve the storage for the custom resource
......@@ -101,6 +106,7 @@ type crdInfo struct {
type crdStorageMap map[types.UID]*crdInfo
func NewCustomResourceDefinitionHandler(
genericAPIServer *server.GenericAPIServer,
versionDiscoveryHandler *versionDiscoveryHandler,
groupDiscoveryHandler *groupDiscoveryHandler,
requestContextMapper apirequest.RequestContextMapper,
......@@ -109,6 +115,7 @@ func NewCustomResourceDefinitionHandler(
restOptionsGetter generic.RESTOptionsGetter,
admission admission.Interface) *crdHandler {
ret := &crdHandler{
genericAPIServer: genericAPIServer,
versionDiscoveryHandler: versionDiscoveryHandler,
groupDiscoveryHandler: groupDiscoveryHandler,
customStorage: atomic.Value{},
......@@ -120,14 +127,27 @@ func NewCustomResourceDefinitionHandler(
}
crdInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
UpdateFunc: ret.updateCustomResourceDefinition,
AddFunc: func(obj interface{}) {
ret.updateAPI(obj, false)
},
UpdateFunc: func(oldObj, newObj interface{}) {
ret.updateCustomResourceDefinition(oldObj, newObj)
ret.updateAPI(newObj, false)
},
DeleteFunc: func(obj interface{}) {
ret.updateAPI(obj, true)
ret.removeDeadStorage()
},
})
ret.customStorage.Store(crdStorageMap{})
go func() {
// pretty hacky, but this will install the CRD api group if no CRDs exist
time.Sleep(5 * time.Second)
ret.updateAPI(nil, false)
}()
return ret
}
......@@ -285,6 +305,44 @@ func (r *crdHandler) serveScale(w http.ResponseWriter, req *http.Request, reques
}
}
func (r *crdHandler) updateAPI(obj interface{}, del bool) {
if r.genericAPIServer.DiscoveryGroupManager == nil {
return
}
r.addRoot.Do(func() {
ver := metav1.GroupVersionForDiscovery{
Version: "v1beta1",
GroupVersion: fmt.Sprintf("apiextensions.k8s.io/v1beta1"),
}
r.genericAPIServer.DiscoveryGroupManager.AddGroup(metav1.APIGroup{
Name: "apiextensions.k8s.io",
Versions: []metav1.GroupVersionForDiscovery{ver},
PreferredVersion: ver,
})
})
newCRD, ok := obj.(*apiextensions.CustomResourceDefinition)
if !ok {
return
}
if del {
r.genericAPIServer.DiscoveryGroupManager.RemoveGroup(newCRD.Spec.Group)
return
}
ver := metav1.GroupVersionForDiscovery{
Version: newCRD.Spec.Version,
GroupVersion: fmt.Sprintf("%s/%s", newCRD.Spec.Group, newCRD.Spec.Version),
}
r.genericAPIServer.DiscoveryGroupManager.AddGroup(metav1.APIGroup{
Name: newCRD.Spec.Group,
Versions: []metav1.GroupVersionForDiscovery{ver},
PreferredVersion: ver,
})
}
func (r *crdHandler) updateCustomResourceDefinition(oldObj, newObj interface{}) {
oldCRD := oldObj.(*apiextensions.CustomResourceDefinition)
newCRD := newObj.(*apiextensions.CustomResourceDefinition)
......
......@@ -19,8 +19,11 @@ package discovery
import (
"errors"
"net/http"
"strings"
"sync"
"k8s.io/apiserver/pkg/server/routes"
restful "github.com/emicklei/go-restful"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
......@@ -35,6 +38,8 @@ import (
// GroupManager is an interface that allows dynamic mutation of the existing webservice to handle
// API groups being added or removed.
type GroupManager interface {
routes.ListedPathProvider
AddGroup(apiGroup metav1.APIGroup)
RemoveGroup(groupName string)
......@@ -73,6 +78,22 @@ func NewRootAPIsHandler(addresses Addresses, serializer runtime.NegotiatedSerial
}
}
func (s *rootAPIsHandler) ListedPaths() []string {
s.lock.RLock()
defer s.lock.RUnlock()
var result []string
for name, group := range s.apiGroups {
if strings.Contains(name, ".") {
for _, ver := range group.Versions {
result = append(result, "/apis/"+ver.GroupVersion)
}
}
}
return result
}
func (s *rootAPIsHandler) AddGroup(apiGroup metav1.APIGroup) {
s.lock.Lock()
defer s.lock.Unlock()
......
......@@ -432,7 +432,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
s.healthzChecks = append(s.healthzChecks, delegateCheck)
}
s.listedPathProvider = routes.ListedPathProviders{s.listedPathProvider, delegationTarget}
s.listedPathProvider = routes.ListedPathProviders{s.listedPathProvider, delegationTarget, s.DiscoveryGroupManager}
installAPI(s, c.Config)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment