mirror of
https://github.com/rancher/steve.git
synced 2025-09-17 15:58:41 +00:00
Respect CreateOptions in ext.CreateOrUpdate (#623)
This commit is contained in:
committed by
GitHub
parent
e3b881f13a
commit
9121a52d5d
@@ -58,7 +58,7 @@ func (t *authzTestStore) List(ctx context.Context, _ *metainternalversion.ListOp
|
|||||||
decision, _, err := t.authorizer.Authorize(ctx, authorizer.AttributesRecord{
|
decision, _, err := t.authorizer.Authorize(ctx, authorizer.AttributesRecord{
|
||||||
User: userInfo,
|
User: userInfo,
|
||||||
Verb: "customverb",
|
Verb: "customverb",
|
||||||
Resource: "testtypes",
|
Resource: testTypeResource,
|
||||||
ResourceRequest: true,
|
ResourceRequest: true,
|
||||||
APIGroup: "ext.cattle.io",
|
APIGroup: "ext.cattle.io",
|
||||||
})
|
})
|
||||||
@@ -162,7 +162,7 @@ func (s *ExtensionAPIServerSuite) TestAuthorization() {
|
|||||||
testStore: newDefaultTestStore(),
|
testStore: newDefaultTestStore(),
|
||||||
authorizer: s.GetAuthorizer(),
|
authorizer: s.GetAuthorizer(),
|
||||||
}
|
}
|
||||||
err := s.Install("testtypes", testTypeGV.WithKind("TestType"), store)
|
err := s.Install(testTypeResource, testTypeGV.WithKind("TestType"), store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -65,7 +65,7 @@ func TestStore(t *testing.T) {
|
|||||||
ts := httptest.NewServer(extensionAPIServer)
|
ts := httptest.NewServer(extensionAPIServer)
|
||||||
defer ts.Close()
|
defer ts.Close()
|
||||||
|
|
||||||
recWatch, err := createRecordingWatcher(scheme, testTypeGV.WithResource("testtypes"), ts.URL)
|
recWatch, err := createRecordingWatcher(scheme, testTypeGVR, ts.URL)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
updatedObj := testTypeFixture.DeepCopy()
|
updatedObj := testTypeFixture.DeepCopy()
|
||||||
@@ -306,35 +306,35 @@ func TestDiscoveryAndOpenAPI(t *testing.T) {
|
|||||||
objT: &TestTypeOther{},
|
objT: &TestTypeOther{},
|
||||||
objListT: &TestTypeOtherList{},
|
objListT: &TestTypeOtherList{},
|
||||||
gvk: testTypeGV.WithKind("TestTypeOther"),
|
gvk: testTypeGV.WithKind("TestTypeOther"),
|
||||||
gvr: schema.GroupVersionResource{Group: testTypeGV.Group, Version: testTypeGV.Version, Resource: "testtypes"},
|
gvr: schema.GroupVersionResource{Group: testTypeGV.Group, Version: testTypeGV.Version, Resource: "testtypeothers"},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Install("testtypes", differentVersion.WithKind("TestType"), &testStore[*TestType, *TestTypeList]{
|
err = s.Install(testTypeResource, differentVersion.WithKind("TestType"), &testStore[*TestType, *TestTypeList]{
|
||||||
singular: "testtype",
|
singular: "testtype",
|
||||||
objT: &TestType{},
|
objT: &TestType{},
|
||||||
objListT: &TestTypeList{},
|
objListT: &TestTypeList{},
|
||||||
gvk: differentVersion.WithKind("TestType"),
|
gvk: differentVersion.WithKind("TestType"),
|
||||||
gvr: schema.GroupVersionResource{Group: differentVersion.Group, Version: differentVersion.Version, Resource: "testtypes"},
|
gvr: schema.GroupVersionResource{Group: differentVersion.Group, Version: differentVersion.Version, Resource: testTypeResource},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Install("testtypes", differentGroupVersion.WithKind("TestType"), &testStore[*TestType, *TestTypeList]{
|
err = s.Install(testTypeResource, differentGroupVersion.WithKind("TestType"), &testStore[*TestType, *TestTypeList]{
|
||||||
singular: "testtype",
|
singular: "testtype",
|
||||||
objT: &TestType{},
|
objT: &TestType{},
|
||||||
objListT: &TestTypeList{},
|
objListT: &TestTypeList{},
|
||||||
gvk: differentGroupVersion.WithKind("TestType"),
|
gvk: differentGroupVersion.WithKind("TestType"),
|
||||||
gvr: schema.GroupVersionResource{Group: differentGroupVersion.Group, Version: differentVersion.Version, Resource: "testtypes"},
|
gvr: schema.GroupVersionResource{Group: differentGroupVersion.Group, Version: differentVersion.Version, Resource: testTypeResource},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Install("testtypes", partialGroupVersion.WithKind("TestType"), &partialStorage{
|
err = s.Install(testTypeResource, partialGroupVersion.WithKind("TestType"), &partialStorage{
|
||||||
gvk: partialGroupVersion.WithKind("TestType"),
|
gvk: partialGroupVersion.WithKind("TestType"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -482,7 +482,7 @@ func TestDiscoveryAndOpenAPI(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testtypes",
|
Name: testTypeResource,
|
||||||
SingularName: "testtype",
|
SingularName: "testtype",
|
||||||
Namespaced: false,
|
Namespaced: false,
|
||||||
Kind: "TestType",
|
Kind: "TestType",
|
||||||
@@ -507,7 +507,7 @@ func TestDiscoveryAndOpenAPI(t *testing.T) {
|
|||||||
GroupVersion: "ext.cattle.io/v2",
|
GroupVersion: "ext.cattle.io/v2",
|
||||||
APIResources: []metav1.APIResource{
|
APIResources: []metav1.APIResource{
|
||||||
{
|
{
|
||||||
Name: "testtypes",
|
Name: testTypeResource,
|
||||||
SingularName: "testtype",
|
SingularName: "testtype",
|
||||||
Namespaced: false,
|
Namespaced: false,
|
||||||
Kind: "TestType",
|
Kind: "TestType",
|
||||||
@@ -532,7 +532,7 @@ func TestDiscoveryAndOpenAPI(t *testing.T) {
|
|||||||
GroupVersion: "ext2.cattle.io/v3",
|
GroupVersion: "ext2.cattle.io/v3",
|
||||||
APIResources: []metav1.APIResource{
|
APIResources: []metav1.APIResource{
|
||||||
{
|
{
|
||||||
Name: "testtypes",
|
Name: testTypeResource,
|
||||||
SingularName: "testtype",
|
SingularName: "testtype",
|
||||||
Namespaced: false,
|
Namespaced: false,
|
||||||
Kind: "TestType",
|
Kind: "TestType",
|
||||||
@@ -557,7 +557,7 @@ func TestDiscoveryAndOpenAPI(t *testing.T) {
|
|||||||
GroupVersion: "ext.cattle.io/v4",
|
GroupVersion: "ext.cattle.io/v4",
|
||||||
APIResources: []metav1.APIResource{
|
APIResources: []metav1.APIResource{
|
||||||
{
|
{
|
||||||
Name: "testtypes",
|
Name: testTypeResource,
|
||||||
SingularName: "testtype",
|
SingularName: "testtype",
|
||||||
Namespaced: false,
|
Namespaced: false,
|
||||||
Kind: "TestType",
|
Kind: "TestType",
|
||||||
@@ -674,7 +674,7 @@ func setupExtensionAPIServer(
|
|||||||
extensionAPIServerSetter func(*ExtensionAPIServer) error,
|
extensionAPIServerSetter func(*ExtensionAPIServer) error,
|
||||||
) (*ExtensionAPIServer, error) {
|
) (*ExtensionAPIServer, error) {
|
||||||
fn := func(e *ExtensionAPIServer) error {
|
fn := func(e *ExtensionAPIServer) error {
|
||||||
err := e.Install("testtypes", testTypeGV.WithKind("TestType"), store)
|
err := e.Install(testTypeResource, testTypeGV.WithKind("TestType"), store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("InstallStore: %w", err)
|
return fmt.Errorf("InstallStore: %w", err)
|
||||||
}
|
}
|
||||||
@@ -822,7 +822,7 @@ func TestCustomColumns(t *testing.T) {
|
|||||||
opts.Authorizer = authorizer.AuthorizerFunc(authzAllowAll)
|
opts.Authorizer = authorizer.AuthorizerFunc(authzAllowAll)
|
||||||
opts.Authenticator = authenticator.RequestFunc(authAsAdmin)
|
opts.Authenticator = authenticator.RequestFunc(authAsAdmin)
|
||||||
}, func(s *ExtensionAPIServer) error {
|
}, func(s *ExtensionAPIServer) error {
|
||||||
err := s.Install("testtypes", testTypeGV.WithKind("TestType"), store)
|
err := s.Install(testTypeResource, testTypeGV.WithKind("TestType"), store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -34,11 +34,19 @@ func addKnownTypesTest(scheme *runtime.Scheme) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
testTypeResource = "testtypes"
|
||||||
|
|
||||||
testTypeGV = schema.GroupVersion{
|
testTypeGV = schema.GroupVersion{
|
||||||
Group: "ext.cattle.io",
|
Group: "ext.cattle.io",
|
||||||
Version: "v1",
|
Version: "v1",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testTypeGVR = schema.GroupVersionResource{
|
||||||
|
Group: testTypeGV.Group,
|
||||||
|
Version: testTypeGV.Version,
|
||||||
|
Resource: testTypeResource,
|
||||||
|
}
|
||||||
|
|
||||||
testTypeListFixture = TestTypeList{
|
testTypeListFixture = TestTypeList{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
Kind: "TestTypeList",
|
Kind: "TestTypeList",
|
||||||
@@ -103,7 +111,6 @@ func (in *TestTypeList) DeepCopyInto(out *TestTypeList) {
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (in *TestTypeList) DeepCopy() *TestTypeList {
|
func (in *TestTypeList) DeepCopy() *TestTypeList {
|
||||||
@@ -131,7 +138,6 @@ func (in *TestType) DeepCopyInto(out *TestType) {
|
|||||||
*out = *in
|
*out = *in
|
||||||
out.TypeMeta = in.TypeMeta
|
out.TypeMeta = in.TypeMeta
|
||||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (in *TestType) DeepCopy() *TestType {
|
func (in *TestType) DeepCopy() *TestType {
|
||||||
@@ -196,7 +202,7 @@ func newDefaultTestStore() *testStore[*TestType, *TestTypeList] {
|
|||||||
objT: &TestType{},
|
objT: &TestType{},
|
||||||
objListT: &TestTypeList{},
|
objListT: &TestTypeList{},
|
||||||
gvk: testTypeGV.WithKind("TestType"),
|
gvk: testTypeGV.WithKind("TestType"),
|
||||||
gvr: schema.GroupVersionResource{Group: testTypeGV.Group, Version: testTypeGV.Version, Resource: "testtypes"},
|
gvr: testTypeGVR,
|
||||||
items: map[string]*TestType{
|
items: map[string]*TestType{
|
||||||
testTypeFixture.Name: &testTypeFixture,
|
testTypeFixture.Name: &testTypeFixture,
|
||||||
},
|
},
|
||||||
|
@@ -138,7 +138,11 @@ func CreateOrUpdate[T runtime.Object](
|
|||||||
return nil, false, convertError(fmt.Errorf("object was of type %T, not of expected type %T", obj, zeroT))
|
return nil, false, convertError(fmt.Errorf("object was of type %T, not of expected type %T", obj, zeroT))
|
||||||
}
|
}
|
||||||
|
|
||||||
newObj, err := createFn(ctx, tObj, &metav1.CreateOptions{})
|
newObj, err := createFn(ctx, tObj, &metav1.CreateOptions{
|
||||||
|
DryRun: options.DryRun,
|
||||||
|
FieldManager: options.FieldManager,
|
||||||
|
FieldValidation: options.FieldValidation,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, convertError(err)
|
return nil, false, convertError(err)
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,17 @@
|
|||||||
package ext
|
package ext
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConvertListOptions(t *testing.T) {
|
func TestConvertListOptions(t *testing.T) {
|
||||||
@@ -67,3 +70,79 @@ func TestConvertError(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fakeUpdatedObjectInfo struct {
|
||||||
|
obj runtime.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeUpdatedObjectInfo) UpdatedObject(ctx context.Context, oldObj runtime.Object) (runtime.Object, error) {
|
||||||
|
return f.obj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeUpdatedObjectInfo) Preconditions() *metav1.Preconditions {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateOrUpdate(t *testing.T) {
|
||||||
|
t.Run("create options are respected", func(t *testing.T) {
|
||||||
|
var createValidationCalled bool
|
||||||
|
createValidation := func(ctx context.Context, obj runtime.Object) error {
|
||||||
|
createValidationCalled = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateValidationCalled bool
|
||||||
|
updateValidation := func(ctx context.Context, obj runtime.Object, oldObj runtime.Object) error {
|
||||||
|
updateValidationCalled = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
forceAllowCreate := false
|
||||||
|
|
||||||
|
options := &metav1.UpdateOptions{
|
||||||
|
DryRun: []string{"All"},
|
||||||
|
FieldManager: "test",
|
||||||
|
FieldValidation: metav1.FieldValidationStrict,
|
||||||
|
}
|
||||||
|
|
||||||
|
getFn := func(ctx context.Context, name string, opts *metav1.GetOptions) (*TestType, error) {
|
||||||
|
return nil, apierrors.NewNotFound(testTypeGVR.GroupResource(), name)
|
||||||
|
}
|
||||||
|
|
||||||
|
var createFnCalled bool
|
||||||
|
createFn := func(ctx context.Context, obj *TestType, opts *metav1.CreateOptions) (*TestType, error) {
|
||||||
|
createFnCalled = true
|
||||||
|
|
||||||
|
require.NotNil(t, opts)
|
||||||
|
assert.Equal(t, options.DryRun, opts.DryRun)
|
||||||
|
assert.Equal(t, options.FieldManager, opts.FieldManager)
|
||||||
|
assert.Equal(t, options.FieldValidation, opts.FieldValidation)
|
||||||
|
|
||||||
|
return obj.DeepCopy(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateFnCalled bool
|
||||||
|
updateFn := func(ctx context.Context, obj *TestType, opts *metav1.UpdateOptions) (*TestType, error) {
|
||||||
|
updateFnCalled = true
|
||||||
|
return obj.DeepCopy(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
objInfo := &fakeUpdatedObjectInfo{
|
||||||
|
obj: &TestType{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
obj, isCreated, err := CreateOrUpdate(context.Background(), "foo", objInfo, createValidation, updateValidation, forceAllowCreate, options, getFn, createFn, updateFn)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotNil(t, obj)
|
||||||
|
assert.True(t, isCreated)
|
||||||
|
|
||||||
|
assert.True(t, createValidationCalled)
|
||||||
|
assert.False(t, updateValidationCalled)
|
||||||
|
assert.True(t, createFnCalled)
|
||||||
|
assert.False(t, updateFnCalled)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user