From 9903815c50f22e37c801b0a85b9c70283fdf21e6 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sun, 2 Feb 2025 15:18:34 +0100 Subject: [PATCH] add basic vault integration --- cmd/migrate.go | 3 +- generate.go | 1 + integration.go | 5 ++ ...enabled_to_workspace_integrations.down.sql | 1 + ...s_enabled_to_workspace_integrations.up.sql | 1 + internal/integrations/paystack.go | 3 + internal/vault/vault.go | 12 +++ mocks/integration.go | 50 +++++++---- mocks/vault.go | 83 +++++++++++++++++++ swagger/docs.go | 5 ++ swagger/swagger.json | 5 ++ swagger/swagger.yaml | 5 ++ web/ui/src/client/Api.ts | 3 + 13 files changed, 158 insertions(+), 19 deletions(-) create mode 100644 internal/datastore/postgres/migrations/20250202140712_add_is_enabled_to_workspace_integrations.down.sql create mode 100644 internal/datastore/postgres/migrations/20250202140712_add_is_enabled_to_workspace_integrations.up.sql create mode 100644 internal/integrations/paystack.go create mode 100644 internal/vault/vault.go create mode 100644 mocks/vault.go diff --git a/cmd/migrate.go b/cmd/migrate.go index 48455f1d..5964b5b2 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -13,7 +13,8 @@ import ( "go.uber.org/zap" ) -func addMigrateCommand(c *cobra.Command, cfg *config.Config) { +func addMigrateCommand(c *cobra.Command, + cfg *config.Config) { cmd := &cobra.Command{ Use: "migrate", diff --git a/generate.go b/generate.go index fab3a3e2..f5ec21cb 100644 --- a/generate.go +++ b/generate.go @@ -26,3 +26,4 @@ package malak //go:generate mockgen -source=preferences.go -destination=mocks/preferences.go -package=malak_mocks //go:generate mockgen -source=integration.go -destination=mocks/integration.go -package=malak_mocks //go:generate mockgen -source=internal/pkg/billing/billing.go -destination=mocks/billing.go -package=malak_mocks +//go:generate mockgen -source=internal/vault/vault.go -destination=mocks/vault.go -package=malak_mocks diff --git a/integration.go b/integration.go index d69d5920..67b25548 100644 --- a/integration.go +++ b/integration.go @@ -47,8 +47,12 @@ type WorkspaceIntegration struct { IntegrationID uuid.UUID `json:"integration_id,omitempty"` Integration *Integration `bun:"rel:belongs-to,join:integration_id=id" json:"integration,omitempty"` + // IsEnabled - this integration is enabled and data can be fetched IsEnabled bool `json:"is_enabled,omitempty"` + // IsActive determines if the connection to the integration has been tested and works + IsActive bool `json:"is_active,omitempty"` + CreatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"created_at,omitempty"` UpdatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"updated_at,omitempty"` DeletedAt *time.Time `bun:",soft_delete,nullzero" json:"-,omitempty"` @@ -86,5 +90,6 @@ type IntegrationDataPoint struct { type IntegrationProviderClient interface { Name() IntegrationProvider + Ping(context.Context) error io.Closer } diff --git a/internal/datastore/postgres/migrations/20250202140712_add_is_enabled_to_workspace_integrations.down.sql b/internal/datastore/postgres/migrations/20250202140712_add_is_enabled_to_workspace_integrations.down.sql new file mode 100644 index 00000000..b308bfac --- /dev/null +++ b/internal/datastore/postgres/migrations/20250202140712_add_is_enabled_to_workspace_integrations.down.sql @@ -0,0 +1 @@ +ALTER TABLE workspace_integrations DROP COLUMN is_active; diff --git a/internal/datastore/postgres/migrations/20250202140712_add_is_enabled_to_workspace_integrations.up.sql b/internal/datastore/postgres/migrations/20250202140712_add_is_enabled_to_workspace_integrations.up.sql new file mode 100644 index 00000000..88b9dd9e --- /dev/null +++ b/internal/datastore/postgres/migrations/20250202140712_add_is_enabled_to_workspace_integrations.up.sql @@ -0,0 +1 @@ +ALTER TABLE workspace_integrations ADD COLUMN is_active BOOLEAN DEFAULT FALSE; diff --git a/internal/integrations/paystack.go b/internal/integrations/paystack.go new file mode 100644 index 00000000..3c41b6e1 --- /dev/null +++ b/internal/integrations/paystack.go @@ -0,0 +1,3 @@ +package integrations + +type PaystackClient struct{} diff --git a/internal/vault/vault.go b/internal/vault/vault.go new file mode 100644 index 00000000..7fda1a9c --- /dev/null +++ b/internal/vault/vault.go @@ -0,0 +1,12 @@ +package vault + +import ( + "context" + "io" +) + +type Vault interface { + io.Closer + Create(context.Context) error + Delete(context.Context) error +} diff --git a/mocks/integration.go b/mocks/integration.go index 7e84993f..cb386476 100644 --- a/mocks/integration.go +++ b/mocks/integration.go @@ -70,32 +70,32 @@ func (mr *MockIntegrationRepositoryMockRecorder) List(arg0, arg1 any) *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIntegrationRepository)(nil).List), arg0, arg1) } -// MockIntegrationProvider is a mock of IntegrationProvider interface. -type MockIntegrationProvider struct { +// MockIntegrationProviderClient is a mock of IntegrationProviderClient interface. +type MockIntegrationProviderClient struct { ctrl *gomock.Controller - recorder *MockIntegrationProviderMockRecorder + recorder *MockIntegrationProviderClientMockRecorder isgomock struct{} } -// MockIntegrationProviderMockRecorder is the mock recorder for MockIntegrationProvider. -type MockIntegrationProviderMockRecorder struct { - mock *MockIntegrationProvider +// MockIntegrationProviderClientMockRecorder is the mock recorder for MockIntegrationProviderClient. +type MockIntegrationProviderClientMockRecorder struct { + mock *MockIntegrationProviderClient } -// NewMockIntegrationProvider creates a new mock instance. -func NewMockIntegrationProvider(ctrl *gomock.Controller) *MockIntegrationProvider { - mock := &MockIntegrationProvider{ctrl: ctrl} - mock.recorder = &MockIntegrationProviderMockRecorder{mock} +// NewMockIntegrationProviderClient creates a new mock instance. +func NewMockIntegrationProviderClient(ctrl *gomock.Controller) *MockIntegrationProviderClient { + mock := &MockIntegrationProviderClient{ctrl: ctrl} + mock.recorder = &MockIntegrationProviderClientMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIntegrationProvider) EXPECT() *MockIntegrationProviderMockRecorder { +func (m *MockIntegrationProviderClient) EXPECT() *MockIntegrationProviderClientMockRecorder { return m.recorder } // Close mocks base method. -func (m *MockIntegrationProvider) Close() error { +func (m *MockIntegrationProviderClient) Close() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Close") ret0, _ := ret[0].(error) @@ -103,21 +103,35 @@ func (m *MockIntegrationProvider) Close() error { } // Close indicates an expected call of Close. -func (mr *MockIntegrationProviderMockRecorder) Close() *gomock.Call { +func (mr *MockIntegrationProviderClientMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockIntegrationProvider)(nil).Close)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockIntegrationProviderClient)(nil).Close)) } // Name mocks base method. -func (m *MockIntegrationProvider) Name() string { +func (m *MockIntegrationProviderClient) Name() malak.IntegrationProvider { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) + ret0, _ := ret[0].(malak.IntegrationProvider) return ret0 } // Name indicates an expected call of Name. -func (mr *MockIntegrationProviderMockRecorder) Name() *gomock.Call { +func (mr *MockIntegrationProviderClientMockRecorder) Name() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockIntegrationProvider)(nil).Name)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockIntegrationProviderClient)(nil).Name)) +} + +// Ping mocks base method. +func (m *MockIntegrationProviderClient) Ping(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Ping", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Ping indicates an expected call of Ping. +func (mr *MockIntegrationProviderClientMockRecorder) Ping(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockIntegrationProviderClient)(nil).Ping), arg0) } diff --git a/mocks/vault.go b/mocks/vault.go new file mode 100644 index 00000000..d928e20c --- /dev/null +++ b/mocks/vault.go @@ -0,0 +1,83 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: internal/vault/vault.go +// +// Generated by this command: +// +// mockgen -source=internal/vault/vault.go -destination=mocks/vault.go -package=malak_mocks +// + +// Package malak_mocks is a generated GoMock package. +package malak_mocks + +import ( + context "context" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockVault is a mock of Vault interface. +type MockVault struct { + ctrl *gomock.Controller + recorder *MockVaultMockRecorder + isgomock struct{} +} + +// MockVaultMockRecorder is the mock recorder for MockVault. +type MockVaultMockRecorder struct { + mock *MockVault +} + +// NewMockVault creates a new mock instance. +func NewMockVault(ctrl *gomock.Controller) *MockVault { + mock := &MockVault{ctrl: ctrl} + mock.recorder = &MockVaultMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockVault) EXPECT() *MockVaultMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockVault) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockVaultMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockVault)(nil).Close)) +} + +// Create mocks base method. +func (m *MockVault) Create(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Create indicates an expected call of Create. +func (mr *MockVaultMockRecorder) Create(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockVault)(nil).Create), arg0) +} + +// Delete mocks base method. +func (m *MockVault) Delete(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockVaultMockRecorder) Delete(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockVault)(nil).Delete), arg0) +} diff --git a/swagger/docs.go b/swagger/docs.go index e9b4d77c..c8af63cd 100644 --- a/swagger/docs.go +++ b/swagger/docs.go @@ -3091,7 +3091,12 @@ const docTemplate = `{ "integration_id": { "type": "string" }, + "is_active": { + "description": "IsActive determines if the connection to the integration has been tested and works", + "type": "boolean" + }, "is_enabled": { + "description": "IsEnabled - this integration is enabled and data can be fetched", "type": "boolean" }, "reference": { diff --git a/swagger/swagger.json b/swagger/swagger.json index f999126f..1ca41f7d 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -825,7 +825,12 @@ "integration_id": { "type": "string" }, + "is_active": { + "description": "IsActive determines if the connection to the integration has been tested and works", + "type": "boolean" + }, "is_enabled": { + "description": "IsEnabled - this integration is enabled and data can be fetched", "type": "boolean" }, "reference": { diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml index 25fbec18..a4e6fdcc 100644 --- a/swagger/swagger.yaml +++ b/swagger/swagger.yaml @@ -567,7 +567,12 @@ components: $ref: '#/components/schemas/malak.Integration' integration_id: type: string + is_active: + description: IsActive determines if the connection to the integration has + been tested and works + type: boolean is_enabled: + description: IsEnabled - this integration is enabled and data can be fetched type: boolean reference: type: string diff --git a/web/ui/src/client/Api.ts b/web/ui/src/client/Api.ts index 172eda37..336448da 100644 --- a/web/ui/src/client/Api.ts +++ b/web/ui/src/client/Api.ts @@ -352,6 +352,9 @@ export interface MalakWorkspaceIntegration { id?: string; integration?: MalakIntegration; integration_id?: string; + /** IsActive determines if the connection to the integration has been tested and works */ + is_active?: boolean; + /** IsEnabled - this integration is enabled and data can be fetched */ is_enabled?: boolean; reference?: string; updated_at?: string;