Merge pull request #63364 from deads2k/api-16-scheme

Automatic merge from submit-queue (batch tested with PRs 63364, 63464). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

simplify api registration

The current registration and groupmeta is only use to determine a preferred ordering to versions.  The scheme already knows about all versions, so this simply makes that knowledge official.  After doing that, the announce, registered, and apimachinery/pkg/apimachinery all drop out.

With this change we'll be able to create `install` packages for each external apigroup that accept a scheme and have suggested orderings.  This will make it possible to close the consistency gap with kubectl, client, and apiserver.

@kubernetes/sig-api-machinery-pr-reviews
@lavalamp @smarterclayton @liggitt @sttts

```release-note
NONE
```

Kubernetes-commit: f929502282b370ceb3adae4816074142d6702c8b
This commit is contained in:
Kubernetes Publisher 2018-05-08 18:36:10 -07:00
commit 842a38c082
20 changed files with 338 additions and 453 deletions

470
Godeps/Godeps.json generated

File diff suppressed because it is too large Load Diff

View File

@ -19,25 +19,15 @@ limitations under the License.
package install
import (
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission"
"k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1"
)
// Install registers the API group and adds types to a scheme
func Install(registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: webhookadmission.GroupName,
VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version},
AddInternalObjectsToScheme: webhookadmission.AddToScheme,
},
announced.VersionToSchemeFunc{
v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme,
},
).Register(registry, scheme); err != nil {
panic(err)
}
func Install(scheme *runtime.Scheme) {
utilruntime.Must(webhookadmission.AddToScheme(scheme))
utilruntime.Must(v1alpha1.AddToScheme(scheme))
utilruntime.Must(scheme.SetVersionPriority(v1alpha1.SchemeGroupVersion))
}

View File

@ -17,25 +17,15 @@ limitations under the License.
package install
import (
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/apis/apiserver"
"k8s.io/apiserver/pkg/apis/apiserver/v1alpha1"
)
// Install registers the API group and adds types to a scheme
func Install(registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: apiserver.GroupName,
VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version},
AddInternalObjectsToScheme: apiserver.AddToScheme,
},
announced.VersionToSchemeFunc{
v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme,
},
).Register(registry, scheme); err != nil {
panic(err)
}
func Install(scheme *runtime.Scheme) {
utilruntime.Must(apiserver.AddToScheme(scheme))
utilruntime.Must(v1alpha1.AddToScheme(scheme))
utilruntime.Must(scheme.SetVersionPriority(v1alpha1.SchemeGroupVersion))
}

View File

@ -19,27 +19,17 @@ limitations under the License.
package install
import (
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/apis/audit"
"k8s.io/apiserver/pkg/apis/audit/v1alpha1"
"k8s.io/apiserver/pkg/apis/audit/v1beta1"
)
// Install registers the API group and adds types to a scheme
func Install(registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: audit.GroupName,
VersionPreferenceOrder: []string{v1beta1.SchemeGroupVersion.Version, v1alpha1.SchemeGroupVersion.Version},
AddInternalObjectsToScheme: audit.AddToScheme,
},
announced.VersionToSchemeFunc{
v1beta1.SchemeGroupVersion.Version: v1beta1.AddToScheme,
v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme,
},
).Register(registry, scheme); err != nil {
panic(err)
}
func Install(scheme *runtime.Scheme) {
utilruntime.Must(audit.AddToScheme(scheme))
utilruntime.Must(v1beta1.AddToScheme(scheme))
utilruntime.Must(v1alpha1.AddToScheme(scheme))
utilruntime.Must(scheme.SetVersionPriority(v1beta1.SchemeGroupVersion, v1alpha1.SchemeGroupVersion))
}

View File

@ -19,25 +19,15 @@ limitations under the License.
package install
import (
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/apis/example"
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
)
// Install registers the API group and adds types to a scheme
func Install(registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: example.GroupName,
VersionPreferenceOrder: []string{examplev1.SchemeGroupVersion.Version},
AddInternalObjectsToScheme: example.AddToScheme,
},
announced.VersionToSchemeFunc{
examplev1.SchemeGroupVersion.Version: examplev1.AddToScheme,
},
).Register(registry, scheme); err != nil {
panic(err)
}
func Install(scheme *runtime.Scheme) {
utilruntime.Must(example.AddToScheme(scheme))
utilruntime.Must(examplev1.AddToScheme(scheme))
utilruntime.Must(scheme.SetVersionPriority(examplev1.SchemeGroupVersion))
}

View File

@ -19,26 +19,15 @@ limitations under the License.
package install
import (
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/apis/example"
"k8s.io/apiserver/pkg/apis/example2"
example2v1 "k8s.io/apiserver/pkg/apis/example2/v1"
)
// Install registers the API group and adds types to a scheme
func Install(registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: example2.GroupName,
VersionPreferenceOrder: []string{example2v1.SchemeGroupVersion.Version},
AddInternalObjectsToScheme: example.AddToScheme,
},
announced.VersionToSchemeFunc{
example2v1.SchemeGroupVersion.Version: example2v1.AddToScheme,
},
).Register(registry, scheme); err != nil {
panic(err)
}
func Install(scheme *runtime.Scheme) {
utilruntime.Must(example.AddToScheme(scheme))
utilruntime.Must(example2v1.AddToScheme(scheme))
utilruntime.Must(scheme.SetVersionPriority(example2v1.SchemeGroupVersion))
}

View File

@ -26,7 +26,6 @@ import (
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apimachinery/registered"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -37,9 +36,8 @@ import (
)
var (
registry = registered.NewAPIRegistrationManager()
scheme = runtime.NewScheme()
codecs = serializer.NewCodecFactory(scheme)
scheme = runtime.NewScheme()
codecs = serializer.NewCodecFactory(scheme)
)
func init() {

View File

@ -28,8 +28,6 @@ import (
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apimachinery"
"k8s.io/apimachinery/pkg/apimachinery/registered"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -49,7 +47,7 @@ import (
// Info about an API group.
type APIGroupInfo struct {
GroupMeta apimachinery.GroupMeta
PrioritizedVersions []schema.GroupVersion
// Info about the resources in this group. Its a map from version to resource to the storage.
VersionedResourcesStorageMap map[string]map[string]rest.Storage
// OptionsExternalVersion controls the APIVersion used for common objects in the
@ -316,7 +314,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error {
// installAPIResources is a private method for installing the REST storage backing each api groupversionresource
func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo) error {
for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions {
for _, groupVersion := range apiGroupInfo.PrioritizedVersions {
if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 {
glog.Warningf("Skipping API %v because it has no resources.", groupVersion)
continue
@ -345,7 +343,7 @@ func (s *GenericAPIServer) InstallLegacyAPIGroup(apiPrefix string, apiGroupInfo
// setup discovery
apiVersions := []string{}
for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions {
for _, groupVersion := range apiGroupInfo.PrioritizedVersions {
apiVersions = append(apiVersions, groupVersion.Version)
}
// Install the version handler.
@ -359,10 +357,10 @@ func (s *GenericAPIServer) InstallLegacyAPIGroup(apiPrefix string, apiGroupInfo
func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
// Do not register empty group or empty version. Doing so claims /apis/ for the wrong entity to be returned.
// Catching these here places the error much closer to its origin
if len(apiGroupInfo.GroupMeta.GroupVersions[0].Group) == 0 {
if len(apiGroupInfo.PrioritizedVersions[0].Group) == 0 {
return fmt.Errorf("cannot register handler with an empty group for %#v", *apiGroupInfo)
}
if len(apiGroupInfo.GroupMeta.GroupVersions[0].Version) == 0 {
if len(apiGroupInfo.PrioritizedVersions[0].Version) == 0 {
return fmt.Errorf("cannot register handler with an empty version for %#v", *apiGroupInfo)
}
@ -374,7 +372,7 @@ func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
// Install the version handler.
// Add a handler at /apis/<groupName> to enumerate all versions supported by this group.
apiVersionsForDiscovery := []metav1.GroupVersionForDiscovery{}
for _, groupVersion := range apiGroupInfo.GroupMeta.GroupVersions {
for _, groupVersion := range apiGroupInfo.PrioritizedVersions {
// Check the config to make sure that we elide versions that don't have any resources
if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 {
continue
@ -385,11 +383,11 @@ func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
})
}
preferredVersionForDiscovery := metav1.GroupVersionForDiscovery{
GroupVersion: apiGroupInfo.GroupMeta.GroupVersions[0].String(),
Version: apiGroupInfo.GroupMeta.GroupVersions[0].Version,
GroupVersion: apiGroupInfo.PrioritizedVersions[0].String(),
Version: apiGroupInfo.PrioritizedVersions[0].Version,
}
apiGroup := metav1.APIGroup{
Name: apiGroupInfo.GroupMeta.GroupVersions[0].Group,
Name: apiGroupInfo.PrioritizedVersions[0].Group,
Versions: apiVersionsForDiscovery,
PreferredVersion: preferredVersionForDiscovery,
}
@ -433,11 +431,9 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
// NewDefaultAPIGroupInfo returns an APIGroupInfo stubbed with "normal" values
// exposed for easier composition from other packages
func NewDefaultAPIGroupInfo(group string, registry *registered.APIRegistrationManager, scheme *runtime.Scheme, parameterCodec runtime.ParameterCodec, codecs serializer.CodecFactory) APIGroupInfo {
groupMeta := registry.GroupOrDie(group)
func NewDefaultAPIGroupInfo(group string, scheme *runtime.Scheme, parameterCodec runtime.ParameterCodec, codecs serializer.CodecFactory) APIGroupInfo {
return APIGroupInfo{
GroupMeta: *groupMeta,
PrioritizedVersions: scheme.PrioritizedVersionsForGroup(group),
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
// TODO unhardcode this. It was hardcoded before, but we need to re-evaluate
OptionsExternalVersion: &schema.GroupVersion{Version: "v1"},

View File

@ -34,7 +34,6 @@ import (
// "github.com/go-openapi/spec"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apimachinery"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -151,12 +150,8 @@ func TestInstallAPIGroups(t *testing.T) {
scheme.AddKnownTypes(v1GroupVersion, &metav1.Status{})
metav1.AddToGroupVersion(scheme, v1GroupVersion)
groupMeta := apimachinery.GroupMeta{
GroupVersions: []schema.GroupVersion{gv},
}
return APIGroupInfo{
GroupMeta: groupMeta,
PrioritizedVersions: []schema.GroupVersion{gv},
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
gv.Version: {
"getter": &testGetterStorage{Version: gv.Version},
@ -184,7 +179,7 @@ func TestInstallAPIGroups(t *testing.T) {
for _, api := range apis[1:] {
err = s.InstallAPIGroup(&api)
assert.NoError(err)
groupPaths = append(groupPaths, APIGroupPrefix+"/"+api.GroupMeta.GroupVersions[0].Group) // /apis/<group>
groupPaths = append(groupPaths, APIGroupPrefix+"/"+api.PrioritizedVersions[0].Group) // /apis/<group>
}
server := httptest.NewServer(s.Handler)
@ -225,19 +220,19 @@ func TestInstallAPIGroups(t *testing.T) {
continue
}
if got, expected := group.Name, info.GroupMeta.GroupVersions[0].Group; got != expected {
if got, expected := group.Name, info.PrioritizedVersions[0].Group; got != expected {
t.Errorf("[%d] unexpected group name at path %q: got=%q expected=%q", i, path, got, expected)
continue
}
if got, expected := group.PreferredVersion.Version, info.GroupMeta.GroupVersions[0].Version; got != expected {
if got, expected := group.PreferredVersion.Version, info.PrioritizedVersions[0].Version; got != expected {
t.Errorf("[%d] unexpected group version at path %q: got=%q expected=%q", i, path, got, expected)
continue
}
}
// should serve APIResourceList at group path + /<group-version>
path = path + "/" + info.GroupMeta.GroupVersions[0].Version
path = path + "/" + info.PrioritizedVersions[0].Version
resp, err = http.Get(server.URL + path)
if err != nil {
t.Errorf("[%d] unexpected error getting path %q path: %v", i, path, err)
@ -259,7 +254,7 @@ func TestInstallAPIGroups(t *testing.T) {
continue
}
if got, expected := resources.GroupVersion, info.GroupMeta.GroupVersions[0].String(); got != expected {
if got, expected := resources.GroupVersion, info.PrioritizedVersions[0].String(); got != expected {
t.Errorf("[%d] unexpected groupVersion at path %q: got=%q expected=%q", i, path, got, expected)
continue
}

View File

@ -97,7 +97,7 @@ func (s *APIEnablementOptions) ApplyTo(c *server.Config, defaultResourceConfig *
func unknownGroups(groups []string, registry GroupRegisty) []string {
unknownGroups := []string{}
for _, group := range groups {
if !registry.IsRegistered(group) {
if !registry.IsGroupRegistered(group) {
unknownGroups = append(unknownGroups, group)
}
}
@ -107,5 +107,5 @@ func unknownGroups(groups []string, registry GroupRegisty) []string {
// GroupRegisty provides a method to check whether given group is registered.
type GroupRegisty interface {
// IsRegistered returns true if given group is registered.
IsRegistered(group string) bool
IsGroupRegistered(group string) bool
}

View File

@ -29,12 +29,12 @@ import (
// GroupVersionRegistry provides access to registered group versions.
type GroupVersionRegistry interface {
// IsRegistered returns true if given group is registered.
IsRegistered(group string) bool
// IsRegisteredVersion returns true if given version is registered.
IsRegisteredVersion(v schema.GroupVersion) bool
// RegisteredGroupVersions returns all registered group versions.
RegisteredGroupVersions() []schema.GroupVersion
// IsGroupRegistered returns true if given group is registered.
IsGroupRegistered(group string) bool
// IsVersionRegistered returns true if given version is registered.
IsVersionRegistered(v schema.GroupVersion) bool
// PrioritizedVersionsAllGroups returns all registered group versions.
PrioritizedVersionsAllGroups() []schema.GroupVersion
}
// MergeResourceEncodingConfigs merges the given defaultResourceConfig with specific GroupVersionResource overrides.
@ -104,12 +104,12 @@ func MergeAPIResourceConfigs(
}
// Exclude group not registered into the registry.
if !registry.IsRegistered(groupVersion.Group) {
if !registry.IsGroupRegistered(groupVersion.Group) {
continue
}
// Verify that the groupVersion is registered into registry.
if !registry.IsRegisteredVersion(groupVersion) {
if !registry.IsVersionRegistered(groupVersion) {
return nil, fmt.Errorf("group version %s that has not been registered", groupVersion.String())
}
enabled, err := getRuntimeConfigValue(overrides, key, false)

View File

@ -22,14 +22,12 @@ import (
apiv1 "k8s.io/api/core/v1"
extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/apimachinery"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime"
serverstore "k8s.io/apiserver/pkg/server/storage"
)
func TestParseRuntimeConfig(t *testing.T) {
registry := newFakeRegistry()
scheme := newFakeScheme()
apiv1GroupVersion := apiv1.SchemeGroupVersion
testCases := []struct {
runtimeConfig map[string]string
@ -116,7 +114,7 @@ func TestParseRuntimeConfig(t *testing.T) {
},
expectedAPIConfig: func() *serverstore.ResourceConfig {
config := newFakeAPIResourceConfigSource()
config.EnableVersions(registry.RegisteredGroupVersions()...)
config.EnableVersions(scheme.PrioritizedVersionsAllGroups()...)
return config
},
err: false,
@ -139,8 +137,8 @@ func TestParseRuntimeConfig(t *testing.T) {
},
}
for index, test := range testCases {
t.Log(registry.RegisteredGroupVersions())
actualDisablers, err := MergeAPIResourceConfigs(test.defaultResourceConfig(), test.runtimeConfig, registry)
t.Log(scheme.PrioritizedVersionsAllGroups())
actualDisablers, err := MergeAPIResourceConfigs(test.defaultResourceConfig(), test.runtimeConfig, scheme)
if err == nil && test.err {
t.Fatalf("expected error for test case: %v", index)
} else if err != nil && !test.err {
@ -165,15 +163,13 @@ func newFakeAPIResourceConfigSource() *serverstore.ResourceConfig {
return ret
}
func newFakeRegistry() *registered.APIRegistrationManager {
registry := registered.NewAPIRegistrationManager()
func newFakeScheme() *runtime.Scheme {
ret := runtime.NewScheme()
apiv1.AddToScheme(ret)
extensionsapiv1beta1.AddToScheme(ret)
registry.RegisterGroup(apimachinery.GroupMeta{
GroupVersions: []schema.GroupVersion{apiv1.SchemeGroupVersion},
})
registry.RegisterGroup(apimachinery.GroupMeta{
GroupVersions: []schema.GroupVersion{extensionsapiv1beta1.SchemeGroupVersion},
})
registry.RegisterVersions([]schema.GroupVersion{apiv1.SchemeGroupVersion, extensionsapiv1beta1.SchemeGroupVersion})
return registry
ret.SetVersionPriority(apiv1.SchemeGroupVersion)
ret.SetVersionPriority(extensionsapiv1beta1.SchemeGroupVersion)
return ret
}

View File

@ -17,7 +17,8 @@ limitations under the License.
package storage
import (
"k8s.io/apimachinery/pkg/apimachinery/registered"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
@ -33,8 +34,8 @@ type ResourceEncodingConfig interface {
}
type DefaultResourceEncodingConfig struct {
groups map[string]*GroupResourceEncodingConfig
registry *registered.APIRegistrationManager
groups map[string]*GroupResourceEncodingConfig
scheme *runtime.Scheme
}
type GroupResourceEncodingConfig struct {
@ -47,8 +48,8 @@ type GroupResourceEncodingConfig struct {
var _ ResourceEncodingConfig = &DefaultResourceEncodingConfig{}
func NewDefaultResourceEncodingConfig(registry *registered.APIRegistrationManager) *DefaultResourceEncodingConfig {
return &DefaultResourceEncodingConfig{groups: map[string]*GroupResourceEncodingConfig{}, registry: registry}
func NewDefaultResourceEncodingConfig(scheme *runtime.Scheme) *DefaultResourceEncodingConfig {
return &DefaultResourceEncodingConfig{groups: map[string]*GroupResourceEncodingConfig{}, scheme: scheme}
}
func newGroupResourceEncodingConfig(defaultEncoding, defaultInternalVersion schema.GroupVersion) *GroupResourceEncodingConfig {
@ -80,16 +81,15 @@ func (o *DefaultResourceEncodingConfig) SetResourceEncoding(resourceBeingStored
}
func (o *DefaultResourceEncodingConfig) StorageEncodingFor(resource schema.GroupResource) (schema.GroupVersion, error) {
groupMeta, err := o.registry.Group(resource.Group)
if err != nil {
return schema.GroupVersion{}, err
if !o.scheme.IsGroupRegistered(resource.Group) {
return schema.GroupVersion{}, fmt.Errorf("group %q is not registered in scheme", resource.Group)
}
groupEncoding, groupExists := o.groups[resource.Group]
if !groupExists {
// return the most preferred external version for the group
return groupMeta.GroupVersions[0], nil
return o.scheme.PrioritizedVersionsForGroup(resource.Group)[0], nil
}
resourceOverride, resourceExists := groupEncoding.ExternalResourceEncodings[resource.Resource]
@ -101,8 +101,8 @@ func (o *DefaultResourceEncodingConfig) StorageEncodingFor(resource schema.Group
}
func (o *DefaultResourceEncodingConfig) InMemoryEncodingFor(resource schema.GroupResource) (schema.GroupVersion, error) {
if _, err := o.registry.Group(resource.Group); err != nil {
return schema.GroupVersion{}, err
if !o.scheme.IsGroupRegistered(resource.Group) {
return schema.GroupVersion{}, fmt.Errorf("group %q is not registered in scheme", resource.Group)
}
groupEncoding, groupExists := o.groups[resource.Group]

View File

@ -20,7 +20,6 @@ import (
"reflect"
"testing"
"k8s.io/apimachinery/pkg/apimachinery/registered"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -34,7 +33,6 @@ import (
var (
v1GroupVersion = schema.GroupVersion{Group: "", Version: "v1"}
registry = registered.NewAPIRegistrationManager()
scheme = runtime.NewScheme()
codecs = serializer.NewCodecFactory(scheme)
parameterCodec = runtime.NewParameterCodec(scheme)
@ -50,7 +48,7 @@ func init() {
&metav1.APIResourceList{},
)
exampleinstall.Install(registry, scheme)
exampleinstall.Install(scheme)
}
type fakeNegotiater struct {
@ -91,7 +89,7 @@ func (n *fakeNegotiater) DecoderToVersion(serializer runtime.Decoder, gv runtime
func TestConfigurableStorageFactory(t *testing.T) {
ns := &fakeNegotiater{types: []string{"test/test"}}
f := NewDefaultStorageFactory(storagebackend.Config{}, "test/test", ns, NewDefaultResourceEncodingConfig(registry), NewResourceConfig(), nil)
f := NewDefaultStorageFactory(storagebackend.Config{}, "test/test", ns, NewDefaultResourceEncodingConfig(scheme), NewResourceConfig(), nil)
f.AddCohabitatingResources(example.Resource("test"), schema.GroupResource{Resource: "test2", Group: "2"})
called := false
testEncoderChain := func(e runtime.Encoder) runtime.Encoder {
@ -115,8 +113,7 @@ func TestConfigurableStorageFactory(t *testing.T) {
}
func TestUpdateEtcdOverrides(t *testing.T) {
registry := registered.NewAPIRegistrationManager()
exampleinstall.Install(registry, scheme)
exampleinstall.Install(scheme)
testCases := []struct {
resource schema.GroupResource
@ -142,7 +139,7 @@ func TestUpdateEtcdOverrides(t *testing.T) {
Prefix: "/registry",
ServerList: defaultEtcdLocation,
}
storageFactory := NewDefaultStorageFactory(defaultConfig, "", codecs, NewDefaultResourceEncodingConfig(registry), NewResourceConfig(), nil)
storageFactory := NewDefaultStorageFactory(defaultConfig, "", codecs, NewDefaultResourceEncodingConfig(scheme), NewResourceConfig(), nil)
storageFactory.SetEtcdLocation(test.resource, test.servers)
var err error

View File

@ -22,7 +22,6 @@ import (
"time"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
@ -42,13 +41,13 @@ type GenericWebhook struct {
}
// NewGenericWebhook creates a new GenericWebhook from the provided kubeconfig file.
func NewGenericWebhook(registry *registered.APIRegistrationManager, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff time.Duration) (*GenericWebhook, error) {
return newGenericWebhook(registry, codecFactory, kubeConfigFile, groupVersions, initialBackoff, defaultRequestTimeout)
func NewGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff time.Duration) (*GenericWebhook, error) {
return newGenericWebhook(scheme, codecFactory, kubeConfigFile, groupVersions, initialBackoff, defaultRequestTimeout)
}
func newGenericWebhook(registry *registered.APIRegistrationManager, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff, requestTimeout time.Duration) (*GenericWebhook, error) {
func newGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff, requestTimeout time.Duration) (*GenericWebhook, error) {
for _, groupVersion := range groupVersions {
if !registry.IsRegisteredVersion(groupVersion) {
if !scheme.IsVersionRegistered(groupVersion) {
return nil, fmt.Errorf("webhook plugin requires enabling extension resource: %s", groupVersion)
}
}

View File

@ -32,7 +32,7 @@ import (
"time"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
@ -258,7 +258,7 @@ func TestKubeConfigFile(t *testing.T) {
if err == nil {
defer os.Remove(kubeConfigFile)
_, err = NewGenericWebhook(registered.NewAPIRegistrationManager(), scheme.Codecs, kubeConfigFile, groupVersions, retryBackoff)
_, err = NewGenericWebhook(runtime.NewScheme(), scheme.Codecs, kubeConfigFile, groupVersions, retryBackoff)
}
return err
@ -281,7 +281,7 @@ func TestKubeConfigFile(t *testing.T) {
// TestMissingKubeConfigFile ensures that a kube config path to a missing file is handled properly
func TestMissingKubeConfigFile(t *testing.T) {
kubeConfigPath := "/some/missing/path"
_, err := NewGenericWebhook(registered.NewAPIRegistrationManager(), scheme.Codecs, kubeConfigPath, groupVersions, retryBackoff)
_, err := NewGenericWebhook(runtime.NewScheme(), scheme.Codecs, kubeConfigPath, groupVersions, retryBackoff)
if err == nil {
t.Errorf("creating the webhook should had failed")
@ -393,7 +393,7 @@ func TestTLSConfig(t *testing.T) {
defer os.Remove(configFile)
wh, err := NewGenericWebhook(registered.NewAPIRegistrationManager(), scheme.Codecs, configFile, groupVersions, retryBackoff)
wh, err := NewGenericWebhook(runtime.NewScheme(), scheme.Codecs, configFile, groupVersions, retryBackoff)
if err == nil {
err = wh.RestClient.Get().Do().Error()
@ -458,7 +458,7 @@ func TestRequestTimeout(t *testing.T) {
var requestTimeout = 10 * time.Millisecond
wh, err := newGenericWebhook(registered.NewAPIRegistrationManager(), scheme.Codecs, configFile, groupVersions, retryBackoff, requestTimeout)
wh, err := newGenericWebhook(runtime.NewScheme(), scheme.Codecs, configFile, groupVersions, retryBackoff, requestTimeout)
if err != nil {
t.Fatalf("failed to create the webhook: %v", err)
}
@ -544,7 +544,7 @@ func TestWithExponentialBackoff(t *testing.T) {
defer os.Remove(configFile)
wh, err := NewGenericWebhook(registered.NewAPIRegistrationManager(), scheme.Codecs, configFile, groupVersions, retryBackoff)
wh, err := NewGenericWebhook(runtime.NewScheme(), scheme.Codecs, configFile, groupVersions, retryBackoff)
if err != nil {
t.Fatalf("failed to create the webhook: %v", err)

View File

@ -25,10 +25,8 @@ import (
"github.com/pborman/uuid"
"k8s.io/apimachinery/pkg/apimachinery/registered"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
auditinternal "k8s.io/apiserver/pkg/apis/audit"
"k8s.io/apiserver/pkg/apis/audit/install"
@ -36,15 +34,8 @@ import (
"k8s.io/apiserver/pkg/audit"
)
// NOTE: Copied from webhook backend to register auditv1beta1 to scheme
var (
registry = registered.NewAPIRegistrationManager()
)
func init() {
allGVs := []schema.GroupVersion{auditv1beta1.SchemeGroupVersion}
registry.RegisterVersions(allGVs)
install.Install(registry, audit.Scheme)
install.Install(audit.Scheme)
}
func TestLogEventsLegacy(t *testing.T) {

View File

@ -20,12 +20,9 @@ package webhook
import (
"time"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime/schema"
auditinternal "k8s.io/apiserver/pkg/apis/audit"
"k8s.io/apiserver/pkg/apis/audit/install"
auditv1alpha1 "k8s.io/apiserver/pkg/apis/audit/v1alpha1"
auditv1beta1 "k8s.io/apiserver/pkg/apis/audit/v1beta1"
"k8s.io/apiserver/pkg/audit"
"k8s.io/apiserver/pkg/util/webhook"
"k8s.io/client-go/rest"
@ -40,22 +37,12 @@ const (
DefaultInitialBackoff = 10 * time.Second
)
var (
// NOTE: Copied from other webhook implementations
//
// Can we make these passable to NewGenericWebhook?
// TODO(audit): figure out a general way to let the client choose their preferred version
registry = registered.NewAPIRegistrationManager()
)
func init() {
allGVs := []schema.GroupVersion{auditv1alpha1.SchemeGroupVersion, auditv1beta1.SchemeGroupVersion}
registry.RegisterVersions(allGVs)
install.Install(registry, audit.Scheme)
install.Install(audit.Scheme)
}
func loadWebhook(configFile string, groupVersion schema.GroupVersion, initialBackoff time.Duration) (*webhook.GenericWebhook, error) {
return webhook.NewGenericWebhook(registry, audit.Codecs, configFile,
return webhook.NewGenericWebhook(audit.Scheme, audit.Codecs, configFile,
[]schema.GroupVersion{groupVersion}, initialBackoff)
}

View File

@ -23,9 +23,10 @@ import (
"github.com/golang/glog"
authentication "k8s.io/api/authentication/v1beta1"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/cache"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/util/webhook"
@ -112,21 +113,15 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(token string) (user.Info,
}, true, nil
}
// NOTE: client-go doesn't provide a registry. client-go does registers the
// authentication/v1beta1. We construct a registry that acknowledges
// authentication/v1beta1 as an enabled version to pass a check enforced in
// NewGenericWebhook.
var registry = registered.NewAPIRegistrationManager()
func init() {
registry.RegisterVersions(groupVersions)
}
// tokenReviewInterfaceFromKubeconfig builds a client from the specified kubeconfig file,
// and returns a TokenReviewInterface that uses that client. Note that the client submits TokenReview
// requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted.
func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string) (authenticationclient.TokenReviewInterface, error) {
gw, err := webhook.NewGenericWebhook(registry, scheme.Codecs, kubeConfigFile, groupVersions, 0)
localScheme := runtime.NewScheme()
scheme.AddToScheme(localScheme)
utilruntime.Must(localScheme.SetVersionPriority(groupVersions...))
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0)
if err != nil {
return nil, err
}

View File

@ -25,7 +25,7 @@ import (
"github.com/golang/glog"
authorization "k8s.io/api/authorization/v1beta1"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/cache"
"k8s.io/apiserver/pkg/authentication/user"
@ -234,21 +234,15 @@ func convertToSARExtra(extra map[string][]string) map[string]authorization.Extra
return ret
}
// NOTE: client-go doesn't provide a registry. client-go does registers the
// authorization/v1beta1. We construct a registry that acknowledges
// authorization/v1beta1 as an enabled version to pass a check enforced in
// NewGenericWebhook.
var registry = registered.NewAPIRegistrationManager()
func init() {
registry.RegisterVersions(groupVersions)
}
// subjectAccessReviewInterfaceFromKubeconfig builds a client from the specified kubeconfig file,
// and returns a SubjectAccessReviewInterface that uses that client. Note that the client submits SubjectAccessReview
// requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted.
func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string) (authorizationclient.SubjectAccessReviewInterface, error) {
gw, err := webhook.NewGenericWebhook(registry, scheme.Codecs, kubeConfigFile, groupVersions, 0)
localScheme := runtime.NewScheme()
scheme.AddToScheme(localScheme)
localScheme.SetVersionPriority(groupVersions...)
gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0)
if err != nil {
return nil, err
}