diff --git a/Makefile b/Makefile index 88f2fbb..b354d4c 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,9 @@ mocks: install-mockery ## Build mocks @echo -n "building mocks for sigs.k8s.io/controller-runtime/pkg/client ... " @bin/mockery --quiet --name="(Object|Client|Status|Reader|SubResourceWriter)" --case=underscore --output=mocks/controller-runtime/pkg/client --dir="$(CONTROLLER_RUNTIME_DIR)/pkg/client" @echo "ok." + @echo -n "building mocks for sigs.k8s.io/controller-runtime/pkg/cache ... " + @bin/mockery --quiet --name="(Cache)" --case=underscore --output=mocks/controller-runtime/pkg/cache --dir="$(CONTROLLER_RUNTIME_DIR)/pkg/cache" + @echo "ok." help: ## Show this help. @grep -F -h "##" $(MAKEFILE_LIST) | grep -F -v grep | sed -e 's/\\$$//' \ diff --git a/apis/core/v1alpha1/annotations.go b/apis/core/v1alpha1/annotations.go index 27c7673..4b4c40e 100644 --- a/apis/core/v1alpha1/annotations.go +++ b/apis/core/v1alpha1/annotations.go @@ -82,7 +82,7 @@ const ( // ACK service controller. AnnotationReadOnly = AnnotationPrefix + "read-only" // AnnotationAdoptionPolicy is an annotation whose value is the identifier for whether - // we will attempt adoption only (value = adopt-only) or attempt a create if resource + // we will attempt adoption only (value = adopt-only) or attempt a create if resource // is not found (value adopt-or-create). // // NOTE (michaelhtm): Currently create-or-adopt is not supported diff --git a/mocks/controller-runtime/pkg/cache/cache.go b/mocks/controller-runtime/pkg/cache/cache.go new file mode 100644 index 0000000..3681484 --- /dev/null +++ b/mocks/controller-runtime/pkg/cache/cache.go @@ -0,0 +1,231 @@ +// Code generated by mockery v2.53.3. DO NOT EDIT. + +package mocks + +import ( + cache "sigs.k8s.io/controller-runtime/pkg/cache" + client "sigs.k8s.io/controller-runtime/pkg/client" + + context "context" + + mock "github.com/stretchr/testify/mock" + + schema "k8s.io/apimachinery/pkg/runtime/schema" + + types "k8s.io/apimachinery/pkg/types" +) + +// Cache is an autogenerated mock type for the Cache type +type Cache struct { + mock.Mock +} + +// Get provides a mock function with given fields: ctx, key, obj, opts +func (_m *Cache) Get(ctx context.Context, key types.NamespacedName, obj client.Object, opts ...client.GetOption) error { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, key, obj) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, types.NamespacedName, client.Object, ...client.GetOption) error); ok { + r0 = rf(ctx, key, obj, opts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetInformer provides a mock function with given fields: ctx, obj, opts +func (_m *Cache) GetInformer(ctx context.Context, obj client.Object, opts ...cache.InformerGetOption) (cache.Informer, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, obj) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetInformer") + } + + var r0 cache.Informer + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, client.Object, ...cache.InformerGetOption) (cache.Informer, error)); ok { + return rf(ctx, obj, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, client.Object, ...cache.InformerGetOption) cache.Informer); ok { + r0 = rf(ctx, obj, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cache.Informer) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, client.Object, ...cache.InformerGetOption) error); ok { + r1 = rf(ctx, obj, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetInformerForKind provides a mock function with given fields: ctx, gvk, opts +func (_m *Cache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...cache.InformerGetOption) (cache.Informer, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, gvk) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetInformerForKind") + } + + var r0 cache.Informer + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, schema.GroupVersionKind, ...cache.InformerGetOption) (cache.Informer, error)); ok { + return rf(ctx, gvk, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, schema.GroupVersionKind, ...cache.InformerGetOption) cache.Informer); ok { + r0 = rf(ctx, gvk, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cache.Informer) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, schema.GroupVersionKind, ...cache.InformerGetOption) error); ok { + r1 = rf(ctx, gvk, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// IndexField provides a mock function with given fields: ctx, obj, field, extractValue +func (_m *Cache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { + ret := _m.Called(ctx, obj, field, extractValue) + + if len(ret) == 0 { + panic("no return value specified for IndexField") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, client.Object, string, client.IndexerFunc) error); ok { + r0 = rf(ctx, obj, field, extractValue) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// List provides a mock function with given fields: ctx, list, opts +func (_m *Cache) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, list) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for List") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, client.ObjectList, ...client.ListOption) error); ok { + r0 = rf(ctx, list, opts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// RemoveInformer provides a mock function with given fields: ctx, obj +func (_m *Cache) RemoveInformer(ctx context.Context, obj client.Object) error { + ret := _m.Called(ctx, obj) + + if len(ret) == 0 { + panic("no return value specified for RemoveInformer") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, client.Object) error); ok { + r0 = rf(ctx, obj) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Start provides a mock function with given fields: ctx +func (_m *Cache) Start(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Start") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WaitForCacheSync provides a mock function with given fields: ctx +func (_m *Cache) WaitForCacheSync(ctx context.Context) bool { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for WaitForCacheSync") + } + + var r0 bool + if rf, ok := ret.Get(0).(func(context.Context) bool); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// NewCache creates a new instance of Cache. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCache(t interface { + mock.TestingT + Cleanup(func()) +}) *Cache { + mock := &Cache{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/controller-runtime/pkg/cache/new_cache_func.go b/mocks/controller-runtime/pkg/cache/new_cache_func.go new file mode 100644 index 0000000..502380e --- /dev/null +++ b/mocks/controller-runtime/pkg/cache/new_cache_func.go @@ -0,0 +1,47 @@ +// Code generated by mockery v2.53.3. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + cache "sigs.k8s.io/controller-runtime/pkg/cache" +) + +// newCacheFunc is an autogenerated mock type for the newCacheFunc type +type newCacheFunc struct { + mock.Mock +} + +// Execute provides a mock function with given fields: config, namespace +func (_m *newCacheFunc) Execute(config cache.Config, namespace string) cache.Cache { + ret := _m.Called(config, namespace) + + if len(ret) == 0 { + panic("no return value specified for Execute") + } + + var r0 cache.Cache + if rf, ok := ret.Get(0).(func(cache.Config, string) cache.Cache); ok { + r0 = rf(config, namespace) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cache.Cache) + } + } + + return r0 +} + +// newNewCacheFunc creates a new instance of newCacheFunc. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func newNewCacheFunc(t interface { + mock.TestingT + Cleanup(func()) +}) *newCacheFunc { + mock := &newCacheFunc{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/condition/condition.go b/pkg/condition/condition.go index 208508a..132d1b8 100644 --- a/pkg/condition/condition.go +++ b/pkg/condition/condition.go @@ -29,7 +29,7 @@ var ( NotManagedReason = "This resource already exists but is not managed by ACK. " + "To bring the resource under ACK management, you should explicitly adopt " + "the resource by enabling the ResourceAdoption feature gate and populating " + - "the `services.k8s.aws/adoption-policy` and `services.k8s.aws/adoption-fields` " + + "the `services.k8s.aws/adoption-policy` and `services.k8s.aws/adoption-fields` " + "annotations." UnknownSyncedMessage = "Unable to determine if desired resource state matches latest observed state" NotSyncedMessage = "Resource not synced" diff --git a/pkg/runtime/adoption_reconciler.go b/pkg/runtime/adoption_reconciler.go index 279de76..3ddf7f1 100644 --- a/pkg/runtime/adoption_reconciler.go +++ b/pkg/runtime/adoption_reconciler.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" ctrlrt "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" k8sctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/predicate" @@ -57,7 +58,7 @@ type adoptionReconciler struct { // of an upstream controller-runtime.Manager func (r *adoptionReconciler) BindControllerManager(mgr ctrlrt.Manager) error { r.kc = mgr.GetClient() - r.apiReader = mgr.GetAPIReader() + r.ackResourceCache = mgr.GetCache() return ctrlrt.NewControllerManagedBy( mgr, ).For( @@ -251,7 +252,7 @@ func (r *adoptionReconciler) Sync( // Only create the described resource if it does not already exist // in k8s cluster. - if err := r.apiReader.Get(ctx, types.NamespacedName{ + if err := r.ackResourceCache.Get(ctx, types.NamespacedName{ Namespace: described.MetaObject().GetNamespace(), Name: described.MetaObject().GetName(), }, described.RuntimeObject()); err != nil { @@ -306,7 +307,7 @@ func (r *adoptionReconciler) getAdoptedResource( req ctrlrt.Request, ) (*ackv1alpha1.AdoptedResource, error) { ro := &ackv1alpha1.AdoptedResource{} - // Here we use k8s APIReader to read the k8s object by making the + // Here we use k8s ACKResourceCache to read the k8s object by making the // direct call to k8s apiserver instead of using k8sClient. // The reason is that k8sClient uses a cache and sometimes k8sClient can // return stale copy of object. @@ -314,7 +315,7 @@ func (r *adoptionReconciler) getAdoptedResource( // making single read call for complete reconciler loop. // See following issue for more details: // https://github.com/aws-controllers-k8s/community/issues/894 - if err := r.apiReader.Get(ctx, req.NamespacedName, ro); err != nil { + if err := r.ackResourceCache.Get(ctx, req.NamespacedName, ro); err != nil { return nil, err } return ro, nil @@ -615,17 +616,17 @@ func NewAdoptionReconcilerWithClient( metrics *ackmetrics.Metrics, cache ackrtcache.Caches, kc client.Client, - apiReader client.Reader, + ackResourceCache cache.Cache, ) acktypes.AdoptedResourceReconciler { return &adoptionReconciler{ reconciler: reconciler{ - sc: sc, - log: log.WithName("adopted-reconciler"), - cfg: cfg, - metrics: metrics, - cache: cache, - kc: kc, - apiReader: apiReader, + sc: sc, + log: log.WithName("adopted-reconciler"), + cfg: cfg, + metrics: metrics, + cache: cache, + kc: kc, + ackResourceCache: ackResourceCache, }, } } diff --git a/pkg/runtime/adoption_reconciler_test.go b/pkg/runtime/adoption_reconciler_test.go index 2c21fd1..e241cad 100644 --- a/pkg/runtime/adoption_reconciler_test.go +++ b/pkg/runtime/adoption_reconciler_test.go @@ -29,6 +29,7 @@ import ( ctrlrtzap "sigs.k8s.io/controller-runtime/pkg/log/zap" ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1" + ctrlrtcachemock "github.com/aws-controllers-k8s/runtime/mocks/controller-runtime/pkg/cache" ctrlrtclientmock "github.com/aws-controllers-k8s/runtime/mocks/controller-runtime/pkg/client" ackmocks "github.com/aws-controllers-k8s/runtime/mocks/pkg/types" ackcfg "github.com/aws-controllers-k8s/runtime/pkg/config" @@ -45,7 +46,7 @@ const ( // Helper functions for tests -func mockAdoptionReconciler() (acktypes.AdoptedResourceReconciler, *ctrlrtclientmock.Client, *ctrlrtclientmock.Reader) { +func mockAdoptionReconciler() (acktypes.AdoptedResourceReconciler, *ctrlrtclientmock.Client, *ctrlrtcachemock.Cache) { zapOptions := ctrlrtzap.Options{ Development: true, Level: zapcore.InfoLevel, @@ -60,7 +61,7 @@ func mockAdoptionReconciler() (acktypes.AdoptedResourceReconciler, *ctrlrtclient rmFactoryMap["services.k8s.aws"] = &rmfactory sc.On("GetResourceManagerFactories").Return(rmFactoryMap) kc := &ctrlrtclientmock.Client{} - apiReader := &ctrlrtclientmock.Reader{} + ackResourceCache := &ctrlrtcachemock.Cache{} return ackrt.NewAdoptionReconcilerWithClient( sc, fakeLogger, @@ -68,8 +69,8 @@ func mockAdoptionReconciler() (acktypes.AdoptedResourceReconciler, *ctrlrtclient metrics, ackrtcache.Caches{}, kc, - apiReader, - ), kc, apiReader + ackResourceCache, + ), kc, ackResourceCache } func mockDescriptorAndAWSResource() (*ackmocks.AWSResourceDescriptor, *ackmocks.AWSResource, *ackmocks.AWSResource) { @@ -126,8 +127,8 @@ func setupMockDescriptor(descriptor *ackmocks.AWSResourceDescriptor, res *ackmoc descriptor.On("MarkAdopted", res).Run(func(args mock.Arguments) {}) } -func setupMockApiReaderForAdoptedResource(apiReader *ctrlrtclientmock.Reader, ctx context.Context, res *ackmocks.AWSResource) { - apiReader.On("Get", ctx, types.NamespacedName{ +func setupMockACKResourceCacheForAdoptedResource(ackResourceCache *ctrlrtcachemock.Cache, ctx context.Context, res *ackmocks.AWSResource) { + ackResourceCache.On("Get", ctx, types.NamespacedName{ Namespace: AdoptedResourceNamespace, Name: AdoptedResourceName, }, res.RuntimeObject()).Return(k8serrors.NewNotFound(schema.GroupResource{}, "")) @@ -154,7 +155,7 @@ func TestSync_FailureInSettingIdentifiers(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockAdoptionReconciler() + r, kc, ackResourcesCache := mockAdoptionReconciler() descriptor, res, resDeepCopy := mockDescriptorAndAWSResource() manager := mockManager() adoptedRes := adoptedResource(AdoptedResourceNamespace, AdoptedResourceName) @@ -179,7 +180,7 @@ func TestSync_FailureInSettingIdentifiers(t *testing.T) { // of SetIdentifiers failure manager.AssertNotCalled(t, "ReadOne", ctx, res) // No calls to findout if the AWSResource already exists - apiReader.AssertNotCalled(t, "Get", ctx, types.NamespacedName{ + ackResourcesCache.AssertNotCalled(t, "Get", ctx, types.NamespacedName{ Namespace: AdoptedResourceNamespace, Name: AdoptedResourceName, }, res.RuntimeObject()) @@ -192,7 +193,7 @@ func TestSync_FailureInReadOne(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockAdoptionReconciler() + r, kc, ackResourceCache := mockAdoptionReconciler() descriptor, res, resDeepCopy := mockDescriptorAndAWSResource() manager := mockManager() adoptedRes := adoptedResource(AdoptedResourceNamespace, AdoptedResourceName) @@ -216,7 +217,7 @@ func TestSync_FailureInReadOne(t *testing.T) { manager.AssertCalled(t, "ReadOne", ctx, res) // No calls to findout if the AWSResource already exists because of ReadOne // failure - apiReader.AssertNotCalled(t, "Get", ctx, types.NamespacedName{ + ackResourceCache.AssertNotCalled(t, "Get", ctx, types.NamespacedName{ Namespace: AdoptedResourceNamespace, Name: AdoptedResourceName, }, res.RuntimeObject()) @@ -229,7 +230,7 @@ func TestSync_AWSResourceAlreadyExists(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockAdoptionReconciler() + r, kc, ackResourceCache := mockAdoptionReconciler() descriptor, res, resDeepCopy := mockDescriptorAndAWSResource() manager := mockManager() adoptedRes := adoptedResource(AdoptedResourceNamespace, AdoptedResourceName) @@ -242,7 +243,7 @@ func TestSync_AWSResourceAlreadyExists(t *testing.T) { setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) - apiReader.On("Get", ctx, types.NamespacedName{ + ackResourceCache.On("Get", ctx, types.NamespacedName{ Namespace: AdoptedResourceNamespace, Name: AdoptedResourceName, }, res.RuntimeObject()).Return(nil) @@ -252,17 +253,17 @@ func TestSync_AWSResourceAlreadyExists(t *testing.T) { //Assertions require.Nil(err) - assertAWSResourceRead(t, ctx, manager, apiReader, adoptedRes, res) + assertAWSResourceRead(t, ctx, manager, ackResourceCache, adoptedRes, res) assertAWSResourceCreation(false, t, ctx, kc, statusWriter, res, resDeepCopy) assertAdoptedResourceManaged(true, t, ctx, kc, adoptedRes) assertAdoptedCondition("True", require, t, ctx, kc, statusWriter, adoptedRes) } -func TestSync_APIReaderUnknownError(t *testing.T) { +func TestSync_ACKResourceCacheUnknownError(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockAdoptionReconciler() + r, kc, ackResourceCache := mockAdoptionReconciler() descriptor, res, resDeepCopy := mockDescriptorAndAWSResource() manager := mockManager() adoptedRes := adoptedResource(AdoptedResourceNamespace, AdoptedResourceName) @@ -275,7 +276,7 @@ func TestSync_APIReaderUnknownError(t *testing.T) { setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) - apiReader.On("Get", ctx, types.NamespacedName{ + ackResourceCache.On("Get", ctx, types.NamespacedName{ Namespace: AdoptedResourceNamespace, Name: AdoptedResourceName, }, res.RuntimeObject()).Return(errors.New("unknown error")) @@ -286,7 +287,7 @@ func TestSync_APIReaderUnknownError(t *testing.T) { //Assertions require.NotNil(err) require.Equal("unknown error", err.Error()) - assertAWSResourceRead(t, ctx, manager, apiReader, adoptedRes, res) + assertAWSResourceRead(t, ctx, manager, ackResourceCache, adoptedRes, res) assertAWSResourceCreation(false, t, ctx, kc, statusWriter, res, resDeepCopy) assertAdoptedResourceManaged(false, t, ctx, kc, adoptedRes) assertAdoptedCondition("False", require, t, ctx, kc, statusWriter, adoptedRes) @@ -296,7 +297,7 @@ func TestSync_ErrorInResourceCreation(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockAdoptionReconciler() + r, kc, ackResourceCache := mockAdoptionReconciler() descriptor, res, resDeepCopy := mockDescriptorAndAWSResource() manager := mockManager() adoptedRes := adoptedResource(AdoptedResourceNamespace, AdoptedResourceName) @@ -308,7 +309,7 @@ func TestSync_ErrorInResourceCreation(t *testing.T) { setupMockClientForAdoptedResource(kc, statusWriter, ctx, adoptedRes) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) - setupMockApiReaderForAdoptedResource(apiReader, ctx, res) + setupMockACKResourceCacheForAdoptedResource(ackResourceCache, ctx, res) kc.On("Create", ctx, res.RuntimeObject()).Return(errors.New("creation failure")) // Call @@ -317,7 +318,7 @@ func TestSync_ErrorInResourceCreation(t *testing.T) { //Assertions require.NotNil(err) require.Equal("creation failure", err.Error()) - assertAWSResourceRead(t, ctx, manager, apiReader, adoptedRes, res) + assertAWSResourceRead(t, ctx, manager, ackResourceCache, adoptedRes, res) kc.AssertCalled(t, "Create", ctx, res.RuntimeObject()) // Update status of AWSResource should not happen due to creation failure statusWriter.AssertNotCalled(t, "Update", ctx, res.RuntimeObject()) @@ -329,7 +330,7 @@ func TestSync_ErrorInStatusUpdate(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockAdoptionReconciler() + r, kc, ackResourceCache := mockAdoptionReconciler() descriptor, res, resDeepCopy := mockDescriptorAndAWSResource() manager := mockManager() adoptedRes := adoptedResource(AdoptedResourceNamespace, AdoptedResourceName) @@ -341,7 +342,7 @@ func TestSync_ErrorInStatusUpdate(t *testing.T) { setupMockClientForAdoptedResource(kc, statusWriter, ctx, adoptedRes) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) - setupMockApiReaderForAdoptedResource(apiReader, ctx, res) + setupMockACKResourceCacheForAdoptedResource(ackResourceCache, ctx, res) kc.On("Create", ctx, res.RuntimeObject()).Return(nil) statusWriter.On("Update", ctx, res.RuntimeObject()).Return(errors.New("status update failure")) @@ -351,7 +352,7 @@ func TestSync_ErrorInStatusUpdate(t *testing.T) { //Assertions require.NotNil(err) require.Equal("status update failure", err.Error()) - assertAWSResourceRead(t, ctx, manager, apiReader, adoptedRes, res) + assertAWSResourceRead(t, ctx, manager, ackResourceCache, adoptedRes, res) assertAWSResourceCreation(true, t, ctx, kc, statusWriter, res, resDeepCopy) assertAdoptedResourceManaged(false, t, ctx, kc, adoptedRes) assertAdoptedCondition("False", require, t, ctx, kc, statusWriter, adoptedRes) @@ -361,7 +362,7 @@ func TestSync_HappyCase(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockAdoptionReconciler() + r, kc, ackResourceCache := mockAdoptionReconciler() descriptor, res, resDeepCopy := mockDescriptorAndAWSResource() manager := mockManager() adoptedRes := adoptedResource(AdoptedResourceNamespace, AdoptedResourceName) @@ -373,7 +374,7 @@ func TestSync_HappyCase(t *testing.T) { setupMockClientForAdoptedResource(kc, statusWriter, ctx, adoptedRes) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) - setupMockApiReaderForAdoptedResource(apiReader, ctx, res) + setupMockACKResourceCacheForAdoptedResource(ackResourceCache, ctx, res) kc.On("Create", ctx, res.RuntimeObject()).Return(nil) statusWriter.On("Update", ctx, res.RuntimeObject()).Return(nil) @@ -382,7 +383,7 @@ func TestSync_HappyCase(t *testing.T) { //Assertions require.Nil(err) - assertAWSResourceRead(t, ctx, manager, apiReader, adoptedRes, res) + assertAWSResourceRead(t, ctx, manager, ackResourceCache, adoptedRes, res) assertAWSResourceCreation(true, t, ctx, kc, statusWriter, res, resDeepCopy) assertAdoptedResourceManaged(true, t, ctx, kc, adoptedRes) assertAdoptedCondition("True", require, t, ctx, kc, statusWriter, adoptedRes) @@ -456,19 +457,19 @@ func assertAWSResourceCreation( // assertAWSResourceRead asserts that // a) Identifiers are set from AdoptedResource to AWSResource // b) ReadOne call is made to find observed state of AWSResource -// c) APIReader.Get call is made to validate that AWSResource does not already +// c) ACKResourceCache.Get call is made to validate that AWSResource does not already // exist in k8s cluster func assertAWSResourceRead( t *testing.T, ctx context.Context, manager *ackmocks.AWSResourceManager, - apiReader *ctrlrtclientmock.Reader, + ackResourceCache *ctrlrtcachemock.Cache, adoptedRes *ackv1alpha1.AdoptedResource, res *ackmocks.AWSResource, ) { res.AssertCalled(t, "SetIdentifiers", adoptedRes.Spec.AWS) manager.AssertCalled(t, "ReadOne", ctx, res) - apiReader.AssertCalled(t, "Get", ctx, types.NamespacedName{ + ackResourceCache.AssertCalled(t, "Get", ctx, types.NamespacedName{ Namespace: AdoptedResourceNamespace, Name: AdoptedResourceName, }, res.RuntimeObject()) diff --git a/pkg/runtime/field_export_reconciler.go b/pkg/runtime/field_export_reconciler.go index 19e8ebd..2b84584 100644 --- a/pkg/runtime/field_export_reconciler.go +++ b/pkg/runtime/field_export_reconciler.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" ctrlrt "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" k8sctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/predicate" @@ -63,7 +64,7 @@ type fieldExportReconciler struct { // CRs func (r *fieldExportReconciler) BindControllerManager(mgr ctrlrt.Manager) error { r.kc = mgr.GetClient() - r.apiReader = mgr.GetAPIReader() + r.ackResourceCache = mgr.GetCache() return ctrlrt.NewControllerManagedBy( mgr, @@ -197,7 +198,7 @@ func (r *fieldExportReconciler) getFieldExport( req ctrlrt.Request, ) (*ackv1alpha1.FieldExport, error) { ro := &ackv1alpha1.FieldExport{} - // Here we use k8s APIReader to read the k8s object by making the + // Here we use k8s ackResourceCache to read the k8s object by making the // direct call to k8s apiserver instead of using k8sClient. // The reason is that k8sClient uses a cache and sometimes k8sClient can // return stale copy of object. @@ -205,7 +206,7 @@ func (r *fieldExportReconciler) getFieldExport( // making single read call for complete reconciler loop. // See following issue for more details: // https://github.com/aws-controllers-k8s/community/issues/894 - if err := r.apiReader.Get(ctx, req.NamespacedName, ro); err != nil { + if err := r.ackResourceCache.Get(ctx, req.NamespacedName, ro); err != nil { return nil, err } return ro, nil @@ -219,7 +220,7 @@ func (r *fieldExportReconciler) getSourceResource( name types.NamespacedName, ) (acktypes.AWSResource, error) { obj := rd.EmptyRuntimeObject() - if err := r.apiReader.Get(ctx, name, obj); err != nil { + if err := r.ackResourceCache.Get(ctx, name, obj); err != nil { return nil, err } res := rd.ResourceFromRuntimeObject(obj) @@ -311,7 +312,7 @@ func (r *fieldExportReconciler) writeToConfigMap( } cm := &corev1.ConfigMap{} - err := r.apiReader.Get(ctx, nsn, cm) + err := r.ackResourceCache.Get(ctx, nsn, cm) if err != nil { return errors.Wrap(err, ackerr.FieldExportMissingConfigMap.Error()) } @@ -358,7 +359,7 @@ func (r *fieldExportReconciler) writeToSecret( } secret := &corev1.Secret{} - err := r.apiReader.Get(ctx, nsn, secret) + err := r.ackResourceCache.Get(ctx, nsn, secret) if err != nil { return errors.Wrap(err, ackerr.FieldExportMissingSecret.Error()) } @@ -389,7 +390,7 @@ func (r *fieldExportReconciler) GetFieldExportsForResource( opts := []client.ListOption{ client.InNamespace(nsn.Namespace), } - if err := r.apiReader.List(ctx, listed, opts...); err != nil { + if err := r.ackResourceCache.List(ctx, listed, opts...); err != nil { return []ackv1alpha1.FieldExport{}, err } @@ -638,7 +639,7 @@ type fieldExportResourceReconciler struct { // CRs func (r *fieldExportResourceReconciler) BindControllerManager(mgr ctrlrt.Manager) error { r.kc = mgr.GetClient() - r.apiReader = mgr.GetAPIReader() + r.ackResourceCache = mgr.GetCache() if ackcompare.IsNil(r.rd) { return errors.New("cannot bind to AWS resource. reconciler marked for reconciling field exports") @@ -731,17 +732,17 @@ func NewFieldExportReconcilerWithClient( metrics *ackmetrics.Metrics, cache ackrtcache.Caches, kc client.Client, - apiReader client.Reader, + ackResourceCache cache.Cache, ) acktypes.FieldExportReconciler { return &fieldExportReconciler{ reconciler: reconciler{ - sc: sc, - log: log.WithName("field-export-reconciler"), - cfg: cfg, - metrics: metrics, - cache: cache, - kc: kc, - apiReader: apiReader, + sc: sc, + log: log.WithName("field-export-reconciler"), + cfg: cfg, + metrics: metrics, + cache: cache, + kc: kc, + ackResourceCache: ackResourceCache, }, } } @@ -758,19 +759,19 @@ func NewFieldExportResourceReconcilerWithClient( metrics *ackmetrics.Metrics, cache ackrtcache.Caches, kc client.Client, - apiReader client.Reader, + ackResourceCache cache.Cache, rd acktypes.AWSResourceDescriptor, ) acktypes.FieldExportReconciler { return &fieldExportResourceReconciler{ fieldExportReconciler: fieldExportReconciler{ reconciler: reconciler{ - sc: sc, - log: log.WithName("field-export-reconciler"), - cfg: cfg, - metrics: metrics, - cache: cache, - kc: kc, - apiReader: apiReader, + sc: sc, + log: log.WithName("field-export-reconciler"), + cfg: cfg, + metrics: metrics, + cache: cache, + kc: kc, + ackResourceCache: ackResourceCache, }, }, rd: rd, diff --git a/pkg/runtime/field_export_reconciler_test.go b/pkg/runtime/field_export_reconciler_test.go index f2d30a3..15880c3 100644 --- a/pkg/runtime/field_export_reconciler_test.go +++ b/pkg/runtime/field_export_reconciler_test.go @@ -41,6 +41,7 @@ import ( apimachineryruntimemock "github.com/aws-controllers-k8s/runtime/mocks/apimachinery/pkg/runtime" k8srtschemamocks "github.com/aws-controllers-k8s/runtime/mocks/apimachinery/pkg/runtime/schema" + ctrlrtcachemock "github.com/aws-controllers-k8s/runtime/mocks/controller-runtime/pkg/cache" ctrlrtclientmock "github.com/aws-controllers-k8s/runtime/mocks/controller-runtime/pkg/client" mocks "github.com/aws-controllers-k8s/runtime/mocks/pkg/types" ) @@ -61,11 +62,11 @@ var ( // Helper functions for tests -func mockFieldExportReconciler() (acktypes.FieldExportReconciler, *ctrlrtclientmock.Client, *ctrlrtclientmock.Reader) { +func mockFieldExportReconciler() (acktypes.FieldExportReconciler, *ctrlrtclientmock.Client, *ctrlrtcachemock.Cache) { return mockFieldExportReconcilerWithResourceDescriptor(mockResourceDescriptor()) } -func mockFieldExportReconcilerWithResourceDescriptor(rd *mocks.AWSResourceDescriptor) (acktypes.FieldExportReconciler, *ctrlrtclientmock.Client, *ctrlrtclientmock.Reader) { +func mockFieldExportReconcilerWithResourceDescriptor(rd *mocks.AWSResourceDescriptor) (acktypes.FieldExportReconciler, *ctrlrtclientmock.Client, *ctrlrtcachemock.Cache) { zapOptions := ctrlrtzap.Options{ Development: true, Level: zapcore.InfoLevel, @@ -80,7 +81,7 @@ func mockFieldExportReconcilerWithResourceDescriptor(rd *mocks.AWSResourceDescri rmFactoryMap["services.k8s.aws"] = &rmfactory sc.On("GetResourceManagerFactories").Return(rmFactoryMap) kc := &ctrlrtclientmock.Client{} - apiReader := &ctrlrtclientmock.Reader{} + ackResourceCache := &ctrlrtcachemock.Cache{} return ackrt.NewFieldExportReconcilerWithClient( sc, fakeLogger, @@ -88,8 +89,8 @@ func mockFieldExportReconcilerWithResourceDescriptor(rd *mocks.AWSResourceDescri metrics, ackrtcache.Caches{}, kc, - apiReader, - ), kc, apiReader + ackResourceCache, + ), kc, ackResourceCache } func mockResourceDescriptor() *mocks.AWSResourceDescriptor { @@ -112,12 +113,12 @@ func setupMockClientForFieldExport(kc *ctrlrtclientmock.Client, statusWriter *ct kc.On("Patch", withoutCancelContextMatcher, mock.Anything, mock.AnythingOfType("*client.mergeFromPatch")).Return(nil) } -func setupMockApiReaderForFieldExport(apiReader *ctrlrtclientmock.Reader, ctx context.Context, res *mocks.AWSResource) { - apiReader.On("Get", ctx, types.NamespacedName{ +func setupMockACKResourceCacheForFieldExport(ackResourceCache *ctrlrtcachemock.Cache, ctx context.Context, res *mocks.AWSResource) { + ackResourceCache.On("Get", ctx, types.NamespacedName{ Namespace: FieldExportNamespace, Name: "fake-export-output", }, mock.AnythingOfType("*v1.ConfigMap")).Return(nil) - apiReader.On("Get", ctx, types.NamespacedName{ + ackResourceCache.On("Get", ctx, types.NamespacedName{ Namespace: FieldExportNamespace, Name: "fake-export-output", }, mock.AnythingOfType("*v1.Secret")).Return(nil) @@ -267,7 +268,7 @@ func TestSync_FailureInParsingQuery(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockFieldExportReconciler() + r, kc, ackResourceCache := mockFieldExportReconciler() descriptor, res, _ := mockDescriptorAndAWSResource() manager := mockManager() fieldExport := fieldExportWithPath(FieldExportNamespace, FieldExportName, ackv1alpha1.FieldExportOutputTypeConfigMap, "bad-query") @@ -277,7 +278,7 @@ func TestSync_FailureInParsingQuery(t *testing.T) { //Mock behavior setup setupMockClientForFieldExport(kc, statusWriter, ctx, fieldExport) - setupMockApiReaderForFieldExport(apiReader, ctx, res) + setupMockACKResourceCacheForFieldExport(ackResourceCache, ctx, res) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) setupMockUnstructuredConverter() @@ -297,7 +298,7 @@ func TestSync_FailureInGetField(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockFieldExportReconciler() + r, kc, ackResourceCache := mockFieldExportReconciler() descriptor, res, _ := mockDescriptorAndAWSResource() manager := mockManager() fieldExport := fieldExportWithPath(FieldExportNamespace, FieldExportName, ackv1alpha1.FieldExportOutputTypeConfigMap, ".doesnt.exist") @@ -307,7 +308,7 @@ func TestSync_FailureInGetField(t *testing.T) { //Mock behavior setup setupMockClientForFieldExport(kc, statusWriter, ctx, fieldExport) - setupMockApiReaderForFieldExport(apiReader, ctx, res) + setupMockACKResourceCacheForFieldExport(ackResourceCache, ctx, res) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) setupMockUnstructuredConverter() @@ -327,7 +328,7 @@ func TestSync_FailureInPatchConfigMap(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockFieldExportReconciler() + r, kc, ackResourceCache := mockFieldExportReconciler() descriptor, res, _ := mockDescriptorAndAWSResource() manager := mockManager() fieldExport := fieldExportConfigMap(FieldExportNamespace, FieldExportName) @@ -339,7 +340,7 @@ func TestSync_FailureInPatchConfigMap(t *testing.T) { kc.On("Patch", withoutCancelContextMatcher, mock.AnythingOfType("*v1.ConfigMap"), mock.AnythingOfType("*client.mergeFromPatch")).Return(errors.New("patching denied")) setupMockClientForFieldExport(kc, statusWriter, ctx, fieldExport) - setupMockApiReaderForFieldExport(apiReader, ctx, res) + setupMockACKResourceCacheForFieldExport(ackResourceCache, ctx, res) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) setupMockUnstructuredConverter() @@ -359,7 +360,7 @@ func TestSync_HappyCaseConfigMap(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockFieldExportReconciler() + r, kc, ackResourceCache := mockFieldExportReconciler() descriptor, res, _ := mockDescriptorAndAWSResource() manager := mockManager() fieldExport := fieldExportConfigMap(FieldExportNamespace, FieldExportName) @@ -369,7 +370,7 @@ func TestSync_HappyCaseConfigMap(t *testing.T) { //Mock behavior setup setupMockClientForFieldExport(kc, statusWriter, ctx, fieldExport) - setupMockApiReaderForFieldExport(apiReader, ctx, res) + setupMockACKResourceCacheForFieldExport(ackResourceCache, ctx, res) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) setupMockUnstructuredConverter() @@ -389,7 +390,7 @@ func TestSync_HappyCaseSecret(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockFieldExportReconciler() + r, kc, ackResourceCache := mockFieldExportReconciler() descriptor, res, _ := mockDescriptorAndAWSResource() manager := mockManager() fieldExport := fieldExportSecret(FieldExportNamespace, FieldExportName) @@ -399,7 +400,7 @@ func TestSync_HappyCaseSecret(t *testing.T) { //Mock behavior setup setupMockClientForFieldExport(kc, statusWriter, ctx, fieldExport) - setupMockApiReaderForFieldExport(apiReader, ctx, res) + setupMockACKResourceCacheForFieldExport(ackResourceCache, ctx, res) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) setupMockUnstructuredConverter() @@ -419,10 +420,10 @@ func TestFilterAllExports_HappyCase(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, _, apiReader := mockFieldExportReconciler() + r, _, ackResourceCache := mockFieldExportReconciler() ctx := context.TODO() mockExports := mockFieldExportList() - apiReader.On("List", ctx, mock.AnythingOfType("*v1alpha1.FieldExportList"), mock.Anything).Return(nil). + ackResourceCache.On("List", ctx, mock.AnythingOfType("*v1alpha1.FieldExportList"), mock.Anything).Return(nil). Run(func(args mock.Arguments) { // Replace the field export list argument pointer with our mocks list := args.Get(1).(*ackv1alpha1.FieldExportList) @@ -452,11 +453,11 @@ func TestSync_HappyCaseResourceNoExports(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, _, apiReader := mockFieldExportReconciler() + r, _, ackResourceCache := mockFieldExportReconciler() ctx := context.TODO() mockExports := mockFieldExportList() - apiReader.On("List", ctx, mock.AnythingOfType("*v1alpha1.FieldExportList"), mock.Anything).Return(nil). + ackResourceCache.On("List", ctx, mock.AnythingOfType("*v1alpha1.FieldExportList"), mock.Anything).Return(nil). Run(func(args mock.Arguments) { // Replace the field export list argument pointer with our mocks list := args.Get(1).(*ackv1alpha1.FieldExportList) @@ -486,7 +487,7 @@ func TestSync_SetKeyNameExplicitly(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockFieldExportReconciler() + r, kc, ackResourceCache := mockFieldExportReconciler() descriptor, res, _ := mockDescriptorAndAWSResource() manager := mockManager() fieldExport := fieldExportWithKey(FieldExportNamespace, FieldExportName, ackv1alpha1.FieldExportOutputTypeSecret, "new-key") @@ -496,7 +497,7 @@ func TestSync_SetKeyNameExplicitly(t *testing.T) { //Mock behavior setup setupMockClientForFieldExport(kc, statusWriter, ctx, fieldExport) - setupMockApiReaderForFieldExport(apiReader, ctx, res) + setupMockACKResourceCacheForFieldExport(ackResourceCache, ctx, res) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) setupMockUnstructuredConverter() @@ -516,7 +517,7 @@ func TestSync_SetKeyNameExplicitlyWithEmptyString(t *testing.T) { // Setup require := require.New(t) // Mock resource creation - r, kc, apiReader := mockFieldExportReconciler() + r, kc, ackResourceCache := mockFieldExportReconciler() descriptor, res, _ := mockDescriptorAndAWSResource() manager := mockManager() fieldExport := fieldExportWithKey(FieldExportNamespace, FieldExportName, ackv1alpha1.FieldExportOutputTypeSecret, "") @@ -526,7 +527,7 @@ func TestSync_SetKeyNameExplicitlyWithEmptyString(t *testing.T) { //Mock behavior setup setupMockClientForFieldExport(kc, statusWriter, ctx, fieldExport) - setupMockApiReaderForFieldExport(apiReader, ctx, res) + setupMockACKResourceCacheForFieldExport(ackResourceCache, ctx, res) setupMockManager(manager, ctx, res) setupMockDescriptor(descriptor, res) setupMockUnstructuredConverter() @@ -594,7 +595,7 @@ func assertPatchedSecretWithKey(expected bool, t *testing.T, ctx context.Context return bytes.Equal(val, []byte("test-book-name")) }) if expected { - kc.AssertCalled(t, "Patch", withoutCancelContextMatcher, dataMatcher, mock.Anything) + kc.AssertCalled(t, "Patch", withoutCancelContextMatcher, dataMatcher, mock.Anything) } else { kc.AssertNotCalled(t, "Patch", withoutCancelContextMatcher, dataMatcher, mock.Anything) } diff --git a/pkg/runtime/reconciler.go b/pkg/runtime/reconciler.go index ddc94f4..2796600 100644 --- a/pkg/runtime/reconciler.go +++ b/pkg/runtime/reconciler.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" ctrlrt "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" ctrlrtcontroller "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/predicate" @@ -61,13 +62,13 @@ const ( // reconciler describes a generic reconciler within ACK. type reconciler struct { - sc acktypes.ServiceController - kc client.Client - apiReader client.Reader - log logr.Logger - cfg ackcfg.Config - cache ackrtcache.Caches - metrics *ackmetrics.Metrics + sc acktypes.ServiceController + kc client.Client + log logr.Logger + cfg ackcfg.Config + cache ackrtcache.Caches + metrics *ackmetrics.Metrics + ackResourceCache cache.Cache } // resourceReconciler is responsible for reconciling the state of a SINGLE KIND of @@ -101,7 +102,7 @@ func (r *resourceReconciler) BindControllerManager(mgr ctrlrt.Manager) error { return ackerr.NilResourceManagerFactory } r.kc = mgr.GetClient() - r.apiReader = mgr.GetAPIReader() + r.ackResourceCache = mgr.GetCache() rd := r.rmf.ResourceDescriptor() maxConcurrentReconciles := r.cfg.GetReconcileResourceMaxConcurrency(rd.GroupVersionKind().Kind) return ctrlrt.NewControllerManagedBy( @@ -148,7 +149,7 @@ func (r *reconciler) SecretValueFromReference( Name: ref.Name, } var secret corev1.Secret - if err := r.apiReader.Get(ctx, nsn, &secret); err != nil { + if err := r.ackResourceCache.Get(ctx, nsn, &secret); err != nil { return "", ackerr.SecretNotFound } @@ -182,7 +183,7 @@ func (r *reconciler) WriteToSecret( nsn.Namespace = namespace secret := &corev1.Secret{} - err := r.apiReader.Get(ctx, nsn, secret) + err := r.ackResourceCache.Get(ctx, nsn, secret) if err != nil { return ackerr.SecretNotFound } @@ -363,7 +364,7 @@ func (r *resourceReconciler) reconcile( !(r.cfg.FeatureGates.IsEnabled(featuregate.ReadOnlyResources) && IsReadOnly(res)) { // Resolve references before deleting the resource. // Ignore any errors while resolving the references - resolved, _, _ := rm.ResolveReferences(ctx, r.apiReader, res) + resolved, _, _ := rm.ResolveReferences(ctx, r.ackResourceCache, res) return r.deleteResource(ctx, rm, resolved) } @@ -425,7 +426,7 @@ func (r *resourceReconciler) Sync( } rlog.Enter("rm.ResolveReferences") - resolved, hasReferences, err := rm.ResolveReferences(ctx, r.apiReader, desired) + resolved, hasReferences, err := rm.ResolveReferences(ctx, r.ackResourceCache, desired) rlog.Exit("rm.ResolveReferences", err) // TODO (michaelhtm): should we fail here for `adopt-or-create` adoption policy? if err != nil && !needAdoption && !isReadOnly { @@ -1094,7 +1095,7 @@ func (r *resourceReconciler) getAWSResource( req ctrlrt.Request, ) (acktypes.AWSResource, error) { ro := r.rd.EmptyRuntimeObject() - // Here we use k8s APIReader to read the k8s object by making the + // Here we use k8s ackResourceCache to read the k8s object by making the // direct call to k8s apiserver instead of using k8sClient. // The reason is that k8sClient uses a cache and sometimes k8sClient can // return stale copy of object. @@ -1102,7 +1103,7 @@ func (r *resourceReconciler) getAWSResource( // making single read call for complete reconciler loop. // See following issue for more details: // https://github.com/aws-controllers-k8s/community/issues/894 - if err := r.apiReader.Get(ctx, req.NamespacedName, ro); err != nil { + if err := r.ackResourceCache.Get(ctx, req.NamespacedName, ro); err != nil { return nil, err } return r.rd.ResourceFromRuntimeObject(ro), nil diff --git a/pkg/runtime/reconciler_test.go b/pkg/runtime/reconciler_test.go index fb05154..84a1945 100644 --- a/pkg/runtime/reconciler_test.go +++ b/pkg/runtime/reconciler_test.go @@ -505,7 +505,7 @@ func TestReconcilerAdoptOrCreateResource_Adopt(t *testing.T) { latest, latestRTObj, latestMetaObj := resourceMocks() latest.On("Identifiers").Return(ids) latest.On("Conditions").Return([]*ackv1alpha1.Condition{}) - latest.On( + latest.On( "ReplaceConditions", mock.AnythingOfType("[]*v1alpha1.Condition"), ).Return().Run(func(args mock.Arguments) { diff --git a/pkg/runtime/service_controller.go b/pkg/runtime/service_controller.go index 7488c12..9fb2ce0 100644 --- a/pkg/runtime/service_controller.go +++ b/pkg/runtime/service_controller.go @@ -331,9 +331,9 @@ func NewServiceController( ) acktypes.ServiceController { return &serviceController{ ServiceControllerMetadata: acktypes.ServiceControllerMetadata{ - VersionInfo: versionInfo, - ServiceAlias: svcAlias, - ServiceAPIGroup: svcAPIGroup, + VersionInfo: versionInfo, + ServiceAlias: svcAlias, + ServiceAPIGroup: svcAPIGroup, }, metrics: ackmetrics.NewMetrics(svcAlias), } diff --git a/pkg/runtime/util_test.go b/pkg/runtime/util_test.go index 74589e3..a03b2f3 100644 --- a/pkg/runtime/util_test.go +++ b/pkg/runtime/util_test.go @@ -92,7 +92,7 @@ func TestIsForcedAdoption(t *testing.T) { res = &mocks.AWSResource{} res.On("MetaObject").Return(&metav1.ObjectMeta{ Annotations: map[string]string{ - ackv1alpha1.AnnotationAdopted: "true", + ackv1alpha1.AnnotationAdopted: "true", }, }) require.False(ackrt.NeedAdoption(res)) diff --git a/pkg/types/aws_resource.go b/pkg/types/aws_resource.go index dd2673e..6e9bbc3 100644 --- a/pkg/types/aws_resource.go +++ b/pkg/types/aws_resource.go @@ -50,5 +50,5 @@ type AWSResource interface { DeepCopy() AWSResource // PopulateResourceFromAnnotation will set the Spec or Status field that user // provided from annotations - PopulateResourceFromAnnotation(fields map[string]string) error + PopulateResourceFromAnnotation(fields map[string]string) error }