From 0ace883118c7f61f8a0ccae1518721d0845ef9f6 Mon Sep 17 00:00:00 2001 From: Tao Yi Date: Thu, 5 Sep 2024 21:31:48 +0800 Subject: [PATCH] test(konnect): Add SDKWrapper to allow using mock SDK in reconcilers (#543) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(konnect): add SDK interface types for each entity type * tests: add mockery for Konnect SDK * tests: add mocks for KongService SDK * add plugin SDK interface and mock * refactor SDKFactory to allow using mock SDK in reconcilers * add mocks for all submodules of Konnect SDK * move mock SDK code to *_mock.go to allow them being imported by other packages * Update controller/konnect/reconciler_generic_test.go Co-authored-by: Grzegorz Burzyński --------- Co-authored-by: Patryk Małek Co-authored-by: Grzegorz Burzyński --- .golangci.yaml | 5 + .mockery.yaml | 7 +- ...lane_mock_test.go => controlplane_mock.go} | 0 controller/konnect/ops/kongconsumer_mock.go | 264 ++++++++++++++++++ .../konnect/ops/kongconsumergroup_mock.go | 264 ++++++++++++++++++ controller/konnect/ops/kongroute_mock.go | 264 ++++++++++++++++++ ...rvice_mock_test.go => kongservice_mock.go} | 0 controller/konnect/ops/me.go | 12 + controller/konnect/ops/me_mock.go | 110 ++++++++ controller/konnect/ops/ops.go | 43 ++- .../konnect/ops/ops_kongpluginbinding.go | 13 +- controller/konnect/ops/plugin.go | 15 + controller/konnect/ops/plugin_mock.go | 264 ++++++++++++++++++ controller/konnect/ops/sdkfactory.go | 87 ++++++ controller/konnect/ops/sdkfactory_mock.go | 62 ++++ controller/konnect/reconciler_generic.go | 6 +- controller/konnect/reconciler_generic_test.go | 4 +- .../konnect/reconciler_konnectapiauth.go | 9 +- controller/konnect/sdkfactory.go | 33 --- modules/manager/controller_setup.go | 3 +- 20 files changed, 1393 insertions(+), 72 deletions(-) rename controller/konnect/ops/{controlplane_mock_test.go => controlplane_mock.go} (100%) create mode 100644 controller/konnect/ops/kongconsumer_mock.go create mode 100644 controller/konnect/ops/kongconsumergroup_mock.go create mode 100644 controller/konnect/ops/kongroute_mock.go rename controller/konnect/ops/{kongservice_mock_test.go => kongservice_mock.go} (100%) create mode 100644 controller/konnect/ops/me.go create mode 100644 controller/konnect/ops/me_mock.go create mode 100644 controller/konnect/ops/plugin.go create mode 100644 controller/konnect/ops/plugin_mock.go create mode 100644 controller/konnect/ops/sdkfactory.go create mode 100644 controller/konnect/ops/sdkfactory_mock.go delete mode 100644 controller/konnect/sdkfactory.go diff --git a/.golangci.yaml b/.golangci.yaml index d4074e251..18dbfa285 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -146,3 +146,8 @@ issues: linters: - revive text: "exported: exported" + # Generated mock SDKs does not need comments on generated methods. + - path: controller/konnect/ops/.*_mock\.go + linters: + - revive + text: "exported: exported" diff --git a/.mockery.yaml b/.mockery.yaml index 36d799f63..26ddfbfc6 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -3,7 +3,7 @@ inpackage: True disable-version-string: True with-expecter: True -filename: "{{ trimSuffix .InterfaceFile \".go\" | base | lower }}_mock_test.go" +filename: "{{ trimSuffix .InterfaceFile \".go\" | base | lower }}_mock.go" dir: "{{ .InterfaceDir }}" mockname: "Mock{{ .InterfaceName }}" outpkg: "{{ .PackageName }}" @@ -13,3 +13,8 @@ packages: interfaces: ControlPlaneSDK: ServicesSDK: + RoutesSDK: + ConsumersSDK: + ConsumerGroupSDK: + PluginSDK: + MeSDK: diff --git a/controller/konnect/ops/controlplane_mock_test.go b/controller/konnect/ops/controlplane_mock.go similarity index 100% rename from controller/konnect/ops/controlplane_mock_test.go rename to controller/konnect/ops/controlplane_mock.go diff --git a/controller/konnect/ops/kongconsumer_mock.go b/controller/konnect/ops/kongconsumer_mock.go new file mode 100644 index 000000000..e3b277e9c --- /dev/null +++ b/controller/konnect/ops/kongconsumer_mock.go @@ -0,0 +1,264 @@ +// Code generated by mockery. DO NOT EDIT. + +package ops + +import ( + context "context" + + components "github.com/Kong/sdk-konnect-go/models/components" + + mock "github.com/stretchr/testify/mock" + + operations "github.com/Kong/sdk-konnect-go/models/operations" +) + +// MockConsumersSDK is an autogenerated mock type for the ConsumersSDK type +type MockConsumersSDK struct { + mock.Mock +} + +type MockConsumersSDK_Expecter struct { + mock *mock.Mock +} + +func (_m *MockConsumersSDK) EXPECT() *MockConsumersSDK_Expecter { + return &MockConsumersSDK_Expecter{mock: &_m.Mock} +} + +// CreateConsumer provides a mock function with given fields: ctx, controlPlaneID, consumerInput, opts +func (_m *MockConsumersSDK) CreateConsumer(ctx context.Context, controlPlaneID string, consumerInput components.ConsumerInput, opts ...operations.Option) (*operations.CreateConsumerResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, controlPlaneID, consumerInput) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for CreateConsumer") + } + + var r0 *operations.CreateConsumerResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, components.ConsumerInput, ...operations.Option) (*operations.CreateConsumerResponse, error)); ok { + return rf(ctx, controlPlaneID, consumerInput, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, components.ConsumerInput, ...operations.Option) *operations.CreateConsumerResponse); ok { + r0 = rf(ctx, controlPlaneID, consumerInput, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.CreateConsumerResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, components.ConsumerInput, ...operations.Option) error); ok { + r1 = rf(ctx, controlPlaneID, consumerInput, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockConsumersSDK_CreateConsumer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateConsumer' +type MockConsumersSDK_CreateConsumer_Call struct { + *mock.Call +} + +// CreateConsumer is a helper method to define mock.On call +// - ctx context.Context +// - controlPlaneID string +// - consumerInput components.ConsumerInput +// - opts ...operations.Option +func (_e *MockConsumersSDK_Expecter) CreateConsumer(ctx interface{}, controlPlaneID interface{}, consumerInput interface{}, opts ...interface{}) *MockConsumersSDK_CreateConsumer_Call { + return &MockConsumersSDK_CreateConsumer_Call{Call: _e.mock.On("CreateConsumer", + append([]interface{}{ctx, controlPlaneID, consumerInput}, opts...)...)} +} + +func (_c *MockConsumersSDK_CreateConsumer_Call) Run(run func(ctx context.Context, controlPlaneID string, consumerInput components.ConsumerInput, opts ...operations.Option)) *MockConsumersSDK_CreateConsumer_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-3) + for i, a := range args[3:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(components.ConsumerInput), variadicArgs...) + }) + return _c +} + +func (_c *MockConsumersSDK_CreateConsumer_Call) Return(_a0 *operations.CreateConsumerResponse, _a1 error) *MockConsumersSDK_CreateConsumer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockConsumersSDK_CreateConsumer_Call) RunAndReturn(run func(context.Context, string, components.ConsumerInput, ...operations.Option) (*operations.CreateConsumerResponse, error)) *MockConsumersSDK_CreateConsumer_Call { + _c.Call.Return(run) + return _c +} + +// DeleteConsumer provides a mock function with given fields: ctx, controlPlaneID, consumerID, opts +func (_m *MockConsumersSDK) DeleteConsumer(ctx context.Context, controlPlaneID string, consumerID string, opts ...operations.Option) (*operations.DeleteConsumerResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, controlPlaneID, consumerID) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for DeleteConsumer") + } + + var r0 *operations.DeleteConsumerResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, ...operations.Option) (*operations.DeleteConsumerResponse, error)); ok { + return rf(ctx, controlPlaneID, consumerID, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string, ...operations.Option) *operations.DeleteConsumerResponse); ok { + r0 = rf(ctx, controlPlaneID, consumerID, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.DeleteConsumerResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string, ...operations.Option) error); ok { + r1 = rf(ctx, controlPlaneID, consumerID, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockConsumersSDK_DeleteConsumer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteConsumer' +type MockConsumersSDK_DeleteConsumer_Call struct { + *mock.Call +} + +// DeleteConsumer is a helper method to define mock.On call +// - ctx context.Context +// - controlPlaneID string +// - consumerID string +// - opts ...operations.Option +func (_e *MockConsumersSDK_Expecter) DeleteConsumer(ctx interface{}, controlPlaneID interface{}, consumerID interface{}, opts ...interface{}) *MockConsumersSDK_DeleteConsumer_Call { + return &MockConsumersSDK_DeleteConsumer_Call{Call: _e.mock.On("DeleteConsumer", + append([]interface{}{ctx, controlPlaneID, consumerID}, opts...)...)} +} + +func (_c *MockConsumersSDK_DeleteConsumer_Call) Run(run func(ctx context.Context, controlPlaneID string, consumerID string, opts ...operations.Option)) *MockConsumersSDK_DeleteConsumer_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-3) + for i, a := range args[3:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockConsumersSDK_DeleteConsumer_Call) Return(_a0 *operations.DeleteConsumerResponse, _a1 error) *MockConsumersSDK_DeleteConsumer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockConsumersSDK_DeleteConsumer_Call) RunAndReturn(run func(context.Context, string, string, ...operations.Option) (*operations.DeleteConsumerResponse, error)) *MockConsumersSDK_DeleteConsumer_Call { + _c.Call.Return(run) + return _c +} + +// UpsertConsumer provides a mock function with given fields: ctx, upsertConsumerRequest, opts +func (_m *MockConsumersSDK) UpsertConsumer(ctx context.Context, upsertConsumerRequest operations.UpsertConsumerRequest, opts ...operations.Option) (*operations.UpsertConsumerResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, upsertConsumerRequest) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for UpsertConsumer") + } + + var r0 *operations.UpsertConsumerResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, operations.UpsertConsumerRequest, ...operations.Option) (*operations.UpsertConsumerResponse, error)); ok { + return rf(ctx, upsertConsumerRequest, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, operations.UpsertConsumerRequest, ...operations.Option) *operations.UpsertConsumerResponse); ok { + r0 = rf(ctx, upsertConsumerRequest, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.UpsertConsumerResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, operations.UpsertConsumerRequest, ...operations.Option) error); ok { + r1 = rf(ctx, upsertConsumerRequest, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockConsumersSDK_UpsertConsumer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertConsumer' +type MockConsumersSDK_UpsertConsumer_Call struct { + *mock.Call +} + +// UpsertConsumer is a helper method to define mock.On call +// - ctx context.Context +// - upsertConsumerRequest operations.UpsertConsumerRequest +// - opts ...operations.Option +func (_e *MockConsumersSDK_Expecter) UpsertConsumer(ctx interface{}, upsertConsumerRequest interface{}, opts ...interface{}) *MockConsumersSDK_UpsertConsumer_Call { + return &MockConsumersSDK_UpsertConsumer_Call{Call: _e.mock.On("UpsertConsumer", + append([]interface{}{ctx, upsertConsumerRequest}, opts...)...)} +} + +func (_c *MockConsumersSDK_UpsertConsumer_Call) Run(run func(ctx context.Context, upsertConsumerRequest operations.UpsertConsumerRequest, opts ...operations.Option)) *MockConsumersSDK_UpsertConsumer_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(operations.UpsertConsumerRequest), variadicArgs...) + }) + return _c +} + +func (_c *MockConsumersSDK_UpsertConsumer_Call) Return(_a0 *operations.UpsertConsumerResponse, _a1 error) *MockConsumersSDK_UpsertConsumer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockConsumersSDK_UpsertConsumer_Call) RunAndReturn(run func(context.Context, operations.UpsertConsumerRequest, ...operations.Option) (*operations.UpsertConsumerResponse, error)) *MockConsumersSDK_UpsertConsumer_Call { + _c.Call.Return(run) + return _c +} + +// NewMockConsumersSDK creates a new instance of MockConsumersSDK. 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 NewMockConsumersSDK(t interface { + mock.TestingT + Cleanup(func()) +}) *MockConsumersSDK { + mock := &MockConsumersSDK{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/konnect/ops/kongconsumergroup_mock.go b/controller/konnect/ops/kongconsumergroup_mock.go new file mode 100644 index 000000000..f206b93a2 --- /dev/null +++ b/controller/konnect/ops/kongconsumergroup_mock.go @@ -0,0 +1,264 @@ +// Code generated by mockery. DO NOT EDIT. + +package ops + +import ( + context "context" + + components "github.com/Kong/sdk-konnect-go/models/components" + + mock "github.com/stretchr/testify/mock" + + operations "github.com/Kong/sdk-konnect-go/models/operations" +) + +// MockConsumerGroupSDK is an autogenerated mock type for the ConsumerGroupSDK type +type MockConsumerGroupSDK struct { + mock.Mock +} + +type MockConsumerGroupSDK_Expecter struct { + mock *mock.Mock +} + +func (_m *MockConsumerGroupSDK) EXPECT() *MockConsumerGroupSDK_Expecter { + return &MockConsumerGroupSDK_Expecter{mock: &_m.Mock} +} + +// CreateConsumerGroup provides a mock function with given fields: ctx, controlPlaneID, consumerInput, opts +func (_m *MockConsumerGroupSDK) CreateConsumerGroup(ctx context.Context, controlPlaneID string, consumerInput components.ConsumerGroupInput, opts ...operations.Option) (*operations.CreateConsumerGroupResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, controlPlaneID, consumerInput) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for CreateConsumerGroup") + } + + var r0 *operations.CreateConsumerGroupResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, components.ConsumerGroupInput, ...operations.Option) (*operations.CreateConsumerGroupResponse, error)); ok { + return rf(ctx, controlPlaneID, consumerInput, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, components.ConsumerGroupInput, ...operations.Option) *operations.CreateConsumerGroupResponse); ok { + r0 = rf(ctx, controlPlaneID, consumerInput, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.CreateConsumerGroupResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, components.ConsumerGroupInput, ...operations.Option) error); ok { + r1 = rf(ctx, controlPlaneID, consumerInput, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockConsumerGroupSDK_CreateConsumerGroup_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateConsumerGroup' +type MockConsumerGroupSDK_CreateConsumerGroup_Call struct { + *mock.Call +} + +// CreateConsumerGroup is a helper method to define mock.On call +// - ctx context.Context +// - controlPlaneID string +// - consumerInput components.ConsumerGroupInput +// - opts ...operations.Option +func (_e *MockConsumerGroupSDK_Expecter) CreateConsumerGroup(ctx interface{}, controlPlaneID interface{}, consumerInput interface{}, opts ...interface{}) *MockConsumerGroupSDK_CreateConsumerGroup_Call { + return &MockConsumerGroupSDK_CreateConsumerGroup_Call{Call: _e.mock.On("CreateConsumerGroup", + append([]interface{}{ctx, controlPlaneID, consumerInput}, opts...)...)} +} + +func (_c *MockConsumerGroupSDK_CreateConsumerGroup_Call) Run(run func(ctx context.Context, controlPlaneID string, consumerInput components.ConsumerGroupInput, opts ...operations.Option)) *MockConsumerGroupSDK_CreateConsumerGroup_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-3) + for i, a := range args[3:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(components.ConsumerGroupInput), variadicArgs...) + }) + return _c +} + +func (_c *MockConsumerGroupSDK_CreateConsumerGroup_Call) Return(_a0 *operations.CreateConsumerGroupResponse, _a1 error) *MockConsumerGroupSDK_CreateConsumerGroup_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockConsumerGroupSDK_CreateConsumerGroup_Call) RunAndReturn(run func(context.Context, string, components.ConsumerGroupInput, ...operations.Option) (*operations.CreateConsumerGroupResponse, error)) *MockConsumerGroupSDK_CreateConsumerGroup_Call { + _c.Call.Return(run) + return _c +} + +// DeleteConsumerGroup provides a mock function with given fields: ctx, controlPlaneID, consumerID, opts +func (_m *MockConsumerGroupSDK) DeleteConsumerGroup(ctx context.Context, controlPlaneID string, consumerID string, opts ...operations.Option) (*operations.DeleteConsumerGroupResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, controlPlaneID, consumerID) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for DeleteConsumerGroup") + } + + var r0 *operations.DeleteConsumerGroupResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, ...operations.Option) (*operations.DeleteConsumerGroupResponse, error)); ok { + return rf(ctx, controlPlaneID, consumerID, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string, ...operations.Option) *operations.DeleteConsumerGroupResponse); ok { + r0 = rf(ctx, controlPlaneID, consumerID, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.DeleteConsumerGroupResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string, ...operations.Option) error); ok { + r1 = rf(ctx, controlPlaneID, consumerID, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockConsumerGroupSDK_DeleteConsumerGroup_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteConsumerGroup' +type MockConsumerGroupSDK_DeleteConsumerGroup_Call struct { + *mock.Call +} + +// DeleteConsumerGroup is a helper method to define mock.On call +// - ctx context.Context +// - controlPlaneID string +// - consumerID string +// - opts ...operations.Option +func (_e *MockConsumerGroupSDK_Expecter) DeleteConsumerGroup(ctx interface{}, controlPlaneID interface{}, consumerID interface{}, opts ...interface{}) *MockConsumerGroupSDK_DeleteConsumerGroup_Call { + return &MockConsumerGroupSDK_DeleteConsumerGroup_Call{Call: _e.mock.On("DeleteConsumerGroup", + append([]interface{}{ctx, controlPlaneID, consumerID}, opts...)...)} +} + +func (_c *MockConsumerGroupSDK_DeleteConsumerGroup_Call) Run(run func(ctx context.Context, controlPlaneID string, consumerID string, opts ...operations.Option)) *MockConsumerGroupSDK_DeleteConsumerGroup_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-3) + for i, a := range args[3:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockConsumerGroupSDK_DeleteConsumerGroup_Call) Return(_a0 *operations.DeleteConsumerGroupResponse, _a1 error) *MockConsumerGroupSDK_DeleteConsumerGroup_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockConsumerGroupSDK_DeleteConsumerGroup_Call) RunAndReturn(run func(context.Context, string, string, ...operations.Option) (*operations.DeleteConsumerGroupResponse, error)) *MockConsumerGroupSDK_DeleteConsumerGroup_Call { + _c.Call.Return(run) + return _c +} + +// UpsertConsumerGroup provides a mock function with given fields: ctx, upsertConsumerRequest, opts +func (_m *MockConsumerGroupSDK) UpsertConsumerGroup(ctx context.Context, upsertConsumerRequest operations.UpsertConsumerGroupRequest, opts ...operations.Option) (*operations.UpsertConsumerGroupResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, upsertConsumerRequest) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for UpsertConsumerGroup") + } + + var r0 *operations.UpsertConsumerGroupResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, operations.UpsertConsumerGroupRequest, ...operations.Option) (*operations.UpsertConsumerGroupResponse, error)); ok { + return rf(ctx, upsertConsumerRequest, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, operations.UpsertConsumerGroupRequest, ...operations.Option) *operations.UpsertConsumerGroupResponse); ok { + r0 = rf(ctx, upsertConsumerRequest, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.UpsertConsumerGroupResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, operations.UpsertConsumerGroupRequest, ...operations.Option) error); ok { + r1 = rf(ctx, upsertConsumerRequest, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockConsumerGroupSDK_UpsertConsumerGroup_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertConsumerGroup' +type MockConsumerGroupSDK_UpsertConsumerGroup_Call struct { + *mock.Call +} + +// UpsertConsumerGroup is a helper method to define mock.On call +// - ctx context.Context +// - upsertConsumerRequest operations.UpsertConsumerGroupRequest +// - opts ...operations.Option +func (_e *MockConsumerGroupSDK_Expecter) UpsertConsumerGroup(ctx interface{}, upsertConsumerRequest interface{}, opts ...interface{}) *MockConsumerGroupSDK_UpsertConsumerGroup_Call { + return &MockConsumerGroupSDK_UpsertConsumerGroup_Call{Call: _e.mock.On("UpsertConsumerGroup", + append([]interface{}{ctx, upsertConsumerRequest}, opts...)...)} +} + +func (_c *MockConsumerGroupSDK_UpsertConsumerGroup_Call) Run(run func(ctx context.Context, upsertConsumerRequest operations.UpsertConsumerGroupRequest, opts ...operations.Option)) *MockConsumerGroupSDK_UpsertConsumerGroup_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(operations.UpsertConsumerGroupRequest), variadicArgs...) + }) + return _c +} + +func (_c *MockConsumerGroupSDK_UpsertConsumerGroup_Call) Return(_a0 *operations.UpsertConsumerGroupResponse, _a1 error) *MockConsumerGroupSDK_UpsertConsumerGroup_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockConsumerGroupSDK_UpsertConsumerGroup_Call) RunAndReturn(run func(context.Context, operations.UpsertConsumerGroupRequest, ...operations.Option) (*operations.UpsertConsumerGroupResponse, error)) *MockConsumerGroupSDK_UpsertConsumerGroup_Call { + _c.Call.Return(run) + return _c +} + +// NewMockConsumerGroupSDK creates a new instance of MockConsumerGroupSDK. 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 NewMockConsumerGroupSDK(t interface { + mock.TestingT + Cleanup(func()) +}) *MockConsumerGroupSDK { + mock := &MockConsumerGroupSDK{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/konnect/ops/kongroute_mock.go b/controller/konnect/ops/kongroute_mock.go new file mode 100644 index 000000000..13d6db971 --- /dev/null +++ b/controller/konnect/ops/kongroute_mock.go @@ -0,0 +1,264 @@ +// Code generated by mockery. DO NOT EDIT. + +package ops + +import ( + context "context" + + components "github.com/Kong/sdk-konnect-go/models/components" + + mock "github.com/stretchr/testify/mock" + + operations "github.com/Kong/sdk-konnect-go/models/operations" +) + +// MockRoutesSDK is an autogenerated mock type for the RoutesSDK type +type MockRoutesSDK struct { + mock.Mock +} + +type MockRoutesSDK_Expecter struct { + mock *mock.Mock +} + +func (_m *MockRoutesSDK) EXPECT() *MockRoutesSDK_Expecter { + return &MockRoutesSDK_Expecter{mock: &_m.Mock} +} + +// CreateRoute provides a mock function with given fields: ctx, controlPlaneID, route, opts +func (_m *MockRoutesSDK) CreateRoute(ctx context.Context, controlPlaneID string, route components.RouteInput, opts ...operations.Option) (*operations.CreateRouteResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, controlPlaneID, route) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for CreateRoute") + } + + var r0 *operations.CreateRouteResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, components.RouteInput, ...operations.Option) (*operations.CreateRouteResponse, error)); ok { + return rf(ctx, controlPlaneID, route, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, components.RouteInput, ...operations.Option) *operations.CreateRouteResponse); ok { + r0 = rf(ctx, controlPlaneID, route, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.CreateRouteResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, components.RouteInput, ...operations.Option) error); ok { + r1 = rf(ctx, controlPlaneID, route, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockRoutesSDK_CreateRoute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateRoute' +type MockRoutesSDK_CreateRoute_Call struct { + *mock.Call +} + +// CreateRoute is a helper method to define mock.On call +// - ctx context.Context +// - controlPlaneID string +// - route components.RouteInput +// - opts ...operations.Option +func (_e *MockRoutesSDK_Expecter) CreateRoute(ctx interface{}, controlPlaneID interface{}, route interface{}, opts ...interface{}) *MockRoutesSDK_CreateRoute_Call { + return &MockRoutesSDK_CreateRoute_Call{Call: _e.mock.On("CreateRoute", + append([]interface{}{ctx, controlPlaneID, route}, opts...)...)} +} + +func (_c *MockRoutesSDK_CreateRoute_Call) Run(run func(ctx context.Context, controlPlaneID string, route components.RouteInput, opts ...operations.Option)) *MockRoutesSDK_CreateRoute_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-3) + for i, a := range args[3:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(components.RouteInput), variadicArgs...) + }) + return _c +} + +func (_c *MockRoutesSDK_CreateRoute_Call) Return(_a0 *operations.CreateRouteResponse, _a1 error) *MockRoutesSDK_CreateRoute_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockRoutesSDK_CreateRoute_Call) RunAndReturn(run func(context.Context, string, components.RouteInput, ...operations.Option) (*operations.CreateRouteResponse, error)) *MockRoutesSDK_CreateRoute_Call { + _c.Call.Return(run) + return _c +} + +// DeleteRoute provides a mock function with given fields: ctx, controlPlaneID, routeID, opts +func (_m *MockRoutesSDK) DeleteRoute(ctx context.Context, controlPlaneID string, routeID string, opts ...operations.Option) (*operations.DeleteRouteResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, controlPlaneID, routeID) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for DeleteRoute") + } + + var r0 *operations.DeleteRouteResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, ...operations.Option) (*operations.DeleteRouteResponse, error)); ok { + return rf(ctx, controlPlaneID, routeID, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string, ...operations.Option) *operations.DeleteRouteResponse); ok { + r0 = rf(ctx, controlPlaneID, routeID, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.DeleteRouteResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string, ...operations.Option) error); ok { + r1 = rf(ctx, controlPlaneID, routeID, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockRoutesSDK_DeleteRoute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteRoute' +type MockRoutesSDK_DeleteRoute_Call struct { + *mock.Call +} + +// DeleteRoute is a helper method to define mock.On call +// - ctx context.Context +// - controlPlaneID string +// - routeID string +// - opts ...operations.Option +func (_e *MockRoutesSDK_Expecter) DeleteRoute(ctx interface{}, controlPlaneID interface{}, routeID interface{}, opts ...interface{}) *MockRoutesSDK_DeleteRoute_Call { + return &MockRoutesSDK_DeleteRoute_Call{Call: _e.mock.On("DeleteRoute", + append([]interface{}{ctx, controlPlaneID, routeID}, opts...)...)} +} + +func (_c *MockRoutesSDK_DeleteRoute_Call) Run(run func(ctx context.Context, controlPlaneID string, routeID string, opts ...operations.Option)) *MockRoutesSDK_DeleteRoute_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-3) + for i, a := range args[3:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockRoutesSDK_DeleteRoute_Call) Return(_a0 *operations.DeleteRouteResponse, _a1 error) *MockRoutesSDK_DeleteRoute_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockRoutesSDK_DeleteRoute_Call) RunAndReturn(run func(context.Context, string, string, ...operations.Option) (*operations.DeleteRouteResponse, error)) *MockRoutesSDK_DeleteRoute_Call { + _c.Call.Return(run) + return _c +} + +// UpsertRoute provides a mock function with given fields: ctx, req, opts +func (_m *MockRoutesSDK) UpsertRoute(ctx context.Context, req operations.UpsertRouteRequest, opts ...operations.Option) (*operations.UpsertRouteResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, req) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for UpsertRoute") + } + + var r0 *operations.UpsertRouteResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, operations.UpsertRouteRequest, ...operations.Option) (*operations.UpsertRouteResponse, error)); ok { + return rf(ctx, req, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, operations.UpsertRouteRequest, ...operations.Option) *operations.UpsertRouteResponse); ok { + r0 = rf(ctx, req, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.UpsertRouteResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, operations.UpsertRouteRequest, ...operations.Option) error); ok { + r1 = rf(ctx, req, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockRoutesSDK_UpsertRoute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertRoute' +type MockRoutesSDK_UpsertRoute_Call struct { + *mock.Call +} + +// UpsertRoute is a helper method to define mock.On call +// - ctx context.Context +// - req operations.UpsertRouteRequest +// - opts ...operations.Option +func (_e *MockRoutesSDK_Expecter) UpsertRoute(ctx interface{}, req interface{}, opts ...interface{}) *MockRoutesSDK_UpsertRoute_Call { + return &MockRoutesSDK_UpsertRoute_Call{Call: _e.mock.On("UpsertRoute", + append([]interface{}{ctx, req}, opts...)...)} +} + +func (_c *MockRoutesSDK_UpsertRoute_Call) Run(run func(ctx context.Context, req operations.UpsertRouteRequest, opts ...operations.Option)) *MockRoutesSDK_UpsertRoute_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(operations.UpsertRouteRequest), variadicArgs...) + }) + return _c +} + +func (_c *MockRoutesSDK_UpsertRoute_Call) Return(_a0 *operations.UpsertRouteResponse, _a1 error) *MockRoutesSDK_UpsertRoute_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockRoutesSDK_UpsertRoute_Call) RunAndReturn(run func(context.Context, operations.UpsertRouteRequest, ...operations.Option) (*operations.UpsertRouteResponse, error)) *MockRoutesSDK_UpsertRoute_Call { + _c.Call.Return(run) + return _c +} + +// NewMockRoutesSDK creates a new instance of MockRoutesSDK. 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 NewMockRoutesSDK(t interface { + mock.TestingT + Cleanup(func()) +}) *MockRoutesSDK { + mock := &MockRoutesSDK{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/konnect/ops/kongservice_mock_test.go b/controller/konnect/ops/kongservice_mock.go similarity index 100% rename from controller/konnect/ops/kongservice_mock_test.go rename to controller/konnect/ops/kongservice_mock.go diff --git a/controller/konnect/ops/me.go b/controller/konnect/ops/me.go new file mode 100644 index 000000000..12f79c72e --- /dev/null +++ b/controller/konnect/ops/me.go @@ -0,0 +1,12 @@ +package ops + +import ( + "context" + + sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations" +) + +// MeSDK is the interface for Konnect "Me" SDK to get current organization. +type MeSDK interface { + GetOrganizationsMe(ctx context.Context, opts ...sdkkonnectops.Option) (*sdkkonnectops.GetOrganizationsMeResponse, error) +} diff --git a/controller/konnect/ops/me_mock.go b/controller/konnect/ops/me_mock.go new file mode 100644 index 000000000..83d832fd4 --- /dev/null +++ b/controller/konnect/ops/me_mock.go @@ -0,0 +1,110 @@ +// Code generated by mockery. DO NOT EDIT. + +package ops + +import ( + context "context" + + operations "github.com/Kong/sdk-konnect-go/models/operations" + mock "github.com/stretchr/testify/mock" +) + +// MockMeSDK is an autogenerated mock type for the MeSDK type +type MockMeSDK struct { + mock.Mock +} + +type MockMeSDK_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMeSDK) EXPECT() *MockMeSDK_Expecter { + return &MockMeSDK_Expecter{mock: &_m.Mock} +} + +// GetOrganizationsMe provides a mock function with given fields: ctx, opts +func (_m *MockMeSDK) GetOrganizationsMe(ctx context.Context, opts ...operations.Option) (*operations.GetOrganizationsMeResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetOrganizationsMe") + } + + var r0 *operations.GetOrganizationsMeResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ...operations.Option) (*operations.GetOrganizationsMeResponse, error)); ok { + return rf(ctx, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, ...operations.Option) *operations.GetOrganizationsMeResponse); ok { + r0 = rf(ctx, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.GetOrganizationsMeResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, ...operations.Option) error); ok { + r1 = rf(ctx, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockMeSDK_GetOrganizationsMe_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetOrganizationsMe' +type MockMeSDK_GetOrganizationsMe_Call struct { + *mock.Call +} + +// GetOrganizationsMe is a helper method to define mock.On call +// - ctx context.Context +// - opts ...operations.Option +func (_e *MockMeSDK_Expecter) GetOrganizationsMe(ctx interface{}, opts ...interface{}) *MockMeSDK_GetOrganizationsMe_Call { + return &MockMeSDK_GetOrganizationsMe_Call{Call: _e.mock.On("GetOrganizationsMe", + append([]interface{}{ctx}, opts...)...)} +} + +func (_c *MockMeSDK_GetOrganizationsMe_Call) Run(run func(ctx context.Context, opts ...operations.Option)) *MockMeSDK_GetOrganizationsMe_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), variadicArgs...) + }) + return _c +} + +func (_c *MockMeSDK_GetOrganizationsMe_Call) Return(_a0 *operations.GetOrganizationsMeResponse, _a1 error) *MockMeSDK_GetOrganizationsMe_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockMeSDK_GetOrganizationsMe_Call) RunAndReturn(run func(context.Context, ...operations.Option) (*operations.GetOrganizationsMeResponse, error)) *MockMeSDK_GetOrganizationsMe_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMeSDK creates a new instance of MockMeSDK. 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 NewMockMeSDK(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMeSDK { + mock := &MockMeSDK{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/konnect/ops/ops.go b/controller/konnect/ops/ops.go index a5158a574..772309157 100644 --- a/controller/konnect/ops/ops.go +++ b/controller/konnect/ops/ops.go @@ -5,7 +5,6 @@ import ( "fmt" "time" - sdkkonnectgo "github.com/Kong/sdk-konnect-go" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -46,7 +45,7 @@ func Create[ TEnt constraints.EntityType[T], ]( ctx context.Context, - sdk *sdkkonnectgo.SDK, + sdk SDKWrapper, cl client.Client, e *T, ) (*T, error) { @@ -54,17 +53,17 @@ func Create[ switch ent := any(e).(type) { case *konnectv1alpha1.KonnectGatewayControlPlane: - return e, createControlPlane(ctx, sdk.ControlPlanes, ent) + return e, createControlPlane(ctx, sdk.GetControlPlaneSDK(), ent) case *configurationv1alpha1.KongService: - return e, createService(ctx, sdk.Services, ent) + return e, createService(ctx, sdk.GetServicesSDK(), ent) case *configurationv1alpha1.KongRoute: - return e, createRoute(ctx, sdk.Routes, ent) + return e, createRoute(ctx, sdk.GetRoutesSDK(), ent) case *configurationv1.KongConsumer: - return e, createConsumer(ctx, sdk.Consumers, ent) + return e, createConsumer(ctx, sdk.GetConsumersSDK(), ent) case *configurationv1beta1.KongConsumerGroup: - return e, createConsumerGroup(ctx, sdk.ConsumerGroups, ent) + return e, createConsumerGroup(ctx, sdk.GetConsumerGroupsSDK(), ent) case *configurationv1alpha1.KongPluginBinding: - return e, createPlugin(ctx, cl, sdk, ent) + return e, createPlugin(ctx, cl, sdk.GetPluginSDK(), ent) // --------------------------------------------------------------------- // TODO: add other Konnect types @@ -79,7 +78,7 @@ func Create[ func Delete[ T constraints.SupportedKonnectEntityType, TEnt constraints.EntityType[T], -](ctx context.Context, sdk *sdkkonnectgo.SDK, cl client.Client, e *T) error { +](ctx context.Context, sdk SDKWrapper, cl client.Client, e *T) error { ent := TEnt(e) if ent.GetKonnectStatus().GetKonnectID() == "" { return fmt.Errorf( @@ -92,17 +91,17 @@ func Delete[ switch ent := any(e).(type) { case *konnectv1alpha1.KonnectGatewayControlPlane: - return deleteControlPlane(ctx, sdk.ControlPlanes, ent) + return deleteControlPlane(ctx, sdk.GetControlPlaneSDK(), ent) case *configurationv1alpha1.KongService: - return deleteService(ctx, sdk.Services, ent) + return deleteService(ctx, sdk.GetServicesSDK(), ent) case *configurationv1alpha1.KongRoute: - return deleteRoute(ctx, sdk.Routes, ent) + return deleteRoute(ctx, sdk.GetRoutesSDK(), ent) case *configurationv1.KongConsumer: - return deleteConsumer(ctx, sdk.Consumers, ent) + return deleteConsumer(ctx, sdk.GetConsumersSDK(), ent) case *configurationv1beta1.KongConsumerGroup: - return deleteConsumerGroup(ctx, sdk.ConsumerGroups, ent) + return deleteConsumerGroup(ctx, sdk.GetConsumerGroupsSDK(), ent) case *configurationv1alpha1.KongPluginBinding: - return deletePlugin(ctx, sdk, ent) + return deletePlugin(ctx, sdk.GetPluginSDK(), ent) // --------------------------------------------------------------------- // TODO: add other Konnect types @@ -117,7 +116,7 @@ func Delete[ func Update[ T constraints.SupportedKonnectEntityType, TEnt constraints.EntityType[T], -](ctx context.Context, sdk *sdkkonnectgo.SDK, syncPeriod time.Duration, cl client.Client, e *T) (ctrl.Result, error) { +](ctx context.Context, sdk SDKWrapper, syncPeriod time.Duration, cl client.Client, e *T) (ctrl.Result, error) { var ( ent = TEnt(e) condProgrammed, ok = k8sutils.GetCondition(conditions.KonnectEntityProgrammedConditionType, ent) @@ -155,17 +154,17 @@ func Update[ switch ent := any(e).(type) { case *konnectv1alpha1.KonnectGatewayControlPlane: - return ctrl.Result{}, updateControlPlane(ctx, sdk.ControlPlanes, ent) + return ctrl.Result{}, updateControlPlane(ctx, sdk.GetControlPlaneSDK(), ent) case *configurationv1alpha1.KongService: - return ctrl.Result{}, updateService(ctx, sdk.Services, ent) + return ctrl.Result{}, updateService(ctx, sdk.GetServicesSDK(), ent) case *configurationv1alpha1.KongRoute: - return ctrl.Result{}, updateRoute(ctx, sdk.Routes, cl, ent) + return ctrl.Result{}, updateRoute(ctx, sdk.GetRoutesSDK(), cl, ent) case *configurationv1.KongConsumer: - return ctrl.Result{}, updateConsumer(ctx, sdk.Consumers, cl, ent) + return ctrl.Result{}, updateConsumer(ctx, sdk.GetConsumersSDK(), cl, ent) case *configurationv1beta1.KongConsumerGroup: - return ctrl.Result{}, updateConsumerGroup(ctx, sdk.ConsumerGroups, cl, ent) + return ctrl.Result{}, updateConsumerGroup(ctx, sdk.GetConsumerGroupsSDK(), cl, ent) case *configurationv1alpha1.KongPluginBinding: - return ctrl.Result{}, updatePlugin(ctx, sdk, cl, ent) + return ctrl.Result{}, updatePlugin(ctx, sdk.GetPluginSDK(), cl, ent) // --------------------------------------------------------------------- // TODO: add other Konnect types diff --git a/controller/konnect/ops/ops_kongpluginbinding.go b/controller/konnect/ops/ops_kongpluginbinding.go index d04c6faab..0fc814897 100644 --- a/controller/konnect/ops/ops_kongpluginbinding.go +++ b/controller/konnect/ops/ops_kongpluginbinding.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" - sdkkonnectgo "github.com/Kong/sdk-konnect-go" sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components" sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations" sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors" @@ -32,7 +31,7 @@ import ( func createPlugin( ctx context.Context, cl client.Client, - sdk *sdkkonnectgo.SDK, + sdk PluginSDK, pluginBinding *configurationv1alpha1.KongPluginBinding, ) error { controlPlaneID := pluginBinding.GetControlPlaneID() @@ -44,7 +43,7 @@ func createPlugin( return err } - resp, err := sdk.Plugins.CreatePlugin(ctx, + resp, err := sdk.CreatePlugin(ctx, controlPlaneID, *pluginInput, ) @@ -87,7 +86,7 @@ func createPlugin( // if the operation fails. func updatePlugin( ctx context.Context, - sdk *sdkkonnectgo.SDK, + sdk PluginSDK, cl client.Client, pb *configurationv1alpha1.KongPluginBinding, ) error { @@ -121,7 +120,7 @@ func updatePlugin( return err } - resp, err := sdk.Plugins.UpsertPlugin(ctx, + resp, err := sdk.UpsertPlugin(ctx, sdkkonnectops.UpsertPluginRequest{ ControlPlaneID: controlPlaneID, PluginID: pb.GetKonnectID(), @@ -167,11 +166,11 @@ func updatePlugin( // It returns an error if the operation fails. func deletePlugin( ctx context.Context, - sdk *sdkkonnectgo.SDK, + sdk PluginSDK, pb *configurationv1alpha1.KongPluginBinding, ) error { id := pb.GetKonnectID() - _, err := sdk.Plugins.DeletePlugin(ctx, pb.GetControlPlaneID(), id) + _, err := sdk.DeletePlugin(ctx, pb.GetControlPlaneID(), id) if errWrapped := wrapErrIfKonnectOpFailed[configurationv1alpha1.KongPluginBinding](err, DeleteOp, pb); errWrapped != nil { // plugin delete operation returns an SDKError instead of a NotFoundError. var sdkError *sdkkonnecterrs.SDKError diff --git a/controller/konnect/ops/plugin.go b/controller/konnect/ops/plugin.go new file mode 100644 index 000000000..4eac06f93 --- /dev/null +++ b/controller/konnect/ops/plugin.go @@ -0,0 +1,15 @@ +package ops + +import ( + "context" + + sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components" + sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations" +) + +// PluginSDK is the interface for Konnect plugin SDK. +type PluginSDK interface { + CreatePlugin(ctx context.Context, controlPlaneID string, plugin sdkkonnectcomp.PluginInput, opts ...sdkkonnectops.Option) (*sdkkonnectops.CreatePluginResponse, error) + UpsertPlugin(ctx context.Context, request sdkkonnectops.UpsertPluginRequest, opts ...sdkkonnectops.Option) (*sdkkonnectops.UpsertPluginResponse, error) + DeletePlugin(ctx context.Context, controlPlaneID string, pluginID string, opts ...sdkkonnectops.Option) (*sdkkonnectops.DeletePluginResponse, error) +} diff --git a/controller/konnect/ops/plugin_mock.go b/controller/konnect/ops/plugin_mock.go new file mode 100644 index 000000000..08262cd87 --- /dev/null +++ b/controller/konnect/ops/plugin_mock.go @@ -0,0 +1,264 @@ +// Code generated by mockery. DO NOT EDIT. + +package ops + +import ( + context "context" + + components "github.com/Kong/sdk-konnect-go/models/components" + + mock "github.com/stretchr/testify/mock" + + operations "github.com/Kong/sdk-konnect-go/models/operations" +) + +// MockPluginSDK is an autogenerated mock type for the PluginSDK type +type MockPluginSDK struct { + mock.Mock +} + +type MockPluginSDK_Expecter struct { + mock *mock.Mock +} + +func (_m *MockPluginSDK) EXPECT() *MockPluginSDK_Expecter { + return &MockPluginSDK_Expecter{mock: &_m.Mock} +} + +// CreatePlugin provides a mock function with given fields: ctx, controlPlaneID, plugin, opts +func (_m *MockPluginSDK) CreatePlugin(ctx context.Context, controlPlaneID string, plugin components.PluginInput, opts ...operations.Option) (*operations.CreatePluginResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, controlPlaneID, plugin) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for CreatePlugin") + } + + var r0 *operations.CreatePluginResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, components.PluginInput, ...operations.Option) (*operations.CreatePluginResponse, error)); ok { + return rf(ctx, controlPlaneID, plugin, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, components.PluginInput, ...operations.Option) *operations.CreatePluginResponse); ok { + r0 = rf(ctx, controlPlaneID, plugin, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.CreatePluginResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, components.PluginInput, ...operations.Option) error); ok { + r1 = rf(ctx, controlPlaneID, plugin, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockPluginSDK_CreatePlugin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePlugin' +type MockPluginSDK_CreatePlugin_Call struct { + *mock.Call +} + +// CreatePlugin is a helper method to define mock.On call +// - ctx context.Context +// - controlPlaneID string +// - plugin components.PluginInput +// - opts ...operations.Option +func (_e *MockPluginSDK_Expecter) CreatePlugin(ctx interface{}, controlPlaneID interface{}, plugin interface{}, opts ...interface{}) *MockPluginSDK_CreatePlugin_Call { + return &MockPluginSDK_CreatePlugin_Call{Call: _e.mock.On("CreatePlugin", + append([]interface{}{ctx, controlPlaneID, plugin}, opts...)...)} +} + +func (_c *MockPluginSDK_CreatePlugin_Call) Run(run func(ctx context.Context, controlPlaneID string, plugin components.PluginInput, opts ...operations.Option)) *MockPluginSDK_CreatePlugin_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-3) + for i, a := range args[3:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(components.PluginInput), variadicArgs...) + }) + return _c +} + +func (_c *MockPluginSDK_CreatePlugin_Call) Return(_a0 *operations.CreatePluginResponse, _a1 error) *MockPluginSDK_CreatePlugin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockPluginSDK_CreatePlugin_Call) RunAndReturn(run func(context.Context, string, components.PluginInput, ...operations.Option) (*operations.CreatePluginResponse, error)) *MockPluginSDK_CreatePlugin_Call { + _c.Call.Return(run) + return _c +} + +// DeletePlugin provides a mock function with given fields: ctx, controlPlaneID, pluginID, opts +func (_m *MockPluginSDK) DeletePlugin(ctx context.Context, controlPlaneID string, pluginID string, opts ...operations.Option) (*operations.DeletePluginResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, controlPlaneID, pluginID) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for DeletePlugin") + } + + var r0 *operations.DeletePluginResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, ...operations.Option) (*operations.DeletePluginResponse, error)); ok { + return rf(ctx, controlPlaneID, pluginID, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string, ...operations.Option) *operations.DeletePluginResponse); ok { + r0 = rf(ctx, controlPlaneID, pluginID, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.DeletePluginResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string, ...operations.Option) error); ok { + r1 = rf(ctx, controlPlaneID, pluginID, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockPluginSDK_DeletePlugin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePlugin' +type MockPluginSDK_DeletePlugin_Call struct { + *mock.Call +} + +// DeletePlugin is a helper method to define mock.On call +// - ctx context.Context +// - controlPlaneID string +// - pluginID string +// - opts ...operations.Option +func (_e *MockPluginSDK_Expecter) DeletePlugin(ctx interface{}, controlPlaneID interface{}, pluginID interface{}, opts ...interface{}) *MockPluginSDK_DeletePlugin_Call { + return &MockPluginSDK_DeletePlugin_Call{Call: _e.mock.On("DeletePlugin", + append([]interface{}{ctx, controlPlaneID, pluginID}, opts...)...)} +} + +func (_c *MockPluginSDK_DeletePlugin_Call) Run(run func(ctx context.Context, controlPlaneID string, pluginID string, opts ...operations.Option)) *MockPluginSDK_DeletePlugin_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-3) + for i, a := range args[3:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(string), variadicArgs...) + }) + return _c +} + +func (_c *MockPluginSDK_DeletePlugin_Call) Return(_a0 *operations.DeletePluginResponse, _a1 error) *MockPluginSDK_DeletePlugin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockPluginSDK_DeletePlugin_Call) RunAndReturn(run func(context.Context, string, string, ...operations.Option) (*operations.DeletePluginResponse, error)) *MockPluginSDK_DeletePlugin_Call { + _c.Call.Return(run) + return _c +} + +// UpsertPlugin provides a mock function with given fields: ctx, request, opts +func (_m *MockPluginSDK) UpsertPlugin(ctx context.Context, request operations.UpsertPluginRequest, opts ...operations.Option) (*operations.UpsertPluginResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, request) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for UpsertPlugin") + } + + var r0 *operations.UpsertPluginResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, operations.UpsertPluginRequest, ...operations.Option) (*operations.UpsertPluginResponse, error)); ok { + return rf(ctx, request, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, operations.UpsertPluginRequest, ...operations.Option) *operations.UpsertPluginResponse); ok { + r0 = rf(ctx, request, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*operations.UpsertPluginResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, operations.UpsertPluginRequest, ...operations.Option) error); ok { + r1 = rf(ctx, request, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockPluginSDK_UpsertPlugin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertPlugin' +type MockPluginSDK_UpsertPlugin_Call struct { + *mock.Call +} + +// UpsertPlugin is a helper method to define mock.On call +// - ctx context.Context +// - request operations.UpsertPluginRequest +// - opts ...operations.Option +func (_e *MockPluginSDK_Expecter) UpsertPlugin(ctx interface{}, request interface{}, opts ...interface{}) *MockPluginSDK_UpsertPlugin_Call { + return &MockPluginSDK_UpsertPlugin_Call{Call: _e.mock.On("UpsertPlugin", + append([]interface{}{ctx, request}, opts...)...)} +} + +func (_c *MockPluginSDK_UpsertPlugin_Call) Run(run func(ctx context.Context, request operations.UpsertPluginRequest, opts ...operations.Option)) *MockPluginSDK_UpsertPlugin_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]operations.Option, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(operations.Option) + } + } + run(args[0].(context.Context), args[1].(operations.UpsertPluginRequest), variadicArgs...) + }) + return _c +} + +func (_c *MockPluginSDK_UpsertPlugin_Call) Return(_a0 *operations.UpsertPluginResponse, _a1 error) *MockPluginSDK_UpsertPlugin_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockPluginSDK_UpsertPlugin_Call) RunAndReturn(run func(context.Context, operations.UpsertPluginRequest, ...operations.Option) (*operations.UpsertPluginResponse, error)) *MockPluginSDK_UpsertPlugin_Call { + _c.Call.Return(run) + return _c +} + +// NewMockPluginSDK creates a new instance of MockPluginSDK. 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 NewMockPluginSDK(t interface { + mock.TestingT + Cleanup(func()) +}) *MockPluginSDK { + mock := &MockPluginSDK{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/controller/konnect/ops/sdkfactory.go b/controller/konnect/ops/sdkfactory.go new file mode 100644 index 000000000..35923aa26 --- /dev/null +++ b/controller/konnect/ops/sdkfactory.go @@ -0,0 +1,87 @@ +package ops + +import ( + sdkkonnectgo "github.com/Kong/sdk-konnect-go" + sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components" +) + +// SDKWrapper is a wrapper of Konnect SDK to allow using mock SDKs in tests. +type SDKWrapper interface { + GetControlPlaneSDK() ControlPlaneSDK + GetServicesSDK() ServicesSDK + GetRoutesSDK() RoutesSDK + GetConsumersSDK() ConsumersSDK + GetConsumerGroupsSDK() ConsumerGroupSDK + GetPluginSDK() PluginSDK + GetMeSDK() MeSDK +} + +type sdkWrapper struct { + sdk *sdkkonnectgo.SDK +} + +var _ SDKWrapper = sdkWrapper{} + +// GetControlPlaneSDK returns the SDK to operate Konenct control planes. +func (w sdkWrapper) GetControlPlaneSDK() ControlPlaneSDK { + return w.sdk.ControlPlanes +} + +// GetServicesSDK returns the SDK to operate Kong services. +func (w sdkWrapper) GetServicesSDK() ServicesSDK { + return w.sdk.Services +} + +// GetRoutesSDK returns the SDK to operate Kong routes. +func (w sdkWrapper) GetRoutesSDK() RoutesSDK { + return w.sdk.Routes +} + +// GetConsumersSDK returns the SDK to operate Kong consumers. +func (w sdkWrapper) GetConsumersSDK() ConsumersSDK { + return w.sdk.Consumers +} + +// GetConsumerGroupsSDK returns the SDK to operate Kong consumer groups. +func (w sdkWrapper) GetConsumerGroupsSDK() ConsumerGroupSDK { + return w.sdk.ConsumerGroups +} + +// GetPluginSDK returns the SDK to operate plugins. +func (w sdkWrapper) GetPluginSDK() PluginSDK { + return w.sdk.Plugins +} + +// GetMeSDK returns the "me" SDK to get current organization. +func (w sdkWrapper) GetMeSDK() MeSDK { + return w.sdk.Me +} + +// SDKToken is a token used to authenticate with the Konnect SDK. +type SDKToken string + +// SDKFactory is a factory for creating Konnect SDKs. +type SDKFactory interface { + NewKonnectSDK(serverURL string, token SDKToken) SDKWrapper +} + +type sdkFactory struct{} + +// NewSDKFactory creates a new SDKFactory. +func NewSDKFactory() SDKFactory { + return sdkFactory{} +} + +// NewKonnectSDK creates a new Konnect SDK. +func (f sdkFactory) NewKonnectSDK(serverURL string, token SDKToken) SDKWrapper { + return sdkWrapper{ + sdk: sdkkonnectgo.New( + sdkkonnectgo.WithSecurity( + sdkkonnectcomp.Security{ + PersonalAccessToken: sdkkonnectgo.String(string(token)), + }, + ), + sdkkonnectgo.WithServerURL(serverURL), + ), + } +} diff --git a/controller/konnect/ops/sdkfactory_mock.go b/controller/konnect/ops/sdkfactory_mock.go new file mode 100644 index 000000000..80487d8eb --- /dev/null +++ b/controller/konnect/ops/sdkfactory_mock.go @@ -0,0 +1,62 @@ +package ops + +type MockSDKWrapper struct { + ControlPlaneSDK *MockControlPlaneSDK + ServicesSDK *MockServicesSDK + RoutesSDK *MockRoutesSDK + ConsumersSDK *MockConsumersSDK + ConsumerGroupSDK *MockConsumerGroupSDK + PluginSDK *MockPluginSDK + MeSDK *MockMeSDK +} + +var _ SDKWrapper = MockSDKWrapper{} + +func (m MockSDKWrapper) GetControlPlaneSDK() ControlPlaneSDK { + return m.ControlPlaneSDK +} + +func (m MockSDKWrapper) GetServicesSDK() ServicesSDK { + return m.ServicesSDK +} + +func (m MockSDKWrapper) GetRoutesSDK() RoutesSDK { + return m.RoutesSDK +} + +func (m MockSDKWrapper) GetConsumersSDK() ConsumersSDK { + return m.ConsumersSDK +} + +func (m MockSDKWrapper) GetConsumerGroupsSDK() ConsumerGroupSDK { + return m.ConsumerGroupSDK +} + +func (m MockSDKWrapper) GetPluginSDK() PluginSDK { + return m.PluginSDK +} + +func (m MockSDKWrapper) GetMeSDK() MeSDK { + return m.MeSDK +} + +type MockSDKFactory struct { + w *MockSDKWrapper +} + +var _ SDKFactory = MockSDKFactory{} + +func (m MockSDKFactory) NewKonnectSDK(_ string, _ SDKToken) SDKWrapper { + if m.w != nil { + return *m.w + } + return &MockSDKWrapper{ + ControlPlaneSDK: &MockControlPlaneSDK{}, + ServicesSDK: &MockServicesSDK{}, + RoutesSDK: &MockRoutesSDK{}, + ConsumersSDK: &MockConsumersSDK{}, + ConsumerGroupSDK: &MockConsumerGroupSDK{}, + PluginSDK: &MockPluginSDK{}, + MeSDK: &MockMeSDK{}, + } +} diff --git a/controller/konnect/reconciler_generic.go b/controller/konnect/reconciler_generic.go index fcd16b455..5f94a0a4a 100644 --- a/controller/konnect/reconciler_generic.go +++ b/controller/konnect/reconciler_generic.go @@ -39,7 +39,7 @@ const ( // KonnectEntityReconciler reconciles a Konnect entities. // It uses the generic type constraints to constrain the supported types. type KonnectEntityReconciler[T constraints.SupportedKonnectEntityType, TEnt constraints.EntityType[T]] struct { - sdkFactory SDKFactory + sdkFactory ops.SDKFactory DevelopmentMode bool Client client.Client SyncPeriod time.Duration @@ -66,7 +66,7 @@ func NewKonnectEntityReconciler[ T constraints.SupportedKonnectEntityType, TEnt constraints.EntityType[T], ]( - sdkFactory SDKFactory, + sdkFactory ops.SDKFactory, developmentMode bool, client client.Client, opts ...KonnectEntityReconcilerOption[T, TEnt], @@ -288,7 +288,7 @@ func (r *KonnectEntityReconciler[T, TEnt]) Reconcile( // because the token is retrieved in runtime through KonnectAPIAuthConfiguration. sdk := r.sdkFactory.NewKonnectSDK( "https://"+apiAuth.Spec.ServerURL, - SDKToken(token), + ops.SDKToken(token), ) if delTimestamp := ent.GetDeletionTimestamp(); !delTimestamp.IsZero() { diff --git a/controller/konnect/reconciler_generic_test.go b/controller/konnect/reconciler_generic_test.go index 92ac0af91..597e3536f 100644 --- a/controller/konnect/reconciler_generic_test.go +++ b/controller/konnect/reconciler_generic_test.go @@ -9,6 +9,7 @@ import ( fakectrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/kong/gateway-operator/controller/konnect/constraints" + "github.com/kong/gateway-operator/controller/konnect/ops" "github.com/kong/gateway-operator/modules/manager/scheme" configurationv1 "github.com/kong/kubernetes-configuration/api/configuration/v1" @@ -38,7 +39,8 @@ func testNewKonnectEntityReconciler[ ) { t.Helper() - sdkFactory := NewSDKFactory() + // TODO: use a mock Konnect SDK factory here and use envtest to trigger real reconciliations and Konnect requests + sdkFactory := &ops.MockSDKFactory{} t.Run(ent.GetTypeName(), func(t *testing.T) { cl := fakectrlruntimeclient.NewFakeClient() diff --git a/controller/konnect/reconciler_konnectapiauth.go b/controller/konnect/reconciler_konnectapiauth.go index 8e8823044..c82898528 100644 --- a/controller/konnect/reconciler_konnectapiauth.go +++ b/controller/konnect/reconciler_konnectapiauth.go @@ -19,6 +19,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/predicate" "github.com/kong/gateway-operator/controller/konnect/conditions" + "github.com/kong/gateway-operator/controller/konnect/ops" "github.com/kong/gateway-operator/controller/pkg/log" k8sutils "github.com/kong/gateway-operator/pkg/utils/kubernetes" @@ -27,7 +28,7 @@ import ( // KonnectAPIAuthConfigurationReconciler reconciles a KonnectAPIAuthConfiguration object. type KonnectAPIAuthConfigurationReconciler struct { - SDKFactory SDKFactory + SDKFactory ops.SDKFactory DevelopmentMode bool Client client.Client } @@ -45,7 +46,7 @@ const ( // NewKonnectAPIAuthConfigurationReconciler creates a new KonnectAPIAuthConfigurationReconciler. func NewKonnectAPIAuthConfigurationReconciler( - sdkFactory SDKFactory, + sdkFactory ops.SDKFactory, developmentMode bool, client client.Client, ) *KonnectAPIAuthConfigurationReconciler { @@ -138,7 +139,7 @@ func (r *KonnectAPIAuthConfigurationReconciler) Reconcile( } sdk := r.SDKFactory.NewKonnectSDK( serverURL, - SDKToken(token), + ops.SDKToken(token), ) // TODO(pmalek): check if api auth config has a valid status condition @@ -150,7 +151,7 @@ func (r *KonnectAPIAuthConfigurationReconciler) Reconcile( // NOTE: This is needed because currently the SDK only lists the prod global API as supported: // https://github.com/Kong/sdk-konnect-go/blob/999d9a987e1aa7d2e09ac11b1450f4563adf21ea/models/operations/getorganizationsme.go#L10-L12 - respOrg, err := sdk.Me.GetOrganizationsMe(ctx, sdkkonnectops.WithServerURL("https://"+apiAuth.Spec.ServerURL)) + respOrg, err := sdk.GetMeSDK().GetOrganizationsMe(ctx, sdkkonnectops.WithServerURL("https://"+apiAuth.Spec.ServerURL)) if err != nil { logger.Error(err, "failed to get organization info from Konnect") if cond, ok := k8sutils.GetCondition(conditions.KonnectEntityAPIAuthConfigurationValidConditionType, &apiAuth); !ok || diff --git a/controller/konnect/sdkfactory.go b/controller/konnect/sdkfactory.go deleted file mode 100644 index 07b6fb7cd..000000000 --- a/controller/konnect/sdkfactory.go +++ /dev/null @@ -1,33 +0,0 @@ -package konnect - -import ( - sdkkonnectgo "github.com/Kong/sdk-konnect-go" - sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components" -) - -// SDKToken is a token used to authenticate with the Konnect SDK. -type SDKToken string - -// SDKFactory is a factory for creating Konnect SDKs. -type SDKFactory interface { - NewKonnectSDK(serverURL string, token SDKToken) *sdkkonnectgo.SDK -} - -type sdkFactory struct{} - -// NewSDKFactory creates a new SDKFactory. -func NewSDKFactory() SDKFactory { - return sdkFactory{} -} - -// NewKonnectSDK creates a new Konnect SDK. -func (f sdkFactory) NewKonnectSDK(serverURL string, token SDKToken) *sdkkonnectgo.SDK { - return sdkkonnectgo.New( - sdkkonnectgo.WithSecurity( - sdkkonnectcomp.Security{ - PersonalAccessToken: sdkkonnectgo.String(string(token)), - }, - ), - sdkkonnectgo.WithServerURL(serverURL), - ) -} diff --git a/modules/manager/controller_setup.go b/modules/manager/controller_setup.go index fb869f7e3..6eb46c04a 100644 --- a/modules/manager/controller_setup.go +++ b/modules/manager/controller_setup.go @@ -22,6 +22,7 @@ import ( "github.com/kong/gateway-operator/controller/gatewayclass" "github.com/kong/gateway-operator/controller/kongplugininstallation" "github.com/kong/gateway-operator/controller/konnect" + konnectops "github.com/kong/gateway-operator/controller/konnect/ops" "github.com/kong/gateway-operator/controller/specialized" "github.com/kong/gateway-operator/internal/utils/index" dataplanevalidator "github.com/kong/gateway-operator/internal/validation/dataplane" @@ -305,7 +306,7 @@ func SetupControllers(mgr manager.Manager, c *Config) (map[string]ControllerDef, // Konnect controllers if c.KonnectControllersEnabled { - sdkFactory := konnect.NewSDKFactory() + sdkFactory := konnectops.NewSDKFactory() controllers[KonnectAPIAuthConfigurationControllerName] = ControllerDef{ Enabled: c.KonnectControllersEnabled,