// InstallThirdPartyResource installs a third party resource specified by 'rsrc'. When a resource is // installed a corresponding RESTful resource is added as a valid path in the web service provided by // the master. // // For example, if you install a resource ThirdPartyResource{ Name: "foo.company.com", Versions: {"v1"} } // then the following RESTful resource is created on the server: // http://<host>/apis/company.com/v1/foos/... func (m *ThirdPartyResourceServer) InstallThirdPartyResource(rsrc *extensions.ThirdPartyResource) error { kind, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc) if err != nil { return err } if len(rsrc.Versions) == 0 { return fmt.Errorf("ThirdPartyResource %s has no defined versions", rsrc.Name) } plural, _ := meta.KindToResource(schema.GroupVersionKind{ Group: group, Version: rsrc.Versions[0].Name, Kind: kind, }) path := extensionsrest.MakeThirdPartyPath(group) groupVersion := metav1.GroupVersionForDiscovery{ GroupVersion: group + "/" + rsrc.Versions[0].Name, Version: rsrc.Versions[0].Name, } apiGroup := metav1.APIGroup{ Name: group, Versions: []metav1.GroupVersionForDiscovery{groupVersion}, PreferredVersion: groupVersion, } thirdparty := m.thirdpartyapi(group, kind, rsrc.Versions[0].Name, plural.Resource) // If storage exists, this group has already been added, just update // the group with the new API if m.hasThirdPartyGroupStorage(path) { m.addThirdPartyResourceStorage(path, plural.Resource, thirdparty.Storage[plural.Resource].(*thirdpartyresourcedatastore.REST), apiGroup) return thirdparty.UpdateREST(m.genericAPIServer.HandlerContainer.Container) } if err := thirdparty.InstallREST(m.genericAPIServer.HandlerContainer.Container); err != nil { glog.Errorf("Unable to setup thirdparty api: %v", err) } m.genericAPIServer.HandlerContainer.Add(genericapi.NewGroupWebService(api.Codecs, path, apiGroup)) m.addThirdPartyResourceStorage(path, plural.Resource, thirdparty.Storage[plural.Resource].(*thirdpartyresourcedatastore.REST), apiGroup) api.Registry.AddThirdPartyAPIGroupVersions(schema.GroupVersion{Group: group, Version: rsrc.Versions[0].Name}) 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(APIGroupPrefix, 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 := []metav1.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, metav1.GroupVersionForDiscovery{ GroupVersion: groupVersion.String(), Version: groupVersion.Version, }) } preferedVersionForDiscovery := metav1.GroupVersionForDiscovery{ GroupVersion: apiGroupInfo.GroupMeta.GroupVersion.String(), Version: apiGroupInfo.GroupMeta.GroupVersion.Version, } apiGroup := metav1.APIGroup{ Name: apiGroupInfo.GroupMeta.GroupVersion.Group, Versions: apiVersionsForDiscovery, PreferredVersion: preferedVersionForDiscovery, } s.AddAPIGroupForDiscovery(apiGroup) s.HandlerContainer.Add(genericapi.NewGroupWebService(s.Serializer, APIGroupPrefix+"/"+apiGroup.Name, apiGroup)) return nil }