mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 15:05:27 +00:00
Merge pull request #27554 from deads2k/allow-new-groups
Automatic merge from submit-queue make addition group RESTStorage registration easier Starts factoring out `RESTStorage` creation to eventually allow for decoupled API group `RESTStorage` configuration. Right now you can't add additional groups without modifying the main API Group registration in master.go. Allows the `master.Config` to hold a function that can build a `RESTStorage` based on the `Master` struct. @lavalamp @caesarxuchao @kubernetes/sig-api-machinery @liggitt @smarterclayton
This commit is contained in:
commit
27bb99d41e
@ -25,6 +25,14 @@
|
||||
"path": "/apis/extensions",
|
||||
"description": "get information of a group"
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps/v1alpha1",
|
||||
"description": "API at /apis/apps/v1alpha1"
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps",
|
||||
"description": "get information of a group"
|
||||
},
|
||||
{
|
||||
"path": "/apis/autoscaling/v1",
|
||||
"description": "API at /apis/autoscaling/v1"
|
||||
@ -45,22 +53,6 @@
|
||||
"path": "/apis/batch",
|
||||
"description": "get information of a group"
|
||||
},
|
||||
{
|
||||
"path": "/apis/policy/v1alpha1",
|
||||
"description": "API at /apis/policy/v1alpha1"
|
||||
},
|
||||
{
|
||||
"path": "/apis/policy",
|
||||
"description": "get information of a group"
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps/v1alpha1",
|
||||
"description": "API at /apis/apps/v1alpha1"
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps",
|
||||
"description": "get information of a group"
|
||||
},
|
||||
{
|
||||
"path": "/apis/certificates/v1alpha1",
|
||||
"description": "API at /apis/certificates/v1alpha1"
|
||||
@ -69,6 +61,14 @@
|
||||
"path": "/apis/certificates",
|
||||
"description": "get information of a group"
|
||||
},
|
||||
{
|
||||
"path": "/apis/policy/v1alpha1",
|
||||
"description": "API at /apis/policy/v1alpha1"
|
||||
},
|
||||
{
|
||||
"path": "/apis/policy",
|
||||
"description": "get information of a group"
|
||||
},
|
||||
{
|
||||
"path": "/apis/rbac.authorization.k8s.io/v1alpha1",
|
||||
"description": "API at /apis/rbac.authorization.k8s.io/v1alpha1"
|
||||
|
@ -27,6 +27,7 @@ type APIResourceConfigSource interface {
|
||||
ResourceEnabled(resource unversioned.GroupVersionResource) bool
|
||||
AllResourcesForVersionEnabled(version unversioned.GroupVersion) bool
|
||||
AnyResourcesForVersionEnabled(version unversioned.GroupVersion) bool
|
||||
AnyResourcesForGroupEnabled(group string) bool
|
||||
}
|
||||
|
||||
// Specifies the overrides for various API group versions.
|
||||
@ -170,3 +171,15 @@ func (o *ResourceConfig) AnyResourcesForVersionEnabled(version unversioned.Group
|
||||
|
||||
return versionOverride.Enable
|
||||
}
|
||||
|
||||
func (o *ResourceConfig) AnyResourcesForGroupEnabled(group string) bool {
|
||||
for version := range o.GroupVersionResourceConfigs {
|
||||
if version.Group == group {
|
||||
if o.AnyResourcesForVersionEnabled(version) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -97,3 +97,64 @@ func TestDisabledVersion(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestAnyResourcesForGroupEnabled(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
creator func() APIResourceConfigSource
|
||||
testGroup string
|
||||
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
creator: func() APIResourceConfigSource {
|
||||
return NewResourceConfig()
|
||||
},
|
||||
testGroup: "one",
|
||||
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "present, but disabled",
|
||||
creator: func() APIResourceConfigSource {
|
||||
ret := NewResourceConfig()
|
||||
ret.DisableVersions(unversioned.GroupVersion{Group: "one", Version: "version1"})
|
||||
return ret
|
||||
},
|
||||
testGroup: "one",
|
||||
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "present, and one version enabled",
|
||||
creator: func() APIResourceConfigSource {
|
||||
ret := NewResourceConfig()
|
||||
ret.DisableVersions(unversioned.GroupVersion{Group: "one", Version: "version1"})
|
||||
ret.EnableVersions(unversioned.GroupVersion{Group: "one", Version: "version2"})
|
||||
return ret
|
||||
},
|
||||
testGroup: "one",
|
||||
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "present, and one resource",
|
||||
creator: func() APIResourceConfigSource {
|
||||
ret := NewResourceConfig()
|
||||
ret.DisableVersions(unversioned.GroupVersion{Group: "one", Version: "version1"})
|
||||
ret.EnableResources(unversioned.GroupVersionResource{Group: "one", Version: "version2", Resource: "foo"})
|
||||
return ret
|
||||
},
|
||||
testGroup: "one",
|
||||
|
||||
expectedResult: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
if e, a := tc.expectedResult, tc.creator().AnyResourcesForGroupEnabled(tc.testGroup); e != a {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/storage"
|
||||
etcdmetrics "k8s.io/kubernetes/pkg/storage/etcd/metrics"
|
||||
etcdutil "k8s.io/kubernetes/pkg/storage/etcd/util"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
|
||||
daemonetcd "k8s.io/kubernetes/pkg/registry/daemonset/etcd"
|
||||
@ -132,6 +133,8 @@ type Config struct {
|
||||
DeleteCollectionWorkers int
|
||||
EventTTL time.Duration
|
||||
KubeletClient kubeletclient.KubeletClient
|
||||
// RESTStorageProviders provides RESTStorage building methods keyed by groupName
|
||||
RESTStorageProviders map[string]RESTStorageProvider
|
||||
// Used to start and monitor tunneling
|
||||
Tunneler genericapiserver.Tunneler
|
||||
|
||||
@ -184,6 +187,9 @@ type thirdPartyEntry struct {
|
||||
group unversioned.APIGroup
|
||||
}
|
||||
|
||||
type RESTOptionsGetter func(resource unversioned.GroupResource) generic.RESTOptions
|
||||
type RESTStorageProvider func(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool)
|
||||
|
||||
// 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 must be specified, including:
|
||||
@ -206,6 +212,17 @@ func New(c *Config) (*Master, error) {
|
||||
|
||||
disableThirdPartyControllerForTesting: c.disableThirdPartyControllerForTesting,
|
||||
}
|
||||
|
||||
// Add some hardcoded storage for now. Append to the map.
|
||||
if c.RESTStorageProviders == nil {
|
||||
c.RESTStorageProviders = map[string]RESTStorageProvider{}
|
||||
}
|
||||
c.RESTStorageProviders[autoscaling.GroupName] = buildAutoscalingResources
|
||||
c.RESTStorageProviders[batch.GroupName] = buildBatchResources
|
||||
c.RESTStorageProviders[policy.GroupName] = buildPolicyResources
|
||||
c.RESTStorageProviders[appsapi.GroupName] = buildAppsResources
|
||||
c.RESTStorageProviders[rbac.GroupName] = buildRBACResources(c.AuthorizerRBACSuperUser)
|
||||
c.RESTStorageProviders[certificates.GroupName] = buildCertificateResources
|
||||
m.InstallAPIs(c)
|
||||
|
||||
// TODO: Attempt clean shutdown?
|
||||
@ -297,130 +314,22 @@ func (m *Master) InstallAPIs(c *Config) {
|
||||
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
|
||||
}
|
||||
|
||||
// Install autoscaling unless disabled.
|
||||
if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(autoscalingapiv1.SchemeGroupVersion) {
|
||||
autoscalingResources := m.getAutoscalingResources(c)
|
||||
autoscalingGroupMeta := registered.GroupOrDie(autoscaling.GroupName)
|
||||
|
||||
// Hard code preferred group version to autoscaling/v1
|
||||
autoscalingGroupMeta.GroupVersion = autoscalingapiv1.SchemeGroupVersion
|
||||
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *autoscalingGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1": autoscalingResources,
|
||||
},
|
||||
OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
ParameterCodec: api.ParameterCodec,
|
||||
NegotiatedSerializer: api.Codecs,
|
||||
}
|
||||
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
|
||||
restOptionsGetter := func(resource unversioned.GroupResource) generic.RESTOptions {
|
||||
return m.GetRESTOptionsOrDie(c, resource)
|
||||
}
|
||||
|
||||
// Install batch unless disabled.
|
||||
if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv1.SchemeGroupVersion) ||
|
||||
c.APIResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv2alpha1.SchemeGroupVersion) {
|
||||
batchv1Resources := m.getBatchResources(c, batchapiv1.SchemeGroupVersion)
|
||||
batchGroupMeta := registered.GroupOrDie(batch.GroupName)
|
||||
|
||||
// Hard code preferred group version to batch/v1
|
||||
batchGroupMeta.GroupVersion = batchapiv1.SchemeGroupVersion
|
||||
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *batchGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1": batchv1Resources,
|
||||
},
|
||||
OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
ParameterCodec: api.ParameterCodec,
|
||||
NegotiatedSerializer: api.Codecs,
|
||||
// stabilize order.
|
||||
// TODO find a better way to configure priority of groups
|
||||
for _, group := range sets.StringKeySet(c.RESTStorageProviders).List() {
|
||||
if !c.APIResourceConfigSource.AnyResourcesForGroupEnabled(group) {
|
||||
continue
|
||||
}
|
||||
if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv2alpha1.SchemeGroupVersion) {
|
||||
batchv2alpha1Resources := m.getBatchResources(c, batchapiv2alpha1.SchemeGroupVersion)
|
||||
apiGroupInfo.VersionedResourcesStorageMap["v2alpha1"] = batchv2alpha1Resources
|
||||
restStorageBuilder := c.RESTStorageProviders[group]
|
||||
apiGroupInfo, enabled := restStorageBuilder(c.APIResourceConfigSource, restOptionsGetter)
|
||||
if !enabled {
|
||||
continue
|
||||
}
|
||||
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
|
||||
}
|
||||
|
||||
if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(policyapiv1alpha1.SchemeGroupVersion) {
|
||||
policyResources := m.getPolicyResources(c)
|
||||
policyGroupMeta := registered.GroupOrDie(policy.GroupName)
|
||||
|
||||
// Hard code preferred group version to policy/v1alpha1
|
||||
policyGroupMeta.GroupVersion = policyapiv1alpha1.SchemeGroupVersion
|
||||
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *policyGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1alpha1": policyResources,
|
||||
},
|
||||
OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
ParameterCodec: api.ParameterCodec,
|
||||
NegotiatedSerializer: api.Codecs,
|
||||
}
|
||||
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
|
||||
}
|
||||
|
||||
if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(appsapi.SchemeGroupVersion) {
|
||||
appsResources := m.getAppsResources(c)
|
||||
appsGroupMeta := registered.GroupOrDie(apps.GroupName)
|
||||
|
||||
// Hard code preferred group version to apps/v1alpha1
|
||||
appsGroupMeta.GroupVersion = appsapi.SchemeGroupVersion
|
||||
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *appsGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1alpha1": appsResources,
|
||||
},
|
||||
OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
ParameterCodec: api.ParameterCodec,
|
||||
NegotiatedSerializer: api.Codecs,
|
||||
}
|
||||
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
|
||||
}
|
||||
|
||||
if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(certificatesapiv1alpha1.SchemeGroupVersion) {
|
||||
certificateResources := m.getCertificateResources(c)
|
||||
certificatesGroupMeta := registered.GroupOrDie(certificates.GroupName)
|
||||
|
||||
// Hard code preferred group version to certificates/v1alpha1
|
||||
certificatesGroupMeta.GroupVersion = certificatesapiv1alpha1.SchemeGroupVersion
|
||||
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *certificatesGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1alpha1": certificateResources,
|
||||
},
|
||||
OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
ParameterCodec: api.ParameterCodec,
|
||||
NegotiatedSerializer: api.Codecs,
|
||||
}
|
||||
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
|
||||
}
|
||||
|
||||
if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(rbacapi.SchemeGroupVersion) {
|
||||
rbacResources := m.getRBACResources(c)
|
||||
rbacGroupMeta := registered.GroupOrDie(rbac.GroupName)
|
||||
|
||||
// Hard code preferred group version to rbac/v1alpha1
|
||||
rbacGroupMeta.GroupVersion = rbacapi.SchemeGroupVersion
|
||||
|
||||
apiGroupInfo := genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *rbacGroupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
|
||||
"v1alpha1": rbacResources,
|
||||
},
|
||||
OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
ParameterCodec: api.ParameterCodec,
|
||||
NegotiatedSerializer: api.Codecs,
|
||||
}
|
||||
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
|
||||
}
|
||||
|
||||
@ -901,116 +810,177 @@ func (m *Master) getExtensionResources(c *Config) map[string]rest.Storage {
|
||||
return storage
|
||||
}
|
||||
|
||||
// getAutoscalingResources returns the resources for autoscaling api
|
||||
func (m *Master) getAutoscalingResources(c *Config) map[string]rest.Storage {
|
||||
// TODO update when we support more than one version of this group
|
||||
version := autoscalingapiv1.SchemeGroupVersion
|
||||
// NewDefaultAPIGroupInfo returns a complete APIGroupInfo stubbed with "normal" values
|
||||
// exposed for easier composition from other packages
|
||||
func NewDefaultAPIGroupInfo(group string) genericapiserver.APIGroupInfo {
|
||||
groupMeta := registered.GroupOrDie(group)
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("horizontalpodautoscalers")) {
|
||||
hpaStorage, hpaStatusStorage := horizontalpodautoscaleretcd.NewREST(m.GetRESTOptionsOrDie(c, autoscaling.Resource("horizontalpodautoscalers")))
|
||||
storage["horizontalpodautoscalers"] = hpaStorage
|
||||
storage["horizontalpodautoscalers/status"] = hpaStatusStorage
|
||||
return genericapiserver.APIGroupInfo{
|
||||
GroupMeta: *groupMeta,
|
||||
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
|
||||
OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion,
|
||||
Scheme: api.Scheme,
|
||||
ParameterCodec: api.ParameterCodec,
|
||||
NegotiatedSerializer: api.Codecs,
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
// getCertificateResources returns the resources for certificates API
|
||||
func (m *Master) getCertificateResources(c *Config) map[string]rest.Storage {
|
||||
restOptions := func(resource string) generic.RESTOptions {
|
||||
return m.GetRESTOptionsOrDie(c, certificates.Resource(resource))
|
||||
func buildCertificateResources(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||
apiGroupInfo := NewDefaultAPIGroupInfo(certificates.GroupName)
|
||||
|
||||
storageForVersion := func(version unversioned.GroupVersion) map[string]rest.Storage {
|
||||
storage := map[string]rest.Storage{}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("certificatesigningrequests")) {
|
||||
csrStorage, csrStatusStorage, csrApprovalStorage := certificateetcd.NewREST(restOptionsGetter(certificates.Resource("certificatesigningrequests")))
|
||||
storage["certificatesigningrequests"] = csrStorage
|
||||
storage["certificatesigningrequests/status"] = csrStatusStorage
|
||||
storage["certificatesigningrequests/approval"] = csrApprovalStorage
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
// TODO update when we support more than one version of this group
|
||||
version := certificatesapiv1alpha1.SchemeGroupVersion
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
csrStorage, csrStatusStorage, csrApprovalStorage := certificateetcd.NewREST(restOptions("certificatesigningrequests"))
|
||||
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("certificatesigningrequests")) {
|
||||
storage["certificatesigningrequests"] = csrStorage
|
||||
storage["certificatesigningrequests/status"] = csrStatusStorage
|
||||
storage["certificatesigningrequests/approval"] = csrApprovalStorage
|
||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(certificatesapiv1alpha1.SchemeGroupVersion) {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[certificatesapiv1alpha1.SchemeGroupVersion.Version] = storageForVersion(certificatesapiv1alpha1.SchemeGroupVersion)
|
||||
apiGroupInfo.GroupMeta.GroupVersion = certificatesapiv1alpha1.SchemeGroupVersion
|
||||
}
|
||||
|
||||
return storage
|
||||
return apiGroupInfo, true
|
||||
}
|
||||
|
||||
// getBatchResources returns the resources for batch api
|
||||
func (m *Master) getBatchResources(c *Config, version unversioned.GroupVersion) map[string]rest.Storage {
|
||||
storage := map[string]rest.Storage{}
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("jobs")) {
|
||||
jobsStorage, jobsStatusStorage := jobetcd.NewREST(m.GetRESTOptionsOrDie(c, batch.Resource("jobs")))
|
||||
storage["jobs"] = jobsStorage
|
||||
storage["jobs/status"] = jobsStatusStorage
|
||||
func buildAutoscalingResources(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||
apiGroupInfo := NewDefaultAPIGroupInfo(autoscaling.GroupName)
|
||||
|
||||
storageForVersion := func(version unversioned.GroupVersion) map[string]rest.Storage {
|
||||
storage := map[string]rest.Storage{}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("horizontalpodautoscalers")) {
|
||||
hpaStorage, hpaStatusStorage := horizontalpodautoscaleretcd.NewREST(restOptionsGetter(autoscaling.Resource("horizontalpodautoscalers")))
|
||||
storage["horizontalpodautoscalers"] = hpaStorage
|
||||
storage["horizontalpodautoscalers/status"] = hpaStatusStorage
|
||||
}
|
||||
return storage
|
||||
}
|
||||
return storage
|
||||
|
||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(autoscalingapiv1.SchemeGroupVersion) {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[autoscalingapiv1.SchemeGroupVersion.Version] = storageForVersion(autoscalingapiv1.SchemeGroupVersion)
|
||||
apiGroupInfo.GroupMeta.GroupVersion = autoscalingapiv1.SchemeGroupVersion
|
||||
}
|
||||
|
||||
return apiGroupInfo, true
|
||||
}
|
||||
|
||||
// getPolicyResources returns the resources for policy api
|
||||
func (m *Master) getPolicyResources(c *Config) map[string]rest.Storage {
|
||||
// TODO update when we support more than one version of this group
|
||||
version := policyapiv1alpha1.SchemeGroupVersion
|
||||
func buildBatchResources(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||
apiGroupInfo := NewDefaultAPIGroupInfo(batch.GroupName)
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("poddisruptionbudgets")) {
|
||||
poddisruptionbudgetStorage, poddisruptionbudgetStatusStorage := poddisruptionbudgetetcd.NewREST(m.GetRESTOptionsOrDie(c, policy.Resource("poddisruptionbudgets")))
|
||||
storage["poddisruptionbudgets"] = poddisruptionbudgetStorage
|
||||
storage["poddisruptionbudgets/status"] = poddisruptionbudgetStatusStorage
|
||||
storageForVersion := func(version unversioned.GroupVersion) map[string]rest.Storage {
|
||||
storage := map[string]rest.Storage{}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("jobs")) {
|
||||
jobsStorage, jobsStatusStorage := jobetcd.NewREST(restOptionsGetter(batch.Resource("jobs")))
|
||||
storage["jobs"] = jobsStorage
|
||||
storage["jobs/status"] = jobsStatusStorage
|
||||
}
|
||||
return storage
|
||||
}
|
||||
return storage
|
||||
|
||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv2alpha1.SchemeGroupVersion) {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[batchapiv2alpha1.SchemeGroupVersion.Version] = storageForVersion(batchapiv2alpha1.SchemeGroupVersion)
|
||||
apiGroupInfo.GroupMeta.GroupVersion = batchapiv2alpha1.SchemeGroupVersion
|
||||
}
|
||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(batchapiv1.SchemeGroupVersion) {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[batchapiv1.SchemeGroupVersion.Version] = storageForVersion(batchapiv1.SchemeGroupVersion)
|
||||
apiGroupInfo.GroupMeta.GroupVersion = batchapiv1.SchemeGroupVersion
|
||||
}
|
||||
|
||||
return apiGroupInfo, true
|
||||
}
|
||||
|
||||
// getAppsResources returns the resources for apps api
|
||||
func (m *Master) getAppsResources(c *Config) map[string]rest.Storage {
|
||||
// TODO update when we support more than one version of this group
|
||||
version := appsapi.SchemeGroupVersion
|
||||
func buildPolicyResources(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||
apiGroupInfo := NewDefaultAPIGroupInfo(policy.GroupName)
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("petsets")) {
|
||||
petsetStorage, petsetStatusStorage := petsetetcd.NewREST(m.GetRESTOptionsOrDie(c, apps.Resource("petsets")))
|
||||
storage["petsets"] = petsetStorage
|
||||
storage["petsets/status"] = petsetStatusStorage
|
||||
storageForVersion := func(version unversioned.GroupVersion) map[string]rest.Storage {
|
||||
storage := map[string]rest.Storage{}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("poddisruptionbudgets")) {
|
||||
poddisruptionbudgetStorage, poddisruptionbudgetStatusStorage := poddisruptionbudgetetcd.NewREST(restOptionsGetter(policy.Resource("poddisruptionbudgets")))
|
||||
storage["poddisruptionbudgets"] = poddisruptionbudgetStorage
|
||||
storage["poddisruptionbudgets/status"] = poddisruptionbudgetStatusStorage
|
||||
}
|
||||
return storage
|
||||
}
|
||||
return storage
|
||||
|
||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(policyapiv1alpha1.SchemeGroupVersion) {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[policyapiv1alpha1.SchemeGroupVersion.Version] = storageForVersion(policyapiv1alpha1.SchemeGroupVersion)
|
||||
apiGroupInfo.GroupMeta.GroupVersion = policyapiv1alpha1.SchemeGroupVersion
|
||||
}
|
||||
|
||||
return apiGroupInfo, true
|
||||
}
|
||||
|
||||
func (m *Master) getRBACResources(c *Config) map[string]rest.Storage {
|
||||
version := rbacapi.SchemeGroupVersion
|
||||
func buildAppsResources(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||
apiGroupInfo := NewDefaultAPIGroupInfo(appsapi.GroupName)
|
||||
|
||||
once := new(sync.Once)
|
||||
var authorizationRuleResolver rbacvalidation.AuthorizationRuleResolver
|
||||
newRuleValidator := func() rbacvalidation.AuthorizationRuleResolver {
|
||||
once.Do(func() {
|
||||
authorizationRuleResolver = rbacvalidation.NewDefaultRuleResolver(
|
||||
role.NewRegistry(roleetcd.NewREST(m.GetRESTOptionsOrDie(c, rbac.Resource("roles")))),
|
||||
rolebinding.NewRegistry(rolebindingetcd.NewREST(m.GetRESTOptionsOrDie(c, rbac.Resource("rolebindings")))),
|
||||
clusterrole.NewRegistry(clusterroleetcd.NewREST(m.GetRESTOptionsOrDie(c, rbac.Resource("clusterroles")))),
|
||||
clusterrolebinding.NewRegistry(clusterrolebindingetcd.NewREST(m.GetRESTOptionsOrDie(c, rbac.Resource("clusterrolebindings")))),
|
||||
)
|
||||
})
|
||||
return authorizationRuleResolver
|
||||
storageForVersion := func(version unversioned.GroupVersion) map[string]rest.Storage {
|
||||
storage := map[string]rest.Storage{}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("petsets")) {
|
||||
petsetStorage, petsetStatusStorage := petsetetcd.NewREST(restOptionsGetter(apps.Resource("petsets")))
|
||||
storage["petsets"] = petsetStorage
|
||||
storage["petsets/status"] = petsetStatusStorage
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("roles")) {
|
||||
rolesStorage := roleetcd.NewREST(m.GetRESTOptionsOrDie(c, rbac.Resource("roles")))
|
||||
storage["roles"] = rolepolicybased.NewStorage(rolesStorage, newRuleValidator(), c.AuthorizerRBACSuperUser)
|
||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(appsapi.SchemeGroupVersion) {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[appsapi.SchemeGroupVersion.Version] = storageForVersion(appsapi.SchemeGroupVersion)
|
||||
apiGroupInfo.GroupMeta.GroupVersion = appsapi.SchemeGroupVersion
|
||||
}
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("rolebindings")) {
|
||||
roleBindingsStorage := rolebindingetcd.NewREST(m.GetRESTOptionsOrDie(c, rbac.Resource("rolebindings")))
|
||||
storage["rolebindings"] = rolebindingpolicybased.NewStorage(roleBindingsStorage, newRuleValidator(), c.AuthorizerRBACSuperUser)
|
||||
|
||||
return apiGroupInfo, true
|
||||
}
|
||||
|
||||
func buildRBACResources(authorizerRBACSuperUser string) RESTStorageProvider {
|
||||
return func(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
|
||||
apiGroupInfo := NewDefaultAPIGroupInfo(rbac.GroupName)
|
||||
|
||||
storageForVersion := func(version unversioned.GroupVersion) map[string]rest.Storage {
|
||||
once := new(sync.Once)
|
||||
var authorizationRuleResolver rbacvalidation.AuthorizationRuleResolver
|
||||
newRuleValidator := func() rbacvalidation.AuthorizationRuleResolver {
|
||||
once.Do(func() {
|
||||
authorizationRuleResolver = rbacvalidation.NewDefaultRuleResolver(
|
||||
role.NewRegistry(roleetcd.NewREST(restOptionsGetter(rbac.Resource("roles")))),
|
||||
rolebinding.NewRegistry(rolebindingetcd.NewREST(restOptionsGetter(rbac.Resource("rolebindings")))),
|
||||
clusterrole.NewRegistry(clusterroleetcd.NewREST(restOptionsGetter(rbac.Resource("clusterroles")))),
|
||||
clusterrolebinding.NewRegistry(clusterrolebindingetcd.NewREST(restOptionsGetter(rbac.Resource("clusterrolebindings")))),
|
||||
)
|
||||
})
|
||||
return authorizationRuleResolver
|
||||
}
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("roles")) {
|
||||
rolesStorage := roleetcd.NewREST(restOptionsGetter(rbac.Resource("roles")))
|
||||
storage["roles"] = rolepolicybased.NewStorage(rolesStorage, newRuleValidator(), authorizerRBACSuperUser)
|
||||
}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("rolebindings")) {
|
||||
roleBindingsStorage := rolebindingetcd.NewREST(restOptionsGetter(rbac.Resource("rolebindings")))
|
||||
storage["rolebindings"] = rolebindingpolicybased.NewStorage(roleBindingsStorage, newRuleValidator(), authorizerRBACSuperUser)
|
||||
}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("clusterroles")) {
|
||||
clusterRolesStorage := clusterroleetcd.NewREST(restOptionsGetter(rbac.Resource("clusterroles")))
|
||||
storage["clusterroles"] = clusterrolepolicybased.NewStorage(clusterRolesStorage, newRuleValidator(), authorizerRBACSuperUser)
|
||||
}
|
||||
if apiResourceConfigSource.ResourceEnabled(version.WithResource("clusterrolebindings")) {
|
||||
clusterRoleBindingsStorage := clusterrolebindingetcd.NewREST(restOptionsGetter(rbac.Resource("clusterrolebindings")))
|
||||
storage["clusterrolebindings"] = clusterrolebindingpolicybased.NewStorage(clusterRoleBindingsStorage, newRuleValidator(), authorizerRBACSuperUser)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
if apiResourceConfigSource.AnyResourcesForVersionEnabled(rbacapi.SchemeGroupVersion) {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[rbacapi.SchemeGroupVersion.Version] = storageForVersion(rbacapi.SchemeGroupVersion)
|
||||
apiGroupInfo.GroupMeta.GroupVersion = rbacapi.SchemeGroupVersion
|
||||
}
|
||||
|
||||
return apiGroupInfo, true
|
||||
}
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("clusterroles")) {
|
||||
clusterRolesStorage := clusterroleetcd.NewREST(m.GetRESTOptionsOrDie(c, rbac.Resource("clusterroles")))
|
||||
storage["clusterroles"] = clusterrolepolicybased.NewStorage(clusterRolesStorage, newRuleValidator(), c.AuthorizerRBACSuperUser)
|
||||
}
|
||||
if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("clusterrolebindings")) {
|
||||
clusterRoleBindingsStorage := clusterrolebindingetcd.NewREST(m.GetRESTOptionsOrDie(c, rbac.Resource("clusterrolebindings")))
|
||||
storage["clusterrolebindings"] = clusterrolebindingpolicybased.NewStorage(clusterRoleBindingsStorage, newRuleValidator(), c.AuthorizerRBACSuperUser)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
// findExternalAddress returns ExternalIP of provided node with fallback to LegacyHostIP.
|
||||
@ -1065,7 +1035,16 @@ func (m *Master) IsTunnelSyncHealthy(req *http.Request) error {
|
||||
|
||||
func DefaultAPIResourceConfigSource() *genericapiserver.ResourceConfig {
|
||||
ret := genericapiserver.NewResourceConfig()
|
||||
ret.EnableVersions(apiv1.SchemeGroupVersion, extensionsapiv1beta1.SchemeGroupVersion, batchapiv1.SchemeGroupVersion, autoscalingapiv1.SchemeGroupVersion, appsapi.SchemeGroupVersion, policyapiv1alpha1.SchemeGroupVersion, rbacapi.SchemeGroupVersion, certificatesapiv1alpha1.SchemeGroupVersion)
|
||||
ret.EnableVersions(
|
||||
apiv1.SchemeGroupVersion,
|
||||
extensionsapiv1beta1.SchemeGroupVersion,
|
||||
batchapiv1.SchemeGroupVersion,
|
||||
autoscalingapiv1.SchemeGroupVersion,
|
||||
appsapi.SchemeGroupVersion,
|
||||
policyapiv1alpha1.SchemeGroupVersion,
|
||||
rbacapi.SchemeGroupVersion,
|
||||
certificatesapiv1alpha1.SchemeGroupVersion,
|
||||
)
|
||||
|
||||
// all extensions resources except these are disabled by default
|
||||
ret.EnableResources(
|
||||
|
@ -136,9 +136,14 @@ func newMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *ass
|
||||
// limitedAPIResourceConfigSource only enables the core group, the extensions group, the batch group, and the autoscaling group.
|
||||
func limitedAPIResourceConfigSource() *genericapiserver.ResourceConfig {
|
||||
ret := genericapiserver.NewResourceConfig()
|
||||
ret.EnableVersions(apiv1.SchemeGroupVersion, extensionsapiv1beta1.SchemeGroupVersion,
|
||||
batchapiv1.SchemeGroupVersion, batchapiv2alpha1.SchemeGroupVersion,
|
||||
appsapi.SchemeGroupVersion, autoscalingapiv1.SchemeGroupVersion)
|
||||
ret.EnableVersions(
|
||||
apiv1.SchemeGroupVersion,
|
||||
extensionsapiv1beta1.SchemeGroupVersion,
|
||||
batchapiv1.SchemeGroupVersion,
|
||||
batchapiv2alpha1.SchemeGroupVersion,
|
||||
appsapi.SchemeGroupVersion,
|
||||
autoscalingapiv1.SchemeGroupVersion,
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
@ -493,7 +498,7 @@ func TestDiscoveryAtAPIS(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
assert.Equal(3, len(groupList.Groups))
|
||||
assert.Equal(4, len(groupList.Groups))
|
||||
for _, group := range groupList.Groups {
|
||||
if !expectGroupNames.Has(group.Name) {
|
||||
t.Errorf("got unexpected group %s", group.Name)
|
||||
@ -520,7 +525,7 @@ func TestDiscoveryAtAPIS(t *testing.T) {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
assert.Equal(4, len(groupList.Groups))
|
||||
assert.Equal(5, len(groupList.Groups))
|
||||
|
||||
expectGroupNames.Insert("company.com")
|
||||
expectVersions["company.com"] = []unversioned.GroupVersionForDiscovery{thirdPartyGV}
|
||||
|
Loading…
Reference in New Issue
Block a user