mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
Merge pull request #33384 from deads2k/api-14-move-storage-files
Automatic merge from submit-queue move the REST storage creation to its proper packages Moves the `RESTStorageProvider` interfaces to their proper packages.
This commit is contained in:
commit
4219d9584b
@ -55,9 +55,34 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/healthz"
|
"k8s.io/kubernetes/pkg/healthz"
|
||||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||||
"k8s.io/kubernetes/pkg/master/ports"
|
"k8s.io/kubernetes/pkg/master/ports"
|
||||||
controlleretcd "k8s.io/kubernetes/pkg/registry/controller/etcd"
|
|
||||||
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
|
"k8s.io/kubernetes/pkg/registry/generic/registry"
|
||||||
|
"k8s.io/kubernetes/pkg/routes"
|
||||||
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
|
etcdutil "k8s.io/kubernetes/pkg/storage/etcd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/storage/storagebackend"
|
||||||
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
// RESTStorage installers
|
||||||
|
appsrest "k8s.io/kubernetes/pkg/registry/apps/rest"
|
||||||
|
authenticationrest "k8s.io/kubernetes/pkg/registry/authentication/rest"
|
||||||
|
authorizationrest "k8s.io/kubernetes/pkg/registry/authorization/rest"
|
||||||
|
autoscalingrest "k8s.io/kubernetes/pkg/registry/autoscaling/rest"
|
||||||
|
batchrest "k8s.io/kubernetes/pkg/registry/batch/rest"
|
||||||
|
certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest"
|
||||||
|
extensionsrest "k8s.io/kubernetes/pkg/registry/extensions/rest"
|
||||||
|
policyrest "k8s.io/kubernetes/pkg/registry/policy/rest"
|
||||||
|
rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
|
||||||
|
storagerest "k8s.io/kubernetes/pkg/registry/storage/rest"
|
||||||
|
|
||||||
|
// direct etcd registry dependencies
|
||||||
"k8s.io/kubernetes/pkg/registry/core/componentstatus"
|
"k8s.io/kubernetes/pkg/registry/core/componentstatus"
|
||||||
configmapetcd "k8s.io/kubernetes/pkg/registry/core/configmap/etcd"
|
configmapetcd "k8s.io/kubernetes/pkg/registry/core/configmap/etcd"
|
||||||
|
controlleretcd "k8s.io/kubernetes/pkg/registry/core/controller/etcd"
|
||||||
"k8s.io/kubernetes/pkg/registry/core/endpoint"
|
"k8s.io/kubernetes/pkg/registry/core/endpoint"
|
||||||
endpointsetcd "k8s.io/kubernetes/pkg/registry/core/endpoint/etcd"
|
endpointsetcd "k8s.io/kubernetes/pkg/registry/core/endpoint/etcd"
|
||||||
eventetcd "k8s.io/kubernetes/pkg/registry/core/event/etcd"
|
eventetcd "k8s.io/kubernetes/pkg/registry/core/event/etcd"
|
||||||
@ -82,17 +107,6 @@ import (
|
|||||||
serviceaccountetcd "k8s.io/kubernetes/pkg/registry/core/serviceaccount/etcd"
|
serviceaccountetcd "k8s.io/kubernetes/pkg/registry/core/serviceaccount/etcd"
|
||||||
"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata"
|
"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata"
|
||||||
thirdpartyresourcedataetcd "k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata/etcd"
|
thirdpartyresourcedataetcd "k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata/etcd"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
|
||||||
"k8s.io/kubernetes/pkg/registry/generic/registry"
|
|
||||||
rbacstorage "k8s.io/kubernetes/pkg/registry/rbac/storage"
|
|
||||||
"k8s.io/kubernetes/pkg/routes"
|
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
|
||||||
etcdutil "k8s.io/kubernetes/pkg/storage/etcd/util"
|
|
||||||
"k8s.io/kubernetes/pkg/storage/storagebackend"
|
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -224,19 +238,19 @@ func New(c *Config) (*Master, error) {
|
|||||||
if c.RESTStorageProviders == nil {
|
if c.RESTStorageProviders == nil {
|
||||||
c.RESTStorageProviders = map[string]genericapiserver.RESTStorageProvider{}
|
c.RESTStorageProviders = map[string]genericapiserver.RESTStorageProvider{}
|
||||||
}
|
}
|
||||||
c.RESTStorageProviders[appsapi.GroupName] = AppsRESTStorageProvider{}
|
c.RESTStorageProviders[appsapi.GroupName] = appsrest.RESTStorageProvider{}
|
||||||
c.RESTStorageProviders[autoscaling.GroupName] = AutoscalingRESTStorageProvider{}
|
c.RESTStorageProviders[authenticationv1beta1.GroupName] = authenticationrest.RESTStorageProvider{Authenticator: c.Authenticator}
|
||||||
c.RESTStorageProviders[batch.GroupName] = BatchRESTStorageProvider{}
|
c.RESTStorageProviders[authorization.GroupName] = authorizationrest.RESTStorageProvider{Authorizer: c.Authorizer}
|
||||||
c.RESTStorageProviders[certificates.GroupName] = CertificatesRESTStorageProvider{}
|
c.RESTStorageProviders[autoscaling.GroupName] = autoscalingrest.RESTStorageProvider{}
|
||||||
c.RESTStorageProviders[extensions.GroupName] = ExtensionsRESTStorageProvider{
|
c.RESTStorageProviders[batch.GroupName] = batchrest.RESTStorageProvider{}
|
||||||
|
c.RESTStorageProviders[certificates.GroupName] = certificatesrest.RESTStorageProvider{}
|
||||||
|
c.RESTStorageProviders[extensions.GroupName] = extensionsrest.RESTStorageProvider{
|
||||||
ResourceInterface: m,
|
ResourceInterface: m,
|
||||||
DisableThirdPartyControllerForTesting: m.disableThirdPartyControllerForTesting,
|
DisableThirdPartyControllerForTesting: m.disableThirdPartyControllerForTesting,
|
||||||
}
|
}
|
||||||
c.RESTStorageProviders[policy.GroupName] = PolicyRESTStorageProvider{}
|
c.RESTStorageProviders[policy.GroupName] = policyrest.RESTStorageProvider{}
|
||||||
c.RESTStorageProviders[rbac.GroupName] = &rbacstorage.RESTStorageProvider{AuthorizerRBACSuperUser: c.AuthorizerRBACSuperUser}
|
c.RESTStorageProviders[rbac.GroupName] = &rbacrest.RESTStorageProvider{AuthorizerRBACSuperUser: c.AuthorizerRBACSuperUser}
|
||||||
c.RESTStorageProviders[storage.GroupName] = StorageRESTStorageProvider{}
|
c.RESTStorageProviders[storage.GroupName] = storagerest.RESTStorageProvider{}
|
||||||
c.RESTStorageProviders[authenticationv1beta1.GroupName] = AuthenticationRESTStorageProvider{Authenticator: c.Authenticator}
|
|
||||||
c.RESTStorageProviders[authorization.GroupName] = AuthorizationRESTStorageProvider{Authorizer: c.Authorizer}
|
|
||||||
m.InstallAPIs(c)
|
m.InstallAPIs(c)
|
||||||
|
|
||||||
// TODO: Attempt clean shutdown?
|
// TODO: Attempt clean shutdown?
|
||||||
@ -566,7 +580,7 @@ func (m *Master) HasThirdPartyResource(rsrc *extensions.ThirdPartyResource) (boo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
path := makeThirdPartyPath(group)
|
path := extensionsrest.MakeThirdPartyPath(group)
|
||||||
m.thirdPartyResourcesLock.Lock()
|
m.thirdPartyResourcesLock.Lock()
|
||||||
defer m.thirdPartyResourcesLock.Unlock()
|
defer m.thirdPartyResourcesLock.Unlock()
|
||||||
entry := m.thirdPartyResources[path]
|
entry := m.thirdPartyResources[path]
|
||||||
@ -599,7 +613,7 @@ func (m *Master) removeThirdPartyStorage(path, resource string) error {
|
|||||||
delete(entry.storage, resource)
|
delete(entry.storage, resource)
|
||||||
if len(entry.storage) == 0 {
|
if len(entry.storage) == 0 {
|
||||||
delete(m.thirdPartyResources, path)
|
delete(m.thirdPartyResources, path)
|
||||||
m.RemoveAPIGroupForDiscovery(getThirdPartyGroupName(path))
|
m.RemoveAPIGroupForDiscovery(extensionsrest.GetThirdPartyGroupName(path))
|
||||||
} else {
|
} else {
|
||||||
m.thirdPartyResources[path] = entry
|
m.thirdPartyResources[path] = entry
|
||||||
}
|
}
|
||||||
@ -720,7 +734,7 @@ func (m *Master) InstallThirdPartyResource(rsrc *extensions.ThirdPartyResource)
|
|||||||
Version: rsrc.Versions[0].Name,
|
Version: rsrc.Versions[0].Name,
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
})
|
})
|
||||||
path := makeThirdPartyPath(group)
|
path := extensionsrest.MakeThirdPartyPath(group)
|
||||||
|
|
||||||
groupVersion := unversioned.GroupVersionForDiscovery{
|
groupVersion := unversioned.GroupVersionForDiscovery{
|
||||||
GroupVersion: group + "/" + rsrc.Versions[0].Name,
|
GroupVersion: group + "/" + rsrc.Versions[0].Name,
|
||||||
@ -770,7 +784,7 @@ func (m *Master) thirdpartyapi(group, kind, version, pluralResource string) *api
|
|||||||
internalVersion := unversioned.GroupVersion{Group: group, Version: runtime.APIVersionInternal}
|
internalVersion := unversioned.GroupVersion{Group: group, Version: runtime.APIVersionInternal}
|
||||||
externalVersion := unversioned.GroupVersion{Group: group, Version: version}
|
externalVersion := unversioned.GroupVersion{Group: group, Version: version}
|
||||||
|
|
||||||
apiRoot := makeThirdPartyPath("")
|
apiRoot := extensionsrest.MakeThirdPartyPath("")
|
||||||
return &apiserver.APIGroupVersion{
|
return &apiserver.APIGroupVersion{
|
||||||
Root: apiRoot,
|
Root: apiRoot,
|
||||||
GroupVersion: externalVersion,
|
GroupVersion: externalVersion,
|
||||||
@ -793,7 +807,7 @@ func (m *Master) thirdpartyapi(group, kind, version, pluralResource string) *api
|
|||||||
|
|
||||||
MinRequestTimeout: m.MinRequestTimeout(),
|
MinRequestTimeout: m.MinRequestTimeout(),
|
||||||
|
|
||||||
ResourceLister: dynamicLister{m, makeThirdPartyPath(group)},
|
ResourceLister: dynamicLister{m, extensionsrest.MakeThirdPartyPath(group)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/registry/core/endpoint"
|
"k8s.io/kubernetes/pkg/registry/core/endpoint"
|
||||||
"k8s.io/kubernetes/pkg/registry/core/namespace"
|
"k8s.io/kubernetes/pkg/registry/core/namespace"
|
||||||
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||||
|
extensionsrest "k8s.io/kubernetes/pkg/registry/extensions/rest"
|
||||||
"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata"
|
"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||||
@ -1127,7 +1128,7 @@ func testInstallThirdPartyResourceRemove(t *testing.T, version string) {
|
|||||||
t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item)
|
t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
path := makeThirdPartyPath("company.com")
|
path := extensionsrest.MakeThirdPartyPath("company.com")
|
||||||
master.RemoveThirdPartyResource(path + "/foos")
|
master.RemoveThirdPartyResource(path + "/foos")
|
||||||
|
|
||||||
resp, err = http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test")
|
resp, err = http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test")
|
||||||
|
@ -17,21 +17,10 @@ limitations under the License.
|
|||||||
package master
|
package master
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
expapi "k8s.io/kubernetes/pkg/apis/extensions"
|
|
||||||
"k8s.io/kubernetes/pkg/apiserver"
|
"k8s.io/kubernetes/pkg/apiserver"
|
||||||
thirdpartyresourceetcd "k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresource/etcd"
|
|
||||||
"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata"
|
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const thirdpartyprefix = "/apis"
|
|
||||||
|
|
||||||
// dynamicLister is used to list resources for dynamic third party
|
// dynamicLister is used to list resources for dynamic third party
|
||||||
// apis. It implements the apiserver.APIResourceLister interface
|
// apis. It implements the apiserver.APIResourceLister interface
|
||||||
type dynamicLister struct {
|
type dynamicLister struct {
|
||||||
@ -44,103 +33,3 @@ func (d dynamicLister) ListAPIResources() []unversioned.APIResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ apiserver.APIResourceLister = &dynamicLister{}
|
var _ apiserver.APIResourceLister = &dynamicLister{}
|
||||||
|
|
||||||
func makeThirdPartyPath(group string) string {
|
|
||||||
if len(group) == 0 {
|
|
||||||
return thirdpartyprefix
|
|
||||||
}
|
|
||||||
return thirdpartyprefix + "/" + group
|
|
||||||
}
|
|
||||||
|
|
||||||
func getThirdPartyGroupName(path string) string {
|
|
||||||
return strings.TrimPrefix(strings.TrimPrefix(path, thirdpartyprefix), "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
// resourceInterface is the interface for the parts of the master that know how to add/remove
|
|
||||||
// third party resources. Extracted into an interface for injection for testing.
|
|
||||||
type resourceInterface interface {
|
|
||||||
// Remove a third party resource based on the RESTful path for that resource, the path is <api-group-path>/<resource-plural-name>
|
|
||||||
RemoveThirdPartyResource(path string) error
|
|
||||||
// Install a third party resource described by 'rsrc'
|
|
||||||
InstallThirdPartyResource(rsrc *expapi.ThirdPartyResource) error
|
|
||||||
// Is a particular third party resource currently installed?
|
|
||||||
HasThirdPartyResource(rsrc *expapi.ThirdPartyResource) (bool, error)
|
|
||||||
// List all currently installed third party resources, the returned
|
|
||||||
// names are of the form <api-group-path>/<resource-plural-name>
|
|
||||||
ListThirdPartyResources() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ThirdPartyController is a control loop that knows how to synchronize ThirdPartyResource objects with
|
|
||||||
// RESTful resources which are present in the API server.
|
|
||||||
type ThirdPartyController struct {
|
|
||||||
master resourceInterface
|
|
||||||
thirdPartyResourceRegistry *thirdpartyresourceetcd.REST
|
|
||||||
}
|
|
||||||
|
|
||||||
// Synchronize a single resource with RESTful resources on the master
|
|
||||||
func (t *ThirdPartyController) SyncOneResource(rsrc *expapi.ThirdPartyResource) error {
|
|
||||||
// TODO: we also need to test if the existing installed resource matches the resource we are sync-ing.
|
|
||||||
// Currently, if there is an older, incompatible resource installed, we won't remove it. We should detect
|
|
||||||
// older, incompatible resources and remove them before testing if the resource exists.
|
|
||||||
hasResource, err := t.master.HasThirdPartyResource(rsrc)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !hasResource {
|
|
||||||
return t.master.InstallThirdPartyResource(rsrc)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Synchronize all resources with RESTful resources on the master
|
|
||||||
func (t *ThirdPartyController) SyncResources() error {
|
|
||||||
list, err := t.thirdPartyResourceRegistry.List(api.NewDefaultContext(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return t.syncResourceList(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *ThirdPartyController) syncResourceList(list runtime.Object) error {
|
|
||||||
existing := sets.String{}
|
|
||||||
switch list := list.(type) {
|
|
||||||
case *expapi.ThirdPartyResourceList:
|
|
||||||
// Loop across all schema objects for third party resources
|
|
||||||
for ix := range list.Items {
|
|
||||||
item := &list.Items[ix]
|
|
||||||
// extract the api group and resource kind from the schema
|
|
||||||
_, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(item)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// place it in the set of resources that we expect, so that we don't delete it in the delete pass
|
|
||||||
existing.Insert(makeThirdPartyPath(group))
|
|
||||||
// ensure a RESTful resource for this schema exists on the master
|
|
||||||
if err := t.SyncOneResource(item); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("expected a *ThirdPartyResourceList, got %#v", list)
|
|
||||||
}
|
|
||||||
// deletion phase, get all installed RESTful resources
|
|
||||||
installed := t.master.ListThirdPartyResources()
|
|
||||||
for _, installedAPI := range installed {
|
|
||||||
found := false
|
|
||||||
// search across the expected restful resources to see if this resource belongs to one of the expected ones
|
|
||||||
for _, apiPath := range existing.List() {
|
|
||||||
if installedAPI == apiPath || strings.HasPrefix(installedAPI, apiPath+"/") {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// not expected, delete the resource
|
|
||||||
if !found {
|
|
||||||
if err := t.master.RemoveThirdPartyResource(installedAPI); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
@ -24,11 +24,11 @@ import (
|
|||||||
petsetetcd "k8s.io/kubernetes/pkg/registry/apps/petset/etcd"
|
petsetetcd "k8s.io/kubernetes/pkg/registry/apps/petset/etcd"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AppsRESTStorageProvider struct{}
|
type RESTStorageProvider struct{}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &AppsRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p AppsRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apps.GroupName)
|
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apps.GroupName)
|
||||||
|
|
||||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(appsapiv1alpha1.SchemeGroupVersion) {
|
if apiResourceConfigSource.AnyResourcesForVersionEnabled(appsapiv1alpha1.SchemeGroupVersion) {
|
||||||
@ -39,7 +39,7 @@ func (p AppsRESTStorageProvider) NewRESTStorage(apiResourceConfigSource generica
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p AppsRESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := appsapiv1alpha1.SchemeGroupVersion
|
version := appsapiv1alpha1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
@ -25,13 +25,13 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/registry/authentication/tokenreview"
|
"k8s.io/kubernetes/pkg/registry/authentication/tokenreview"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthenticationRESTStorageProvider struct {
|
type RESTStorageProvider struct {
|
||||||
Authenticator authenticator.Request
|
Authenticator authenticator.Request
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &AuthenticationRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p AuthenticationRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
// TODO figure out how to make the swagger generation stable, while allowing this endpoint to be disabled.
|
// TODO figure out how to make the swagger generation stable, while allowing this endpoint to be disabled.
|
||||||
// if p.Authenticator == nil {
|
// if p.Authenticator == nil {
|
||||||
// return genericapiserver.APIGroupInfo{}, false
|
// return genericapiserver.APIGroupInfo{}, false
|
||||||
@ -47,7 +47,7 @@ func (p AuthenticationRESTStorageProvider) NewRESTStorage(apiResourceConfigSourc
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p AuthenticationRESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := authenticationv1beta1.SchemeGroupVersion
|
version := authenticationv1beta1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
@ -27,13 +27,13 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/registry/authorization/subjectaccessreview"
|
"k8s.io/kubernetes/pkg/registry/authorization/subjectaccessreview"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthorizationRESTStorageProvider struct {
|
type RESTStorageProvider struct {
|
||||||
Authorizer authorizer.Authorizer
|
Authorizer authorizer.Authorizer
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &AuthorizationRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p AuthorizationRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
if p.Authorizer == nil {
|
if p.Authorizer == nil {
|
||||||
return genericapiserver.APIGroupInfo{}, false
|
return genericapiserver.APIGroupInfo{}, false
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ func (p AuthorizationRESTStorageProvider) NewRESTStorage(apiResourceConfigSource
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p AuthorizationRESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := authorizationv1beta1.SchemeGroupVersion
|
version := authorizationv1beta1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
@ -24,11 +24,11 @@ import (
|
|||||||
horizontalpodautoscaleretcd "k8s.io/kubernetes/pkg/registry/autoscaling/horizontalpodautoscaler/etcd"
|
horizontalpodautoscaleretcd "k8s.io/kubernetes/pkg/registry/autoscaling/horizontalpodautoscaler/etcd"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AutoscalingRESTStorageProvider struct{}
|
type RESTStorageProvider struct{}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &AutoscalingRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p AutoscalingRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(autoscaling.GroupName)
|
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(autoscaling.GroupName)
|
||||||
|
|
||||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(autoscalingapiv1.SchemeGroupVersion) {
|
if apiResourceConfigSource.AnyResourcesForVersionEnabled(autoscalingapiv1.SchemeGroupVersion) {
|
||||||
@ -39,7 +39,7 @@ func (p AutoscalingRESTStorageProvider) NewRESTStorage(apiResourceConfigSource g
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p AutoscalingRESTStorageProvider) v1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := autoscalingapiv1.SchemeGroupVersion
|
version := autoscalingapiv1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
@ -26,11 +26,11 @@ import (
|
|||||||
scheduledjobetcd "k8s.io/kubernetes/pkg/registry/batch/scheduledjob/etcd"
|
scheduledjobetcd "k8s.io/kubernetes/pkg/registry/batch/scheduledjob/etcd"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BatchRESTStorageProvider struct{}
|
type RESTStorageProvider struct{}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &BatchRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p BatchRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(batch.GroupName)
|
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(batch.GroupName)
|
||||||
|
|
||||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv2alpha1.SchemeGroupVersion) {
|
if apiResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv2alpha1.SchemeGroupVersion) {
|
||||||
@ -45,7 +45,7 @@ func (p BatchRESTStorageProvider) NewRESTStorage(apiResourceConfigSource generic
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p BatchRESTStorageProvider) v1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := batchapiv1.SchemeGroupVersion
|
version := batchapiv1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
||||||
@ -57,7 +57,7 @@ func (p BatchRESTStorageProvider) v1Storage(apiResourceConfigSource genericapise
|
|||||||
return storage
|
return storage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p BatchRESTStorageProvider) v2alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v2alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := batchapiv2alpha1.SchemeGroupVersion
|
version := batchapiv2alpha1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
@ -24,11 +24,11 @@ import (
|
|||||||
certificateetcd "k8s.io/kubernetes/pkg/registry/certificates/certificates/etcd"
|
certificateetcd "k8s.io/kubernetes/pkg/registry/certificates/certificates/etcd"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CertificatesRESTStorageProvider struct{}
|
type RESTStorageProvider struct{}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &CertificatesRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p CertificatesRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(certificates.GroupName)
|
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(certificates.GroupName)
|
||||||
|
|
||||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(certificatesapiv1alpha1.SchemeGroupVersion) {
|
if apiResourceConfigSource.AnyResourcesForVersionEnabled(certificatesapiv1alpha1.SchemeGroupVersion) {
|
||||||
@ -39,7 +39,7 @@ func (p CertificatesRESTStorageProvider) NewRESTStorage(apiResourceConfigSource
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p CertificatesRESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := certificatesapiv1alpha1.SchemeGroupVersion
|
version := certificatesapiv1alpha1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
@ -16,4 +16,4 @@ limitations under the License.
|
|||||||
|
|
||||||
// Package controller provides Registry interface and it's RESTStorage
|
// Package controller provides Registry interface and it's RESTStorage
|
||||||
// implementation for storing ReplicationController api objects.
|
// implementation for storing ReplicationController api objects.
|
||||||
package controller // import "k8s.io/kubernetes/pkg/registry/controller"
|
package controller // import "k8s.io/kubernetes/pkg/registry/core/controller"
|
@ -28,7 +28,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/apis/autoscaling/validation"
|
"k8s.io/kubernetes/pkg/apis/autoscaling/validation"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
"k8s.io/kubernetes/pkg/registry/cachesize"
|
"k8s.io/kubernetes/pkg/registry/cachesize"
|
||||||
"k8s.io/kubernetes/pkg/registry/controller"
|
"k8s.io/kubernetes/pkg/registry/core/controller"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic/registry"
|
"k8s.io/kubernetes/pkg/registry/generic/registry"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
@ -23,8 +23,8 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/errors"
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/registry/controller"
|
"k8s.io/kubernetes/pkg/registry/core/controller"
|
||||||
"k8s.io/kubernetes/pkg/registry/controller/etcd"
|
"k8s.io/kubernetes/pkg/registry/core/controller/etcd"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
@ -39,14 +39,14 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExtensionsRESTStorageProvider struct {
|
type RESTStorageProvider struct {
|
||||||
ResourceInterface resourceInterface
|
ResourceInterface ResourceInterface
|
||||||
DisableThirdPartyControllerForTesting bool
|
DisableThirdPartyControllerForTesting bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &ExtensionsRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p ExtensionsRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(extensions.GroupName)
|
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(extensions.GroupName)
|
||||||
|
|
||||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(extensionsapiv1beta1.SchemeGroupVersion) {
|
if apiResourceConfigSource.AnyResourcesForVersionEnabled(extensionsapiv1beta1.SchemeGroupVersion) {
|
||||||
@ -57,7 +57,7 @@ func (p ExtensionsRESTStorageProvider) NewRESTStorage(apiResourceConfigSource ge
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p ExtensionsRESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := extensionsapiv1beta1.SchemeGroupVersion
|
version := extensionsapiv1beta1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
131
pkg/registry/extensions/rest/thirdparty_controller.go
Normal file
131
pkg/registry/extensions/rest/thirdparty_controller.go
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
|
thirdpartyresourceetcd "k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresource/etcd"
|
||||||
|
"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata"
|
||||||
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ResourceInterface is the interface for the parts of the master that know how to add/remove
|
||||||
|
// third party resources. Extracted into an interface for injection for testing.
|
||||||
|
type ResourceInterface interface {
|
||||||
|
// Remove a third party resource based on the RESTful path for that resource, the path is <api-group-path>/<resource-plural-name>
|
||||||
|
RemoveThirdPartyResource(path string) error
|
||||||
|
// Install a third party resource described by 'rsrc'
|
||||||
|
InstallThirdPartyResource(rsrc *extensions.ThirdPartyResource) error
|
||||||
|
// Is a particular third party resource currently installed?
|
||||||
|
HasThirdPartyResource(rsrc *extensions.ThirdPartyResource) (bool, error)
|
||||||
|
// List all currently installed third party resources, the returned
|
||||||
|
// names are of the form <api-group-path>/<resource-plural-name>
|
||||||
|
ListThirdPartyResources() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
const thirdpartyprefix = "/apis"
|
||||||
|
|
||||||
|
// ThirdPartyController is a control loop that knows how to synchronize ThirdPartyResource objects with
|
||||||
|
// RESTful resources which are present in the API server.
|
||||||
|
type ThirdPartyController struct {
|
||||||
|
master ResourceInterface
|
||||||
|
thirdPartyResourceRegistry *thirdpartyresourceetcd.REST
|
||||||
|
}
|
||||||
|
|
||||||
|
// Synchronize a single resource with RESTful resources on the master
|
||||||
|
func (t *ThirdPartyController) SyncOneResource(rsrc *extensions.ThirdPartyResource) error {
|
||||||
|
// TODO: we also need to test if the existing installed resource matches the resource we are sync-ing.
|
||||||
|
// Currently, if there is an older, incompatible resource installed, we won't remove it. We should detect
|
||||||
|
// older, incompatible resources and remove them before testing if the resource exists.
|
||||||
|
hasResource, err := t.master.HasThirdPartyResource(rsrc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !hasResource {
|
||||||
|
return t.master.InstallThirdPartyResource(rsrc)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Synchronize all resources with RESTful resources on the master
|
||||||
|
func (t *ThirdPartyController) SyncResources() error {
|
||||||
|
list, err := t.thirdPartyResourceRegistry.List(api.NewDefaultContext(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return t.syncResourceList(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ThirdPartyController) syncResourceList(list runtime.Object) error {
|
||||||
|
existing := sets.String{}
|
||||||
|
switch list := list.(type) {
|
||||||
|
case *extensions.ThirdPartyResourceList:
|
||||||
|
// Loop across all schema objects for third party resources
|
||||||
|
for ix := range list.Items {
|
||||||
|
item := &list.Items[ix]
|
||||||
|
// extract the api group and resource kind from the schema
|
||||||
|
_, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(item)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// place it in the set of resources that we expect, so that we don't delete it in the delete pass
|
||||||
|
existing.Insert(MakeThirdPartyPath(group))
|
||||||
|
// ensure a RESTful resource for this schema exists on the master
|
||||||
|
if err := t.SyncOneResource(item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("expected a *ThirdPartyResourceList, got %#v", list)
|
||||||
|
}
|
||||||
|
// deletion phase, get all installed RESTful resources
|
||||||
|
installed := t.master.ListThirdPartyResources()
|
||||||
|
for _, installedAPI := range installed {
|
||||||
|
found := false
|
||||||
|
// search across the expected restful resources to see if this resource belongs to one of the expected ones
|
||||||
|
for _, apiPath := range existing.List() {
|
||||||
|
if installedAPI == apiPath || strings.HasPrefix(installedAPI, apiPath+"/") {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not expected, delete the resource
|
||||||
|
if !found {
|
||||||
|
if err := t.master.RemoveThirdPartyResource(installedAPI); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeThirdPartyPath(group string) string {
|
||||||
|
if len(group) == 0 {
|
||||||
|
return thirdpartyprefix
|
||||||
|
}
|
||||||
|
return thirdpartyprefix + "/" + group
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetThirdPartyGroupName(path string) string {
|
||||||
|
return strings.TrimPrefix(strings.TrimPrefix(path, thirdpartyprefix), "/")
|
||||||
|
}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@ -40,7 +40,7 @@ func (f *FakeAPIInterface) RemoveThirdPartyResource(path string) error {
|
|||||||
func (f *FakeAPIInterface) InstallThirdPartyResource(rsrc *expapi.ThirdPartyResource) error {
|
func (f *FakeAPIInterface) InstallThirdPartyResource(rsrc *expapi.ThirdPartyResource) error {
|
||||||
f.installed = append(f.installed, rsrc)
|
f.installed = append(f.installed, rsrc)
|
||||||
_, group, _ := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc)
|
_, group, _ := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc)
|
||||||
f.apis = append(f.apis, makeThirdPartyPath(group))
|
f.apis = append(f.apis, MakeThirdPartyPath(group))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ func (f *FakeAPIInterface) HasThirdPartyResource(rsrc *expapi.ThirdPartyResource
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
_, group, _ := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc)
|
_, group, _ := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc)
|
||||||
path := makeThirdPartyPath(group)
|
path := MakeThirdPartyPath(group)
|
||||||
for _, api := range f.apis {
|
for _, api := range f.apis {
|
||||||
if api == path {
|
if api == path {
|
||||||
return true, nil
|
return true, nil
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
@ -24,11 +24,11 @@ import (
|
|||||||
poddisruptionbudgetetcd "k8s.io/kubernetes/pkg/registry/policy/poddisruptionbudget/etcd"
|
poddisruptionbudgetetcd "k8s.io/kubernetes/pkg/registry/policy/poddisruptionbudget/etcd"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PolicyRESTStorageProvider struct{}
|
type RESTStorageProvider struct{}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &PolicyRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p PolicyRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(policy.GroupName)
|
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(policy.GroupName)
|
||||||
|
|
||||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(policyapiv1alpha1.SchemeGroupVersion) {
|
if apiResourceConfigSource.AnyResourcesForVersionEnabled(policyapiv1alpha1.SchemeGroupVersion) {
|
||||||
@ -39,7 +39,7 @@ func (p PolicyRESTStorageProvider) NewRESTStorage(apiResourceConfigSource generi
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p PolicyRESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := policyapiv1alpha1.SchemeGroupVersion
|
version := policyapiv1alpha1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package storage
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package master
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api/rest"
|
"k8s.io/kubernetes/pkg/api/rest"
|
||||||
@ -24,12 +24,12 @@ import (
|
|||||||
storageclassetcd "k8s.io/kubernetes/pkg/registry/storage/storageclass/etcd"
|
storageclassetcd "k8s.io/kubernetes/pkg/registry/storage/storageclass/etcd"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StorageRESTStorageProvider struct {
|
type RESTStorageProvider struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ genericapiserver.RESTStorageProvider = &StorageRESTStorageProvider{}
|
var _ genericapiserver.RESTStorageProvider = &RESTStorageProvider{}
|
||||||
|
|
||||||
func (p StorageRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(storageapi.GroupName)
|
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(storageapi.GroupName)
|
||||||
|
|
||||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(storageapiv1beta1.SchemeGroupVersion) {
|
if apiResourceConfigSource.AnyResourcesForVersionEnabled(storageapiv1beta1.SchemeGroupVersion) {
|
||||||
@ -40,7 +40,7 @@ func (p StorageRESTStorageProvider) NewRESTStorage(apiResourceConfigSource gener
|
|||||||
return apiGroupInfo, true
|
return apiGroupInfo, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p StorageRESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter genericapiserver.RESTOptionsGetter) map[string]rest.Storage {
|
||||||
version := storageapiv1beta1.SchemeGroupVersion
|
version := storageapiv1beta1.SchemeGroupVersion
|
||||||
|
|
||||||
storage := map[string]rest.Storage{}
|
storage := map[string]rest.Storage{}
|
Loading…
Reference in New Issue
Block a user