Fix third party APIs to allow multiple APIs to register for the same group

This commit is contained in:
Brendan Burns 2016-07-01 22:42:51 -07:00
parent 3313d68066
commit ca9a61b3fb
3 changed files with 80 additions and 16 deletions

View File

@ -707,6 +707,13 @@ func (m *Master) ListThirdPartyResources() []string {
return result
}
func (m *Master) hasThirdPartyResourceStorage(path string) bool {
m.thirdPartyResourcesLock.Lock()
defer m.thirdPartyResourcesLock.Unlock()
_, found := m.thirdPartyResources[path]
return found
}
func (m *Master) addThirdPartyResourceStorage(path string, storage *thirdpartyresourcedataetcd.REST, apiGroup unversioned.APIGroup) {
m.thirdPartyResourcesLock.Lock()
defer m.thirdPartyResourcesLock.Unlock()
@ -731,12 +738,19 @@ func (m *Master) InstallThirdPartyResource(rsrc *extensions.ThirdPartyResource)
Version: rsrc.Versions[0].Name,
Kind: kind,
})
path := makeThirdPartyPath(group)
thirdparty := m.thirdpartyapi(group, kind, rsrc.Versions[0].Name, plural.Resource)
if err := thirdparty.InstallREST(m.HandlerContainer); err != nil {
glog.Fatalf("Unable to setup thirdparty api: %v", err)
// If storage exists, this group has already been added, just update
// the group with the new API
if m.hasThirdPartyResourceStorage(path) {
return thirdparty.UpdateREST(m.HandlerContainer)
}
if err := thirdparty.InstallREST(m.HandlerContainer); err != nil {
glog.Errorf("Unable to setup thirdparty api: %v", err)
}
path := makeThirdPartyPath(group)
groupVersion := unversioned.GroupVersionForDiscovery{
GroupVersion: group + "/" + rsrc.Versions[0].Name,
Version: rsrc.Versions[0].Name,

View File

@ -552,27 +552,77 @@ type FooList struct {
}
func initThirdParty(t *testing.T, version, name string) (*Master, *etcdtesting.EtcdTestServer, *httptest.Server, *assert.Assertions) {
return initThirdPartyMultiple(t, []string{version}, []string{name})
}
func initThirdPartyMultiple(t *testing.T, versions, names []string) (*Master, *etcdtesting.EtcdTestServer, *httptest.Server, *assert.Assertions) {
master, etcdserver, _, assert := newMaster(t)
_, master.ServiceClusterIPRange, _ = net.ParseCIDR("10.0.0.0/24")
for ix := range names {
api := &extensions.ThirdPartyResource{
ObjectMeta: api.ObjectMeta{
Name: name,
Name: names[ix],
},
Versions: []extensions.APIVersion{
{
Name: version,
Name: versions[ix],
},
},
}
_, master.ServiceClusterIPRange, _ = net.ParseCIDR("10.0.0.0/24")
if !assert.NoError(master.InstallThirdPartyResource(api)) {
err := master.InstallThirdPartyResource(api)
if !assert.NoError(err) {
t.Logf("Failed to install API: %v", err)
t.FailNow()
}
}
server := httptest.NewServer(master.HandlerContainer.ServeMux)
return master, etcdserver, server, assert
}
func TestInstallMultipleAPIs(t *testing.T) {
names := []string{"foo.company.com", "bar.company.com"}
versions := []string{"v1", "v1"}
_, etcdserver, server, assert := initThirdPartyMultiple(t, versions, names)
defer server.Close()
defer etcdserver.Terminate(t)
for ix := range names {
kind, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(
&extensions.ThirdPartyResource{ObjectMeta: api.ObjectMeta{Name: names[ix]}})
assert.NoError(err, "Failed to extract group & kind")
plural, _ := meta.KindToResource(unversioned.GroupVersionKind{
Group: group,
Version: versions[ix],
Kind: kind,
})
resp, err := http.Get(
fmt.Sprintf("%s/apis/%s/%s/namespaces/default/%s", server.URL, group, versions[ix], plural.Resource))
if !assert.NoError(err, "Failed to do HTTP GET") {
return
}
defer resp.Body.Close()
assert.Equal(http.StatusOK, resp.StatusCode)
data, err := ioutil.ReadAll(resp.Body)
assert.NoError(err)
obj := map[string]interface{}{}
if err = json.Unmarshal(data, &obj); err != nil {
assert.NoError(err, fmt.Sprintf("unexpected error: %v", err))
}
kindOut, found := obj["kind"]
if !found {
t.Errorf("Missing 'kind' in %v", obj)
}
assert.Equal(kindOut, kind+"List")
}
}
func TestInstallThirdPartyAPIList(t *testing.T) {
for _, version := range versionsToTest {
testInstallThirdPartyAPIListVersion(t, version)

View File

@ -324,7 +324,7 @@ func (f *Framework) AfterEach() {
case "json":
for i := range summaries {
typeName := reflect.TypeOf(summaries[i]).String()
Logf("%v JSON\n%v", typeName[strings.LastIndex(typeName, ".")+1:len(typeName)], summaries[i].PrintJSON())
Logf("%v JSON\n%v", typeName[strings.LastIndex(typeName, ".")+1:], summaries[i].PrintJSON())
Logf("Finished")
}
default: