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:
k8s-merge-robot 2016-07-25 10:25:30 -07:00 committed by GitHub
commit 27bb99d41e
5 changed files with 283 additions and 225 deletions

View File

@ -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"

View File

@ -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
}

View File

@ -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)
}
}
}

View File

@ -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: &registered.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: &registered.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: &registered.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: &registered.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: &registered.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: &registered.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: &registered.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(

View File

@ -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}