diff --git a/pkg/apiserver/interfaces.go b/pkg/api/rest/rest.go similarity index 65% rename from pkg/apiserver/interfaces.go rename to pkg/api/rest/rest.go index 450481bdb9e..447377148a2 100644 --- a/pkg/apiserver/interfaces.go +++ b/pkg/api/rest/rest.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package apiserver +package rest import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" @@ -26,15 +26,15 @@ import ( // RESTStorage is a generic interface for RESTful storage services. // Resources which are exported to the RESTful API of apiserver need to implement this interface. It is expected -// that objects may implement any of the REST* interfaces. -// TODO: implement dynamic introspection (so GenericREST objects can indicate what they implement) -type RESTStorage interface { +// that objects may implement any of the below interfaces. +type Storage interface { // New returns an empty object that can be used with Create and Update after request data has been put into it. // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object) New() runtime.Object } -type RESTLister interface { +// Lister is an object that can retrieve resources that match the provided field and label criteria. +type Lister interface { // NewList returns an empty object that can be used with the List call. // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object) NewList() runtime.Object @@ -42,23 +42,27 @@ type RESTLister interface { List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) } -type RESTGetter interface { - // Get finds a resource in the storage by id and returns it. +// Getter is an object that can retrieve a named RESTful resource. +type Getter interface { + // Get finds a resource in the storage by name and returns it. // Although it can return an arbitrary error value, IsNotFound(err) is true for the // returned error value err when the specified resource is not found. - Get(ctx api.Context, id string) (runtime.Object, error) + Get(ctx api.Context, name string) (runtime.Object, error) } -type RESTDeleter interface { +// Deleter is an object that can delete a named RESTful resource. +type Deleter interface { // Delete finds a resource in the storage and deletes it. // Although it can return an arbitrary error value, IsNotFound(err) is true for the // returned error value err when the specified resource is not found. // Delete *may* return the object that was deleted, or a status object indicating additional // information about deletion. - Delete(ctx api.Context, id string) (runtime.Object, error) + Delete(ctx api.Context, name string) (runtime.Object, error) } -type RESTGracefulDeleter interface { +// GracefulDeleter knows how to pass deletion options to allow delayed deletion of a +// RESTful object. +type GracefulDeleter interface { // Delete finds a resource in the storage and deletes it. // If options are provided, the resource will attempt to honor them or return an invalid // request error. @@ -66,20 +70,21 @@ type RESTGracefulDeleter interface { // returned error value err when the specified resource is not found. // Delete *may* return the object that was deleted, or a status object indicating additional // information about deletion. - Delete(ctx api.Context, id string, options *api.DeleteOptions) (runtime.Object, error) + Delete(ctx api.Context, name string, options *api.DeleteOptions) (runtime.Object, error) } -// GracefulDeleteAdapter adapts the RESTDeleter interface to RESTGracefulDeleter +// GracefulDeleteAdapter adapts the Deleter interface to GracefulDeleter type GracefulDeleteAdapter struct { - RESTDeleter + Deleter } -// Delete implements RESTGracefulDeleter in terms of RESTDeleter -func (w GracefulDeleteAdapter) Delete(ctx api.Context, id string, options *api.DeleteOptions) (runtime.Object, error) { - return w.RESTDeleter.Delete(ctx, id) +// Delete implements RESTGracefulDeleter in terms of Deleter +func (w GracefulDeleteAdapter) Delete(ctx api.Context, name string, options *api.DeleteOptions) (runtime.Object, error) { + return w.Deleter.Delete(ctx, name) } -type RESTCreater interface { +// Creater is an object that can create an instance of a RESTful object. +type Creater interface { // New returns an empty object that can be used with Create after request data has been put into it. // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object) New() runtime.Object @@ -88,7 +93,8 @@ type RESTCreater interface { Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) } -type RESTUpdater interface { +// Updater is an object that can update an instance of a RESTful object. +type Updater interface { // New returns an empty object that can be used with Update after request data has been put into it. // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object) New() runtime.Object @@ -99,25 +105,24 @@ type RESTUpdater interface { Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) } -type RESTPatcher interface { - RESTGetter - RESTUpdater +// CreaterUpdater is a storage object that must support both create and update. +// Go prevents embedded interfaces that implement the same method. +type CreaterUpdater interface { + Creater + Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) } -// RESTResult indicates the result of a REST transformation. -type RESTResult struct { - // The result of this operation. May be nil if the operation has no meaningful - // result (like Delete) - runtime.Object +// CreaterUpdater must satisfy the Updater interface. +var _ Updater = CreaterUpdater(nil) - // May be set true to indicate that the Update operation resulted in the object - // being created. - Created bool +type Patcher interface { + Getter + Updater } -// ResourceWatcher should be implemented by all RESTStorage objects that +// Watcher should be implemented by all Storage objects that // want to offer the ability to watch for changes through the watch api. -type ResourceWatcher interface { +type Watcher interface { // 'label' selects on labels; 'field' selects on the object's fields. Not all fields // are supported; an error should be returned if 'field' tries to select on a field that // isn't supported. 'resourceVersion' allows for continuing/starting a watch at a @@ -125,8 +130,18 @@ type ResourceWatcher interface { Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) } +// StandardStorage is an interface covering the common verbs. Provided for testing whether a +// resource satisfies the normal storage methods. Use Storage when passing opaque storage objects. +type StandardStorage interface { + Getter + Lister + CreaterUpdater + GracefulDeleter + Watcher +} + // Redirector know how to return a remote resource's location. type Redirector interface { // ResourceLocation should return the remote location of the given resource, or an error. - ResourceLocation(ctx api.Context, id string) (remoteLocation string, err error) + ResourceLocation(ctx api.Context, name string) (remoteLocation string, err error) } diff --git a/pkg/api/rest/resttest/resttest.go b/pkg/api/rest/resttest/resttest.go index 0690bfc0795..075d125af7b 100644 --- a/pkg/api/rest/resttest/resttest.go +++ b/pkg/api/rest/resttest/resttest.go @@ -22,21 +22,21 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) type Tester struct { *testing.T - storage apiserver.RESTStorage + storage rest.Storage storageError injectErrorFunc clusterScope bool } type injectErrorFunc func(err error) -func New(t *testing.T, storage apiserver.RESTStorage, storageError injectErrorFunc) *Tester { +func New(t *testing.T, storage rest.Storage, storageError injectErrorFunc) *Tester { return &Tester{ T: t, storage: storage, @@ -85,7 +85,7 @@ func (t *Tester) TestCreateResetsUserData(valid runtime.Object) { objectMeta.UID = "bad-uid" objectMeta.CreationTimestamp = now - obj, err := t.storage.(apiserver.RESTCreater).Create(api.NewDefaultContext(), valid) + obj, err := t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -111,7 +111,7 @@ func (t *Tester) TestCreateHasMetadata(valid runtime.Object) { context = api.NewContext() } - obj, err := t.storage.(apiserver.RESTCreater).Create(context, valid) + obj, err := t.storage.(rest.Creater).Create(context, valid) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -131,7 +131,7 @@ func (t *Tester) TestCreateGeneratesName(valid runtime.Object) { objectMeta.GenerateName = "test-" - _, err = t.storage.(apiserver.RESTCreater).Create(api.NewDefaultContext(), valid) + _, err = t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -148,7 +148,7 @@ func (t *Tester) TestCreateGeneratesNameReturnsServerTimeout(valid runtime.Objec objectMeta.GenerateName = "test-" t.withStorageError(errors.NewAlreadyExists("kind", "thing"), func() { - _, err := t.storage.(apiserver.RESTCreater).Create(api.NewDefaultContext(), valid) + _, err := t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid) if err == nil || !errors.IsServerTimeout(err) { t.Fatalf("Unexpected error: %v", err) } @@ -158,7 +158,7 @@ func (t *Tester) TestCreateGeneratesNameReturnsServerTimeout(valid runtime.Objec func (t *Tester) TestCreateInvokesValidation(invalid ...runtime.Object) { for i, obj := range invalid { ctx := api.NewDefaultContext() - _, err := t.storage.(apiserver.RESTCreater).Create(ctx, obj) + _, err := t.storage.(rest.Creater).Create(ctx, obj) if !errors.IsInvalid(err) { t.Errorf("%d: Expected to get an invalid resource error, got %v", i, err) } @@ -173,7 +173,7 @@ func (t *Tester) TestCreateRejectsMismatchedNamespace(valid runtime.Object) { objectMeta.Namespace = "not-default" - _, err = t.storage.(apiserver.RESTCreater).Create(api.NewDefaultContext(), valid) + _, err = t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid) if err == nil { t.Errorf("Expected an error, but we didn't get one") } else if strings.Contains(err.Error(), "Controller.Namespace does not match the provided context") { @@ -189,7 +189,7 @@ func (t *Tester) TestCreateRejectsNamespace(valid runtime.Object) { objectMeta.Namespace = "not-default" - _, err = t.storage.(apiserver.RESTCreater).Create(api.NewDefaultContext(), valid) + _, err = t.storage.(rest.Creater).Create(api.NewDefaultContext(), valid) if err == nil { t.Errorf("Expected an error, but we didn't get one") } else if strings.Contains(err.Error(), "Controller.Namespace does not match the provided context") { @@ -210,11 +210,11 @@ func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefu } ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace) - _, err = t.storage.(apiserver.RESTGracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10)) + _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10)) if err != nil { t.Errorf("unexpected error: %v", err) } - if _, err := t.storage.(apiserver.RESTGetter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) { + if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) { t.Errorf("unexpected error, object should not exist: %v", err) } if wasGracefulFn() { @@ -229,11 +229,11 @@ func (t *Tester) TestDeleteGracefulHasDefault(existing runtime.Object, expectedG } ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace) - _, err = t.storage.(apiserver.RESTGracefulDeleter).Delete(ctx, objectMeta.Name, &api.DeleteOptions{}) + _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, &api.DeleteOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } - if _, err := t.storage.(apiserver.RESTGetter).Get(ctx, objectMeta.Name); err != nil { + if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); err != nil { t.Errorf("unexpected error, object should exist: %v", err) } if !wasGracefulFn() { @@ -248,11 +248,11 @@ func (t *Tester) TestDeleteGracefulUsesZeroOnNil(existing runtime.Object, expect } ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace) - _, err = t.storage.(apiserver.RESTGracefulDeleter).Delete(ctx, objectMeta.Name, nil) + _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, nil) if err != nil { t.Errorf("unexpected error: %v", err) } - if _, err := t.storage.(apiserver.RESTGetter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) { + if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) { t.Errorf("unexpected error, object should exist: %v", err) } } diff --git a/pkg/apiserver/api_installer.go b/pkg/apiserver/api_installer.go index 0cf52dd58bb..6f6dc8e9c20 100644 --- a/pkg/apiserver/api_installer.go +++ b/pkg/apiserver/api_installer.go @@ -28,6 +28,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/emicklei/go-restful" @@ -94,7 +95,7 @@ func (a *APIInstaller) newWebService() *restful.WebService { return ws } -func (a *APIInstaller) registerResourceHandlers(path string, storage RESTStorage, ws *restful.WebService, watchHandler, redirectHandler, proxyHandler http.Handler) error { +func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storage, ws *restful.WebService, watchHandler, redirectHandler, proxyHandler http.Handler) error { admit := a.group.Admit context := a.group.Context @@ -121,7 +122,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage RESTStorage versionedObject := indirectArbitraryPointer(versionedPtr) var versionedList interface{} - if lister, ok := storage.(RESTLister); ok { + if lister, ok := storage.(rest.Lister); ok { list := lister.NewList() _, listKind, err := a.group.Typer.ObjectVersionAndKind(list) versionedListPtr, err := a.group.Creater.New(a.group.Version, listKind) @@ -137,15 +138,15 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage RESTStorage } // what verbs are supported by the storage, used to know what verbs we support per path - creater, isCreater := storage.(RESTCreater) - lister, isLister := storage.(RESTLister) - getter, isGetter := storage.(RESTGetter) - deleter, isDeleter := storage.(RESTDeleter) - gracefulDeleter, isGracefulDeleter := storage.(RESTGracefulDeleter) - updater, isUpdater := storage.(RESTUpdater) - patcher, isPatcher := storage.(RESTPatcher) - _, isWatcher := storage.(ResourceWatcher) - _, isRedirector := storage.(Redirector) + creater, isCreater := storage.(rest.Creater) + lister, isLister := storage.(rest.Lister) + getter, isGetter := storage.(rest.Getter) + deleter, isDeleter := storage.(rest.Deleter) + gracefulDeleter, isGracefulDeleter := storage.(rest.GracefulDeleter) + updater, isUpdater := storage.(rest.Updater) + patcher, isPatcher := storage.(rest.Patcher) + _, isWatcher := storage.(rest.Watcher) + _, isRedirector := storage.(rest.Redirector) var versionedDeleterObject runtime.Object switch { @@ -157,7 +158,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage RESTStorage versionedDeleterObject = object isDeleter = true case isDeleter: - gracefulDeleter = GracefulDeleteAdapter{deleter} + gracefulDeleter = rest.GracefulDeleteAdapter{deleter} } var ctxFn ContextFunc diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index c8f749133f9..f7ac60d8b80 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -30,6 +30,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -90,12 +91,12 @@ type Mux interface { HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) } -// APIGroupVersion is a helper for exposing RESTStorage objects as http.Handlers via go-restful +// APIGroupVersion is a helper for exposing rest.Storage objects as http.Handlers via go-restful // It handles URLs of the form: // /${storage_key}[/${object_name}] -// Where 'storage_key' points to a RESTStorage object stored in storage. +// Where 'storage_key' points to a rest.Storage object stored in storage. type APIGroupVersion struct { - Storage map[string]RESTStorage + Storage map[string]rest.Storage Root string Version string diff --git a/pkg/apiserver/apiserver_test.go b/pkg/apiserver/apiserver_test.go index 1a9718c5de5..45e2191022d 100644 --- a/pkg/apiserver/apiserver_test.go +++ b/pkg/apiserver/apiserver_test.go @@ -34,6 +34,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" apierrs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -124,26 +125,26 @@ type defaultAPIServer struct { } // uses the default settings -func handle(storage map[string]RESTStorage) http.Handler { +func handle(storage map[string]rest.Storage) http.Handler { return handleInternal(storage, admissionControl, mapper, selfLinker) } // tests with a deny admission controller -func handleDeny(storage map[string]RESTStorage) http.Handler { +func handleDeny(storage map[string]rest.Storage) http.Handler { return handleInternal(storage, deny.NewAlwaysDeny(), mapper, selfLinker) } // tests using the new namespace scope mechanism -func handleNamespaced(storage map[string]RESTStorage) http.Handler { +func handleNamespaced(storage map[string]rest.Storage) http.Handler { return handleInternal(storage, admissionControl, namespaceMapper, selfLinker) } // tests using a custom self linker -func handleLinker(storage map[string]RESTStorage, selfLinker runtime.SelfLinker) http.Handler { +func handleLinker(storage map[string]rest.Storage, selfLinker runtime.SelfLinker) http.Handler { return handleInternal(storage, admissionControl, mapper, selfLinker) } -func handleInternal(storage map[string]RESTStorage, admissionControl admission.Interface, mapper meta.RESTMapper, selfLinker runtime.SelfLinker) http.Handler { +func handleInternal(storage map[string]rest.Storage, admissionControl admission.Interface, mapper meta.RESTMapper, selfLinker runtime.SelfLinker) http.Handler { group := &APIGroupVersion{ Storage: storage, @@ -365,7 +366,7 @@ func TestNotFound(t *testing.T) { "watch missing storage": {"GET", "/api/version/watch/", http.StatusNotFound}, "watch with bad method": {"POST", "/api/version/watch/foo/bar", http.StatusMethodNotAllowed}, } - handler := handle(map[string]RESTStorage{ + handler := handle(map[string]rest.Storage{ "foo": &SimpleRESTStorage{}, }) server := httptest.NewServer(handler) @@ -395,7 +396,7 @@ func (UnimplementedRESTStorage) New() runtime.Object { return &Simple{} } -// TestUnimplementedRESTStorage ensures that if a RESTStorage does not implement a given +// TestUnimplementedRESTStorage ensures that if a rest.Storage does not implement a given // method, that it is literally not registered with the server. In the past, // we registered everything, and returned method not supported if it didn't support // a verb. Now we literally do not register a storage if it does not implement anything. @@ -417,7 +418,7 @@ func TestUnimplementedRESTStorage(t *testing.T) { "proxy object": {"GET", "/api/version/proxy/foo/bar", http.StatusNotFound}, "redirect object": {"GET", "/api/version/redirect/foo/bar", http.StatusNotFound}, } - handler := handle(map[string]RESTStorage{ + handler := handle(map[string]rest.Storage{ "foo": UnimplementedRESTStorage{}, }) server := httptest.NewServer(handler) @@ -444,7 +445,7 @@ func TestUnimplementedRESTStorage(t *testing.T) { } func TestVersion(t *testing.T) { - handler := handle(map[string]RESTStorage{}) + handler := handle(map[string]rest.Storage{}) server := httptest.NewServer(handler) defer server.Close() client := http.Client{} @@ -487,7 +488,7 @@ func TestList(t *testing.T) { {"/api/version/simple", "", "/api/version/simple", false}, } for i, testCase := range testCases { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{expectedResourceNamespace: testCase.namespace} storage["simple"] = &simpleStorage selfLinker := &setTestSelfLinker{ @@ -525,7 +526,7 @@ func TestList(t *testing.T) { } func TestErrorList(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ errors: map[string]error{"list": fmt.Errorf("test Error")}, } @@ -545,7 +546,7 @@ func TestErrorList(t *testing.T) { } func TestNonEmptyList(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ list: []Simple{ { @@ -593,7 +594,7 @@ func TestNonEmptyList(t *testing.T) { } func TestSelfLinkSkipsEmptyName(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ list: []Simple{ { @@ -640,7 +641,7 @@ func TestSelfLinkSkipsEmptyName(t *testing.T) { } func TestGet(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ item: Simple{ Other: "foo", @@ -679,7 +680,7 @@ func TestGet(t *testing.T) { } func TestGetAlternateSelfLink(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ item: Simple{ Other: "foo", @@ -717,7 +718,7 @@ func TestGetAlternateSelfLink(t *testing.T) { } func TestGetNamespaceSelfLink(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ item: Simple{ Other: "foo", @@ -754,7 +755,7 @@ func TestGetNamespaceSelfLink(t *testing.T) { } } func TestGetMissing(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ errors: map[string]error{"get": apierrs.NewNotFound("simple", "id")}, } @@ -774,7 +775,7 @@ func TestGetMissing(t *testing.T) { } func TestDelete(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -797,7 +798,7 @@ func TestDelete(t *testing.T) { } func TestDeleteWithOptions(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -834,11 +835,11 @@ func TestDeleteWithOptions(t *testing.T) { } func TestLegacyDelete(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = LegacyRESTStorage{&simpleStorage} - var _ RESTDeleter = storage["simple"].(LegacyRESTStorage) + var _ rest.Deleter = storage["simple"].(LegacyRESTStorage) handler := handle(storage) server := httptest.NewServer(handler) defer server.Close() @@ -861,7 +862,7 @@ func TestLegacyDelete(t *testing.T) { } func TestLegacyDeleteIgnoresOptions(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = LegacyRESTStorage{&simpleStorage} @@ -893,7 +894,7 @@ func TestLegacyDeleteIgnoresOptions(t *testing.T) { } func TestDeleteInvokesAdmissionControl(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -913,7 +914,7 @@ func TestDeleteInvokesAdmissionControl(t *testing.T) { } func TestDeleteMissing(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} ID := "id" simpleStorage := SimpleRESTStorage{ errors: map[string]error{"delete": apierrs.NewNotFound("simple", ID)}, @@ -936,7 +937,7 @@ func TestDeleteMissing(t *testing.T) { } func TestPatch(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} ID := "id" item := &Simple{ ObjectMeta: api.ObjectMeta{ @@ -973,7 +974,7 @@ func TestPatch(t *testing.T) { } func TestPatchRequiresMatchingName(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} ID := "id" item := &Simple{ ObjectMeta: api.ObjectMeta{ @@ -1000,7 +1001,7 @@ func TestPatchRequiresMatchingName(t *testing.T) { } func TestUpdate(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -1043,7 +1044,7 @@ func TestUpdate(t *testing.T) { } func TestUpdateInvokesAdmissionControl(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -1076,7 +1077,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) { } func TestUpdateRequiresMatchingName(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -1105,7 +1106,7 @@ func TestUpdateRequiresMatchingName(t *testing.T) { } func TestUpdateAllowsMissingNamespace(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -1138,7 +1139,7 @@ func TestUpdateAllowsMissingNamespace(t *testing.T) { // when the object name and namespace can't be retrieved, skip name checking func TestUpdateAllowsMismatchedNamespaceOnError(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -1179,7 +1180,7 @@ func TestUpdateAllowsMismatchedNamespaceOnError(t *testing.T) { } func TestUpdatePreventsMismatchedNamespace(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{} ID := "id" storage["simple"] = &simpleStorage @@ -1212,7 +1213,7 @@ func TestUpdatePreventsMismatchedNamespace(t *testing.T) { } func TestUpdateMissing(t *testing.T) { - storage := map[string]RESTStorage{} + storage := map[string]rest.Storage{} ID := "id" simpleStorage := SimpleRESTStorage{ errors: map[string]error{"update": apierrs.NewNotFound("simple", ID)}, @@ -1246,7 +1247,7 @@ func TestUpdateMissing(t *testing.T) { } func TestCreateNotFound(t *testing.T) { - handler := handle(map[string]RESTStorage{ + handler := handle(map[string]rest.Storage{ "simple": &SimpleRESTStorage{ // storage.Create can fail with not found error in theory. // See https://github.com/GoogleCloudPlatform/kubernetes/pull/486#discussion_r15037092. @@ -1275,7 +1276,7 @@ func TestCreateNotFound(t *testing.T) { } func TestCreateChecksDecode(t *testing.T) { - handler := handle(map[string]RESTStorage{"simple": &SimpleRESTStorage{}}) + handler := handle(map[string]rest.Storage{"simple": &SimpleRESTStorage{}}) server := httptest.NewServer(handler) defer server.Close() client := http.Client{} @@ -1299,7 +1300,7 @@ func TestCreateChecksDecode(t *testing.T) { } func TestUpdateChecksDecode(t *testing.T) { - handler := handle(map[string]RESTStorage{"simple": &SimpleRESTStorage{}}) + handler := handle(map[string]rest.Storage{"simple": &SimpleRESTStorage{}}) server := httptest.NewServer(handler) defer server.Close() client := http.Client{} @@ -1367,7 +1368,7 @@ func TestCreate(t *testing.T) { namespace: "default", expectedSet: "/api/version/foo/bar?namespace=default", } - handler := handleLinker(map[string]RESTStorage{"foo": &storage}, selfLinker) + handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker) server := httptest.NewServer(handler) defer server.Close() client := http.Client{} @@ -1423,7 +1424,7 @@ func TestCreateInNamespace(t *testing.T) { namespace: "other", expectedSet: "/api/version/foo/bar?namespace=other", } - handler := handleLinker(map[string]RESTStorage{"foo": &storage}, selfLinker) + handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker) server := httptest.NewServer(handler) defer server.Close() client := http.Client{} @@ -1479,7 +1480,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) { namespace: "other", expectedSet: "/api/version/foo/bar?namespace=other", } - handler := handleInternal(map[string]RESTStorage{"foo": &storage}, deny.NewAlwaysDeny(), mapper, selfLinker) + handler := handleInternal(map[string]rest.Storage{"foo": &storage}, deny.NewAlwaysDeny(), mapper, selfLinker) server := httptest.NewServer(handler) defer server.Close() client := http.Client{} @@ -1539,7 +1540,7 @@ func TestDelayReturnsError(t *testing.T) { return nil, apierrs.NewAlreadyExists("foo", "bar") }, } - handler := handle(map[string]RESTStorage{"foo": &storage}) + handler := handle(map[string]rest.Storage{"foo": &storage}) server := httptest.NewServer(handler) defer server.Close() @@ -1603,7 +1604,7 @@ func TestCreateTimeout(t *testing.T) { return obj, nil }, } - handler := handle(map[string]RESTStorage{ + handler := handle(map[string]rest.Storage{ "foo": &storage, }) server := httptest.NewServer(handler) @@ -1637,7 +1638,7 @@ func TestCORSAllowedOrigins(t *testing.T) { } handler := CORS( - handle(map[string]RESTStorage{}), + handle(map[string]rest.Storage{}), allowedOriginRegexps, nil, nil, "true", ) server := httptest.NewServer(handler) diff --git a/pkg/apiserver/doc.go b/pkg/apiserver/doc.go index 5020b83ff89..ecac809af74 100644 --- a/pkg/apiserver/doc.go +++ b/pkg/apiserver/doc.go @@ -14,5 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package apiserver contains the code that provides a RESTful api service. +// Package apiserver contains the code that provides a rest.ful api service. package apiserver diff --git a/pkg/apiserver/proxy.go b/pkg/apiserver/proxy.go index 88e052cdb7d..86d823d9c4e 100644 --- a/pkg/apiserver/proxy.go +++ b/pkg/apiserver/proxy.go @@ -32,6 +32,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/httplog" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -79,7 +80,7 @@ var tagsToAttrs = map[string]util.StringSet{ // specified by items implementing Redirector. type ProxyHandler struct { prefix string - storage map[string]RESTStorage + storage map[string]rest.Storage codec runtime.Codec context api.RequestContextMapper apiRequestInfoResolver *APIRequestInfoResolver @@ -112,15 +113,15 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } id := parts[1] - rest := "" + remainder := "" if len(parts) > 2 { proxyParts := parts[2:] - rest = strings.Join(proxyParts, "/") + remainder = strings.Join(proxyParts, "/") if strings.HasSuffix(req.URL.Path, "/") { // The original path had a trailing slash, which has been stripped // by KindAndNamespace(). We should add it back because some // servers (like etcd) require it. - rest = rest + "/" + remainder = remainder + "/" } } storage, ok := r.storage[resource] @@ -132,7 +133,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } apiResource = resource - redirector, ok := storage.(Redirector) + redirector, ok := storage.(rest.Redirector) if !ok { httplog.LogOf(req, w).Addf("'%v' is not a redirector", resource) httpCode = errorJSON(errors.NewMethodNotSupported(resource, "proxy"), r.codec, w) @@ -160,7 +161,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { // hosts for paths. destURL.Host = location } - destURL.Path = rest + destURL.Path = remainder destURL.RawQuery = req.URL.RawQuery newReq, err := http.NewRequest(req.Method, destURL.String(), req.Body) if err != nil { diff --git a/pkg/apiserver/proxy_test.go b/pkg/apiserver/proxy_test.go index 797728ffc14..d3b71845da1 100644 --- a/pkg/apiserver/proxy_test.go +++ b/pkg/apiserver/proxy_test.go @@ -28,6 +28,7 @@ import ( "strings" "testing" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "golang.org/x/net/html" "golang.org/x/net/websocket" ) @@ -280,10 +281,10 @@ func TestProxy(t *testing.T) { expectedResourceNamespace: item.reqNamespace, } - namespaceHandler := handleNamespaced(map[string]RESTStorage{"foo": simpleStorage}) + namespaceHandler := handleNamespaced(map[string]rest.Storage{"foo": simpleStorage}) namespaceServer := httptest.NewServer(namespaceHandler) defer namespaceServer.Close() - legacyNamespaceHandler := handle(map[string]RESTStorage{"foo": simpleStorage}) + legacyNamespaceHandler := handle(map[string]rest.Storage{"foo": simpleStorage}) legacyNamespaceServer := httptest.NewServer(legacyNamespaceHandler) defer legacyNamespaceServer.Close() @@ -340,7 +341,7 @@ func TestProxyUpgrade(t *testing.T) { expectedResourceNamespace: "myns", } - namespaceHandler := handleNamespaced(map[string]RESTStorage{"foo": simpleStorage}) + namespaceHandler := handleNamespaced(map[string]rest.Storage{"foo": simpleStorage}) server := httptest.NewServer(namespaceHandler) defer server.Close() diff --git a/pkg/apiserver/redirect.go b/pkg/apiserver/redirect.go index 44e372ea32d..3527ffba67c 100644 --- a/pkg/apiserver/redirect.go +++ b/pkg/apiserver/redirect.go @@ -23,12 +23,13 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/httplog" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) type RedirectHandler struct { - storage map[string]RESTStorage + storage map[string]rest.Storage codec runtime.Codec context api.RequestContextMapper apiRequestInfoResolver *APIRequestInfoResolver @@ -71,7 +72,7 @@ func (r *RedirectHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } apiResource = resource - redirector, ok := storage.(Redirector) + redirector, ok := storage.(rest.Redirector) if !ok { httplog.LogOf(req, w).Addf("'%v' is not a redirector", resource) httpCode = errorJSON(errors.NewMethodNotSupported(resource, "redirect"), r.codec, w) diff --git a/pkg/apiserver/redirect_test.go b/pkg/apiserver/redirect_test.go index c74c99994c8..01da7efc727 100644 --- a/pkg/apiserver/redirect_test.go +++ b/pkg/apiserver/redirect_test.go @@ -22,6 +22,8 @@ import ( "net/http/httptest" "net/url" "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" ) func TestRedirect(t *testing.T) { @@ -29,7 +31,7 @@ func TestRedirect(t *testing.T) { errors: map[string]error{}, expectedResourceNamespace: "default", } - handler := handle(map[string]RESTStorage{"foo": simpleStorage}) + handler := handle(map[string]rest.Storage{"foo": simpleStorage}) server := httptest.NewServer(handler) defer server.Close() @@ -80,7 +82,7 @@ func TestRedirectWithNamespaces(t *testing.T) { errors: map[string]error{}, expectedResourceNamespace: "other", } - handler := handleNamespaced(map[string]RESTStorage{"foo": simpleStorage}) + handler := handleNamespaced(map[string]rest.Storage{"foo": simpleStorage}) server := httptest.NewServer(handler) defer server.Close() diff --git a/pkg/apiserver/resthandler.go b/pkg/apiserver/resthandler.go index 37a289183b5..c8b25c5f1f7 100644 --- a/pkg/apiserver/resthandler.go +++ b/pkg/apiserver/resthandler.go @@ -26,6 +26,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -58,8 +59,8 @@ type ScopeNamer interface { GenerateListLink(req *restful.Request) (path, query string, err error) } -// GetResource returns a function that handles retrieving a single resource from a RESTStorage object. -func GetResource(r RESTGetter, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec) restful.RouteFunction { +// GetResource returns a function that handles retrieving a single resource from a rest.Storage object. +func GetResource(r rest.Getter, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { w := res.ResponseWriter namespace, name, err := namer.Name(req) @@ -101,8 +102,8 @@ func parseSelectorQueryParams(query url.Values, version, apiResource string) (la return label, field, nil } -// ListResource returns a function that handles retrieving a list of resources from a RESTStorage object. -func ListResource(r RESTLister, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, version, apiResource string) restful.RouteFunction { +// ListResource returns a function that handles retrieving a list of resources from a rest.Storage object. +func ListResource(r rest.Lister, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, version, apiResource string) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { w := res.ResponseWriter @@ -134,7 +135,7 @@ func ListResource(r RESTLister, ctxFn ContextFunc, namer ScopeNamer, codec runti } // CreateResource returns a function that will handle a resource creation. -func CreateResource(r RESTCreater, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, typer runtime.ObjectTyper, resource string, admit admission.Interface) restful.RouteFunction { +func CreateResource(r rest.Creater, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, typer runtime.ObjectTyper, resource string, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { w := res.ResponseWriter @@ -191,7 +192,7 @@ func CreateResource(r RESTCreater, ctxFn ContextFunc, namer ScopeNamer, codec ru // PatchResource returns a function that will handle a resource patch // TODO: Eventually PatchResource should just use AtomicUpdate and this routine should be a bit cleaner -func PatchResource(r RESTPatcher, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, typer runtime.ObjectTyper, resource string, admit admission.Interface) restful.RouteFunction { +func PatchResource(r rest.Patcher, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, typer runtime.ObjectTyper, resource string, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { w := res.ResponseWriter @@ -266,7 +267,7 @@ func PatchResource(r RESTPatcher, ctxFn ContextFunc, namer ScopeNamer, codec run } // UpdateResource returns a function that will handle a resource update -func UpdateResource(r RESTUpdater, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, typer runtime.ObjectTyper, resource string, admit admission.Interface) restful.RouteFunction { +func UpdateResource(r rest.Updater, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, typer runtime.ObjectTyper, resource string, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { w := res.ResponseWriter @@ -330,7 +331,7 @@ func UpdateResource(r RESTUpdater, ctxFn ContextFunc, namer ScopeNamer, codec ru } // DeleteResource returns a function that will handle a resource deletion -func DeleteResource(r RESTGracefulDeleter, checkBody bool, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, resource, kind string, admit admission.Interface) restful.RouteFunction { +func DeleteResource(r rest.GracefulDeleter, checkBody bool, ctxFn ContextFunc, namer ScopeNamer, codec runtime.Codec, resource, kind string, admit admission.Interface) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { w := res.ResponseWriter @@ -376,7 +377,7 @@ func DeleteResource(r RESTGracefulDeleter, checkBody bool, ctxFn ContextFunc, na return } - // if the RESTDeleter returns a nil object, fill out a status. Callers may return a valid + // if the rest.Deleter returns a nil object, fill out a status. Callers may return a valid // object with the response. if result == nil { result = &api.Status{ diff --git a/pkg/apiserver/watch.go b/pkg/apiserver/watch.go index c98228316f1..c92fdb3002b 100644 --- a/pkg/apiserver/watch.go +++ b/pkg/apiserver/watch.go @@ -26,6 +26,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/httplog" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" @@ -36,7 +37,7 @@ import ( ) type WatchHandler struct { - storage map[string]RESTStorage + storage map[string]rest.Storage codec runtime.Codec linker runtime.SelfLinker info *APIRequestInfoResolver @@ -90,7 +91,7 @@ func (h *WatchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } apiResource = requestInfo.Resource - watcher, ok := storage.(ResourceWatcher) + watcher, ok := storage.(rest.Watcher) if !ok { httpCode = errorJSON(errors.NewMethodNotSupported(requestInfo.Resource, "watch"), h.codec, w) return diff --git a/pkg/apiserver/watch_test.go b/pkg/apiserver/watch_test.go index 07938da0ae4..c4fb3b52d13 100644 --- a/pkg/apiserver/watch_test.go +++ b/pkg/apiserver/watch_test.go @@ -25,6 +25,7 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -49,8 +50,8 @@ var watchTestTable = []struct { func TestWatchWebsocket(t *testing.T) { simpleStorage := &SimpleRESTStorage{} - _ = ResourceWatcher(simpleStorage) // Give compile error if this doesn't work. - handler := handle(map[string]RESTStorage{"foo": simpleStorage}) + _ = rest.Watcher(simpleStorage) // Give compile error if this doesn't work. + handler := handle(map[string]rest.Storage{"foo": simpleStorage}) server := httptest.NewServer(handler) defer server.Close() @@ -102,7 +103,7 @@ func TestWatchWebsocket(t *testing.T) { func TestWatchHTTP(t *testing.T) { simpleStorage := &SimpleRESTStorage{} - handler := handle(map[string]RESTStorage{"foo": simpleStorage}) + handler := handle(map[string]rest.Storage{"foo": simpleStorage}) server := httptest.NewServer(handler) defer server.Close() client := http.Client{} @@ -167,7 +168,7 @@ func TestWatchParamParsing(t *testing.T) { return label, value, nil }) simpleStorage := &SimpleRESTStorage{} - handler := handle(map[string]RESTStorage{"foo": simpleStorage}) + handler := handle(map[string]rest.Storage{"foo": simpleStorage}) server := httptest.NewServer(handler) defer server.Close() @@ -237,7 +238,7 @@ func TestWatchParamParsing(t *testing.T) { func TestWatchProtocolSelection(t *testing.T) { simpleStorage := &SimpleRESTStorage{} - handler := handle(map[string]RESTStorage{"foo": simpleStorage}) + handler := handle(map[string]rest.Storage{"foo": simpleStorage}) server := httptest.NewServer(handler) defer server.Close() defer server.CloseClientConnections() diff --git a/pkg/client/record/events_cache.go b/pkg/client/record/events_cache.go index 6243b5bcd83..4886f6cd7c1 100644 --- a/pkg/client/record/events_cache.go +++ b/pkg/client/record/events_cache.go @@ -17,10 +17,11 @@ limitations under the License. package record import ( + "sync" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/groupcache/lru" - "sync" ) type history struct { diff --git a/pkg/client/record/events_cache_test.go b/pkg/client/record/events_cache_test.go index fb93745acde..c3860bfb9e5 100644 --- a/pkg/client/record/events_cache_test.go +++ b/pkg/client/record/events_cache_test.go @@ -17,9 +17,10 @@ limitations under the License. package record import ( + "testing" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "testing" ) func TestAddOrUpdateEventNoExisting(t *testing.T) { diff --git a/pkg/master/master.go b/pkg/master/master.go index c6e2ed74111..50c02a85490 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -31,6 +31,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3" @@ -151,7 +152,7 @@ type Master struct { masterServices *util.Runner // storage contains the RESTful endpoints exposed by this master - storage map[string]apiserver.RESTStorage + storage map[string]rest.Storage // registries are internal client APIs for accessing the storage layer // TODO: define the internal typed interface in a way that clients can @@ -384,7 +385,7 @@ func (m *Master) init(c *Config) { } // TODO: Factor out the core API registration - m.storage = map[string]apiserver.RESTStorage{ + m.storage = map[string]rest.Storage{ "pods": podStorage, "pods/status": podStatusStorage, "pods/binding": bindingStorage, @@ -576,7 +577,7 @@ func (m *Master) defaultAPIGroupVersion() *apiserver.APIGroupVersion { // api_v1beta1 returns the resources and codec for API version v1beta1. func (m *Master) api_v1beta1() *apiserver.APIGroupVersion { - storage := make(map[string]apiserver.RESTStorage) + storage := make(map[string]rest.Storage) for k, v := range m.storage { storage[k] = v } @@ -589,7 +590,7 @@ func (m *Master) api_v1beta1() *apiserver.APIGroupVersion { // api_v1beta2 returns the resources and codec for API version v1beta2. func (m *Master) api_v1beta2() *apiserver.APIGroupVersion { - storage := make(map[string]apiserver.RESTStorage) + storage := make(map[string]rest.Storage) for k, v := range m.storage { storage[k] = v } @@ -602,7 +603,7 @@ func (m *Master) api_v1beta2() *apiserver.APIGroupVersion { // api_v1beta3 returns the resources and codec for API version v1beta3. func (m *Master) api_v1beta3() *apiserver.APIGroupVersion { - storage := make(map[string]apiserver.RESTStorage) + storage := make(map[string]rest.Storage) for k, v := range m.storage { if k == "minions" { continue diff --git a/pkg/master/publish.go b/pkg/master/publish.go index 1e5a3f0d849..c2f66f8520c 100644 --- a/pkg/master/publish.go +++ b/pkg/master/publish.go @@ -22,7 +22,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/golang/glog" ) @@ -91,7 +91,7 @@ func (m *Master) createMasterNamespaceIfNeeded(ns string) error { Namespace: "", }, } - _, err := m.storage["namespaces"].(apiserver.RESTCreater).Create(ctx, namespace) + _, err := m.storage["namespaces"].(rest.Creater).Create(ctx, namespace) if err != nil && errors.IsAlreadyExists(err) { err = nil } @@ -121,7 +121,7 @@ func (m *Master) createMasterServiceIfNeeded(serviceName string, serviceIP net.I SessionAffinity: api.AffinityTypeNone, }, } - _, err := m.storage["services"].(apiserver.RESTCreater).Create(ctx, svc) + _, err := m.storage["services"].(rest.Creater).Create(ctx, svc) if err != nil && errors.IsAlreadyExists(err) { err = nil } diff --git a/pkg/master/rest_to_nodes.go b/pkg/master/rest_to_nodes.go index c6af8d7bbae..819be022bdb 100644 --- a/pkg/master/rest_to_nodes.go +++ b/pkg/master/rest_to_nodes.go @@ -20,7 +20,7 @@ import ( "errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" @@ -38,12 +38,12 @@ import ( // // TODO: this also means that pod and node API endpoints have to be colocated in the same // process -func RESTStorageToNodes(storage apiserver.RESTStorage) client.NodesInterface { +func RESTStorageToNodes(storage rest.Storage) client.NodesInterface { return &nodeAdaptor{storage} } type nodeAdaptor struct { - storage apiserver.RESTStorage + storage rest.Storage } func (n *nodeAdaptor) Nodes() client.NodeInterface { @@ -66,7 +66,7 @@ func (n *nodeAdaptor) Create(minion *api.Node) (*api.Node, error) { // List lists all the nodes in the cluster. func (n *nodeAdaptor) List() (*api.NodeList, error) { ctx := api.NewContext() - obj, err := n.storage.(apiserver.RESTLister).List(ctx, labels.Everything(), fields.Everything()) + obj, err := n.storage.(rest.Lister).List(ctx, labels.Everything(), fields.Everything()) if err != nil { return nil, err } @@ -76,7 +76,7 @@ func (n *nodeAdaptor) List() (*api.NodeList, error) { // Get gets an existing node. func (n *nodeAdaptor) Get(name string) (*api.Node, error) { ctx := api.NewContext() - obj, err := n.storage.(apiserver.RESTGetter).Get(ctx, name) + obj, err := n.storage.(rest.Getter).Get(ctx, name) if err != nil { return nil, err } diff --git a/pkg/registry/controller/rest.go b/pkg/registry/controller/rest.go index 19e072719cf..549e079f499 100644 --- a/pkg/registry/controller/rest.go +++ b/pkg/registry/controller/rest.go @@ -71,14 +71,14 @@ type PodLister interface { ListPods(ctx api.Context, labels labels.Selector) (*api.PodList, error) } -// REST implements apiserver.RESTStorage for the replication controller service. +// REST implements rest.Storage for the replication controller service. type REST struct { registry Registry podLister PodLister strategy rcStrategy } -// NewREST returns a new apiserver.RESTStorage for the given registry and PodLister. +// NewREST returns a new rest.Storage for the given registry and PodLister. func NewREST(registry Registry, podLister PodLister) *REST { return &REST{ registry: registry, @@ -167,7 +167,7 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, boo } // Watch returns ReplicationController events via a watch.Interface. -// It implements apiserver.ResourceWatcher. +// It implements rest.Watcher. func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { return rs.registry.WatchControllers(ctx, label, field, resourceVersion) } diff --git a/pkg/registry/endpoint/rest.go b/pkg/registry/endpoint/rest.go index 25f9b473194..b590a47b0d5 100644 --- a/pkg/registry/endpoint/rest.go +++ b/pkg/registry/endpoint/rest.go @@ -32,7 +32,7 @@ type REST struct { registry Registry } -// NewREST returns a new apiserver.RESTStorage implementation for endpoints +// NewREST returns a new rest.Storage implementation for endpoints func NewREST(registry Registry) *REST { return &REST{ registry: registry, @@ -53,7 +53,7 @@ func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Select } // Watch returns Endpoint events via a watch.Interface. -// It implements apiserver.ResourceWatcher. +// It implements rest.Watcher. func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { return rs.registry.WatchEndpoints(ctx, label, field, resourceVersion) } diff --git a/pkg/registry/event/rest.go b/pkg/registry/event/rest.go index 708d3de7006..e6e07329497 100644 --- a/pkg/registry/event/rest.go +++ b/pkg/registry/event/rest.go @@ -135,7 +135,7 @@ func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Select } // Watch returns Events events via a watch.Interface. -// It implements apiserver.ResourceWatcher. +// It implements rest.Watcher. func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion) } diff --git a/pkg/registry/event/rest_test.go b/pkg/registry/event/rest_test.go index 51e274b63cd..f968bb8f1df 100644 --- a/pkg/registry/event/rest_test.go +++ b/pkg/registry/event/rest_test.go @@ -21,8 +21,8 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" @@ -74,8 +74,8 @@ func TestRESTCreate(t *testing.T) { } for _, item := range table { - _, rest := NewTestREST() - c, err := rest.Create(item.ctx, item.event) + _, storage := NewTestREST() + c, err := storage.Create(item.ctx, item.event) if !item.valid { if err == nil { ctxNS := api.NamespaceValue(item.ctx) @@ -94,7 +94,7 @@ func TestRESTCreate(t *testing.T) { t.Errorf("diff: %s", util.ObjectDiff(e, a)) } // Ensure we implement the interface - _ = apiserver.ResourceWatcher(rest) + _ = rest.Watcher(storage) } } diff --git a/pkg/registry/minion/rest.go b/pkg/registry/minion/rest.go index ddb60b79bd3..72b0976ca0e 100644 --- a/pkg/registry/minion/rest.go +++ b/pkg/registry/minion/rest.go @@ -38,7 +38,7 @@ type REST struct { registry Registry } -// NewREST returns a new apiserver.RESTStorage implementation for minion. +// NewREST returns a new rest.Storage implementation for minion. func NewREST(m Registry) *REST { return &REST{ registry: m, @@ -133,7 +133,7 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, boo } // Watch returns Minions events via a watch.Interface. -// It implements apiserver.ResourceWatcher. +// It implements rest.Watcher. func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { return rs.registry.WatchMinions(ctx, label, field, resourceVersion) } diff --git a/pkg/registry/namespace/registry.go b/pkg/registry/namespace/registry.go index 9098c418be9..8301945df1b 100644 --- a/pkg/registry/namespace/registry.go +++ b/pkg/registry/namespace/registry.go @@ -18,7 +18,7 @@ package namespace import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -44,10 +44,10 @@ type Registry interface { // Storage is an interface for a standard REST Storage backend // TODO: move me somewhere common type Storage interface { - apiserver.RESTGracefulDeleter - apiserver.RESTLister - apiserver.RESTGetter - apiserver.ResourceWatcher + rest.GracefulDeleter + rest.Lister + rest.Getter + rest.Watcher Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) diff --git a/pkg/registry/pod/etcd/etcd_test.go b/pkg/registry/pod/etcd/etcd_test.go index a54ed295c09..9159a55c8f4 100644 --- a/pkg/registry/pod/etcd/etcd_test.go +++ b/pkg/registry/pod/etcd/etcd_test.go @@ -26,8 +26,8 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" etcderrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" @@ -682,7 +682,7 @@ func TestResourceLocation(t *testing.T) { cache := &fakeCache{statusToReturn: &api.PodStatus{PodIP: expectedIP}} storage = storage.WithPodStatus(cache) - redirector := apiserver.Redirector(storage) + redirector := rest.Redirector(storage) location, err := redirector.ResourceLocation(api.NewDefaultContext(), tc.query) if err != nil { t.Errorf("Unexpected error: %v", err) diff --git a/pkg/registry/pod/registry.go b/pkg/registry/pod/registry.go index 338be13aeff..f65aaa5690e 100644 --- a/pkg/registry/pod/registry.go +++ b/pkg/registry/pod/registry.go @@ -18,7 +18,7 @@ package pod import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -44,10 +44,10 @@ type Registry interface { // Storage is an interface for a standard REST Storage backend // TODO: move me somewhere common type Storage interface { - apiserver.RESTGracefulDeleter - apiserver.RESTLister - apiserver.RESTGetter - apiserver.ResourceWatcher + rest.GracefulDeleter + rest.Lister + rest.Getter + rest.Watcher Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) diff --git a/pkg/registry/resourcequota/registry.go b/pkg/registry/resourcequota/registry.go index 86135c961fd..5fe29686edd 100644 --- a/pkg/registry/resourcequota/registry.go +++ b/pkg/registry/resourcequota/registry.go @@ -18,7 +18,7 @@ package resourcequota import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -44,10 +44,10 @@ type Registry interface { // Storage is an interface for a standard REST Storage backend // TODO: move me somewhere common type Storage interface { - apiserver.RESTGracefulDeleter - apiserver.RESTLister - apiserver.RESTGetter - apiserver.ResourceWatcher + rest.GracefulDeleter + rest.Lister + rest.Getter + rest.Watcher Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) diff --git a/pkg/registry/secret/rest_test.go b/pkg/registry/secret/rest_test.go index d035304fb90..798b3be09ac 100644 --- a/pkg/registry/secret/rest_test.go +++ b/pkg/registry/secret/rest_test.go @@ -21,7 +21,7 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" @@ -73,8 +73,8 @@ func TestRESTCreate(t *testing.T) { } for _, item := range table { - _, rest := NewTestREST() - c, err := rest.Create(item.ctx, item.secret) + _, storage := NewTestREST() + c, err := storage.Create(item.ctx, item.secret) if !item.valid { if err == nil { ctxNS := api.NamespaceValue(item.ctx) @@ -93,7 +93,7 @@ func TestRESTCreate(t *testing.T) { t.Errorf("diff: %s", util.ObjectDiff(e, a)) } // Ensure we implement the interface - _ = apiserver.ResourceWatcher(rest) + _ = rest.Watcher(storage) } } diff --git a/pkg/registry/service/rest.go b/pkg/registry/service/rest.go index fef7d518e3b..793886551d0 100644 --- a/pkg/registry/service/rest.go +++ b/pkg/registry/service/rest.go @@ -174,7 +174,7 @@ func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Select } // Watch returns Services events via a watch.Interface. -// It implements apiserver.ResourceWatcher. +// It implements rest.Watcher. func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { return rs.registry.WatchServices(ctx, label, field, resourceVersion) } diff --git a/pkg/registry/service/rest_test.go b/pkg/registry/service/rest_test.go index 9f26509fed4..e8ffe087e06 100644 --- a/pkg/registry/service/rest_test.go +++ b/pkg/registry/service/rest_test.go @@ -24,8 +24,8 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" - "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" @@ -384,7 +384,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) { Selector: map[string]string{"bar": "baz"}, }, }) - redirector := apiserver.Redirector(storage) + redirector := rest.Redirector(storage) location, err := redirector.ResourceLocation(ctx, "foo") if err != nil { t.Errorf("Unexpected error: %v", err)