mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 02:34:03 +00:00
Merge pull request #18484 from brendandburns/3rdparty5
Auto commit by PR queue bot
This commit is contained in:
commit
44fc4d3f34
@ -254,8 +254,8 @@ func AddApiWebService(container *restful.Container, apiPrefix string, versions [
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adds a service to return the supported api versions at /apis.
|
// Adds a service to return the supported api versions at /apis.
|
||||||
func AddApisWebService(container *restful.Container, apiPrefix string, groups []unversioned.APIGroup) {
|
func AddApisWebService(container *restful.Container, apiPrefix string, f func() []unversioned.APIGroup) {
|
||||||
rootAPIHandler := RootAPIHandler(groups)
|
rootAPIHandler := RootAPIHandler(f)
|
||||||
ws := new(restful.WebService)
|
ws := new(restful.WebService)
|
||||||
ws.Path(apiPrefix)
|
ws.Path(apiPrefix)
|
||||||
ws.Doc("get available API versions")
|
ws.Doc("get available API versions")
|
||||||
@ -308,10 +308,10 @@ func APIVersionHandler(versions ...string) restful.RouteFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RootAPIHandler returns a handler which will list the provided groups and versions as available.
|
// RootAPIHandler returns a handler which will list the provided groups and versions as available.
|
||||||
func RootAPIHandler(groups []unversioned.APIGroup) restful.RouteFunction {
|
func RootAPIHandler(f func() []unversioned.APIGroup) restful.RouteFunction {
|
||||||
return func(req *restful.Request, resp *restful.Response) {
|
return func(req *restful.Request, resp *restful.Response) {
|
||||||
// TODO: use restful's Response methods
|
// TODO: use restful's Response methods
|
||||||
writeJSON(http.StatusOK, api.Codec, &unversioned.APIGroupList{Groups: groups}, resp.ResponseWriter, true)
|
writeJSON(http.StatusOK, api.Codec, &unversioned.APIGroupList{Groups: f()}, resp.ResponseWriter, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,8 +111,8 @@ type Master struct {
|
|||||||
|
|
||||||
// storage for third party objects
|
// storage for third party objects
|
||||||
thirdPartyStorage storage.Interface
|
thirdPartyStorage storage.Interface
|
||||||
// map from api path to storage for those objects
|
// map from api path to a tuple of (storage for the objects, APIGroup)
|
||||||
thirdPartyResources map[string]*thirdpartyresourcedataetcd.REST
|
thirdPartyResources map[string]thirdPartyEntry
|
||||||
// protects the map
|
// protects the map
|
||||||
thirdPartyResourcesLock sync.RWMutex
|
thirdPartyResourcesLock sync.RWMutex
|
||||||
|
|
||||||
@ -120,6 +120,13 @@ type Master struct {
|
|||||||
tunneler Tunneler
|
tunneler Tunneler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// thirdPartyEntry combines objects storage and API group into one struct
|
||||||
|
// for easy lookup.
|
||||||
|
type thirdPartyEntry struct {
|
||||||
|
storage *thirdpartyresourcedataetcd.REST
|
||||||
|
group unversioned.APIGroup
|
||||||
|
}
|
||||||
|
|
||||||
// New returns a new instance of Master from the given config.
|
// New returns a new instance of Master from the given config.
|
||||||
// Certain config fields will be set to a default value if unset.
|
// Certain config fields will be set to a default value if unset.
|
||||||
// Certain config fields must be specified, including:
|
// Certain config fields must be specified, including:
|
||||||
@ -184,7 +191,7 @@ func (m *Master) InstallAPIs(c *Config) {
|
|||||||
// Install extensions unless disabled.
|
// Install extensions unless disabled.
|
||||||
if !m.ApiGroupVersionOverrides["extensions/v1beta1"].Disable {
|
if !m.ApiGroupVersionOverrides["extensions/v1beta1"].Disable {
|
||||||
m.thirdPartyStorage = c.StorageDestinations.APIGroups[extensions.GroupName].Default
|
m.thirdPartyStorage = c.StorageDestinations.APIGroups[extensions.GroupName].Default
|
||||||
m.thirdPartyResources = map[string]*thirdpartyresourcedataetcd.REST{}
|
m.thirdPartyResources = map[string]thirdPartyEntry{}
|
||||||
|
|
||||||
expVersion := m.experimental(c)
|
expVersion := m.experimental(c)
|
||||||
|
|
||||||
@ -217,7 +224,20 @@ func (m *Master) InstallAPIs(c *Config) {
|
|||||||
|
|
||||||
// This should be done after all groups are registered
|
// This should be done after all groups are registered
|
||||||
// TODO: replace the hardcoded "apis".
|
// TODO: replace the hardcoded "apis".
|
||||||
apiserver.AddApisWebService(m.HandlerContainer, "/apis", allGroups)
|
apiserver.AddApisWebService(m.HandlerContainer, "/apis", func() []unversioned.APIGroup {
|
||||||
|
groups := []unversioned.APIGroup{}
|
||||||
|
for ix := range allGroups {
|
||||||
|
groups = append(groups, allGroups[ix])
|
||||||
|
}
|
||||||
|
m.thirdPartyResourcesLock.Lock()
|
||||||
|
defer m.thirdPartyResourcesLock.Unlock()
|
||||||
|
if m.thirdPartyResources != nil {
|
||||||
|
for key := range m.thirdPartyResources {
|
||||||
|
groups = append(groups, m.thirdPartyResources[key].group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groups
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Master) initV1ResourcesStorage(c *Config) {
|
func (m *Master) initV1ResourcesStorage(c *Config) {
|
||||||
@ -432,7 +452,7 @@ func (m *Master) removeThirdPartyStorage(path string) error {
|
|||||||
defer m.thirdPartyResourcesLock.Unlock()
|
defer m.thirdPartyResourcesLock.Unlock()
|
||||||
storage, found := m.thirdPartyResources[path]
|
storage, found := m.thirdPartyResources[path]
|
||||||
if found {
|
if found {
|
||||||
if err := m.removeAllThirdPartyResources(storage); err != nil {
|
if err := m.removeAllThirdPartyResources(storage.storage); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
delete(m.thirdPartyResources, path)
|
delete(m.thirdPartyResources, path)
|
||||||
@ -486,10 +506,10 @@ func (m *Master) ListThirdPartyResources() []string {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Master) addThirdPartyResourceStorage(path string, storage *thirdpartyresourcedataetcd.REST) {
|
func (m *Master) addThirdPartyResourceStorage(path string, storage *thirdpartyresourcedataetcd.REST, apiGroup unversioned.APIGroup) {
|
||||||
m.thirdPartyResourcesLock.Lock()
|
m.thirdPartyResourcesLock.Lock()
|
||||||
defer m.thirdPartyResourcesLock.Unlock()
|
defer m.thirdPartyResourcesLock.Unlock()
|
||||||
m.thirdPartyResources[path] = storage
|
m.thirdPartyResources[path] = thirdPartyEntry{storage, apiGroup}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstallThirdPartyResource installs a third party resource specified by 'rsrc'. When a resource is
|
// InstallThirdPartyResource installs a third party resource specified by 'rsrc'. When a resource is
|
||||||
@ -518,7 +538,7 @@ func (m *Master) InstallThirdPartyResource(rsrc *extensions.ThirdPartyResource)
|
|||||||
Versions: []unversioned.GroupVersionForDiscovery{groupVersion},
|
Versions: []unversioned.GroupVersionForDiscovery{groupVersion},
|
||||||
}
|
}
|
||||||
apiserver.AddGroupWebService(m.HandlerContainer, path, apiGroup)
|
apiserver.AddGroupWebService(m.HandlerContainer, path, apiGroup)
|
||||||
m.addThirdPartyResourceStorage(path, thirdparty.Storage[strings.ToLower(kind)+"s"].(*thirdpartyresourcedataetcd.REST))
|
m.addThirdPartyResourceStorage(path, thirdparty.Storage[strings.ToLower(kind)+"s"].(*thirdpartyresourcedataetcd.REST), apiGroup)
|
||||||
apiserver.InstallServiceErrorHandler(m.HandlerContainer, m.NewRequestInfoResolver(), []string{thirdparty.GroupVersion.String()})
|
apiserver.InstallServiceErrorHandler(m.HandlerContainer, m.NewRequestInfoResolver(), []string{thirdparty.GroupVersion.String()})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/registry/endpoint"
|
"k8s.io/kubernetes/pkg/registry/endpoint"
|
||||||
"k8s.io/kubernetes/pkg/registry/namespace"
|
"k8s.io/kubernetes/pkg/registry/namespace"
|
||||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||||
thirdpartyresourcedatastorage "k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd"
|
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/storage"
|
"k8s.io/kubernetes/pkg/storage"
|
||||||
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
||||||
@ -343,6 +342,36 @@ func TestDiscoveryAtAPIS(t *testing.T) {
|
|||||||
assert.Equal(expectGroupName, groupList.Groups[0].Name)
|
assert.Equal(expectGroupName, groupList.Groups[0].Name)
|
||||||
assert.Equal(expectVersions, groupList.Groups[0].Versions)
|
assert.Equal(expectVersions, groupList.Groups[0].Versions)
|
||||||
assert.Equal(expectPreferredVersion, groupList.Groups[0].PreferredVersion)
|
assert.Equal(expectPreferredVersion, groupList.Groups[0].PreferredVersion)
|
||||||
|
|
||||||
|
thirdPartyGV := unversioned.GroupVersionForDiscovery{GroupVersion: "company.com/v1", Version: "v1"}
|
||||||
|
master.thirdPartyResources["/apis/company.com/v1"] = thirdPartyEntry{
|
||||||
|
nil,
|
||||||
|
unversioned.APIGroup{
|
||||||
|
Name: "company.com",
|
||||||
|
Versions: []unversioned.GroupVersionForDiscovery{thirdPartyGV},
|
||||||
|
PreferredVersion: thirdPartyGV,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err = http.Get(server.URL + "/apis")
|
||||||
|
if !assert.NoError(err) {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
|
assert.NoError(decodeResponse(resp, &groupList))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
thirdPartyGroupName := "company.com"
|
||||||
|
thirdPartyExpectVersions := []unversioned.GroupVersionForDiscovery{thirdPartyGV}
|
||||||
|
|
||||||
|
assert.Equal(thirdPartyGroupName, groupList.Groups[1].Name)
|
||||||
|
assert.Equal(thirdPartyExpectVersions, groupList.Groups[1].Versions)
|
||||||
|
assert.Equal(thirdPartyGV, groupList.Groups[1].PreferredVersion)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var versionsToTest = []string{"v1", "v3"}
|
var versionsToTest = []string{"v1", "v3"}
|
||||||
@ -365,7 +394,7 @@ type FooList struct {
|
|||||||
func initThirdParty(t *testing.T, version string) (*Master, *etcdtesting.EtcdTestServer, *httptest.Server, *assert.Assertions) {
|
func initThirdParty(t *testing.T, version string) (*Master, *etcdtesting.EtcdTestServer, *httptest.Server, *assert.Assertions) {
|
||||||
master, etcdserver, _, assert := setUp(t)
|
master, etcdserver, _, assert := setUp(t)
|
||||||
|
|
||||||
master.thirdPartyResources = map[string]*thirdpartyresourcedatastorage.REST{}
|
master.thirdPartyResources = map[string]thirdPartyEntry{}
|
||||||
api := &extensions.ThirdPartyResource{
|
api := &extensions.ThirdPartyResource{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "foo.company.com",
|
Name: "foo.company.com",
|
||||||
|
Loading…
Reference in New Issue
Block a user