Skip to content

Commit b686257

Browse files
Arta AsadiArta Asadi
authored andcommitted
fix: add load and remove demo data
1 parent 504bdad commit b686257

File tree

6 files changed

+197
-10
lines changed

6 files changed

+197
-10
lines changed

services/integration/api/integration-types/api.go

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package integration_types
33
import (
44
"encoding/json"
55
"fmt"
6+
"github.com/google/uuid"
7+
"github.com/jackc/pgtype"
68
"github.com/opengovern/og-util/pkg/config"
79
"github.com/opengovern/og-util/pkg/httpclient"
810
"github.com/opengovern/og-util/pkg/opengovernance-es-sdk"
@@ -85,6 +87,7 @@ func (a *API) Register(e *echo.Group) {
8587
plugin.POST("/:id/healthcheck", httpserver.AuthorizeHandler(a.HealthCheck, api.ViewerRole))
8688
plugin.GET("/tables", httpserver.AuthorizeHandler(a.GetPluginsTables, api.ViewerRole))
8789
plugin.PUT("/:id/demo/load", httpserver.AuthorizeHandler(a.LoadPluginDemoData, api.EditorRole))
90+
plugin.PUT("/:id/demo/remove", httpserver.AuthorizeHandler(a.RemovePluginDemoData, api.EditorRole))
8891
}
8992

9093
// List godoc
@@ -1343,6 +1346,10 @@ func (a *API) LoadPluginDemoData(c echo.Context) error {
13431346
return echo.NewHTTPError(http.StatusNotFound, "plugin not found")
13441347
}
13451348

1349+
if plugin.DemoDataLoaded {
1350+
return echo.NewHTTPError(http.StatusConflict, "plugin demo data already loaded")
1351+
}
1352+
13461353
if plugin.DemoDataURL == "" {
13471354
return echo.NewHTTPError(http.StatusNotFound, "plugin does not contain demo data")
13481355
}
@@ -1354,7 +1361,111 @@ func (a *API) LoadPluginDemoData(c echo.Context) error {
13541361
ElasticsearchPass: a.elasticConfig.Password,
13551362
ElasticsearchAddr: a.elasticConfig.Address,
13561363
}
1357-
err = demo_import.LoadDemoData(demoImportConfig, a.logger)
1364+
integrations, err := demo_import.LoadDemoData(demoImportConfig, a.logger)
1365+
if err != nil {
1366+
a.logger.Error("failed to load demo data", zap.Error(err))
1367+
return echo.NewHTTPError(http.StatusInternalServerError, "failed to load demo data")
1368+
}
1369+
1370+
dummyCredentialID := uuid.New()
1371+
dummyCredential := models2.Credential{
1372+
ID: dummyCredentialID,
1373+
IntegrationType: plugin.IntegrationType,
1374+
CredentialType: "",
1375+
Secret: "",
1376+
Metadata: func() pgtype.JSONB {
1377+
var jsonb pgtype.JSONB
1378+
if err := jsonb.Set([]byte("{}")); err != nil {
1379+
a.logger.Error("failed to convert WidgetProps to JSONB", zap.Error(err))
1380+
}
1381+
return jsonb
1382+
}(),
1383+
MaskedSecret: func() pgtype.JSONB {
1384+
var jsonb pgtype.JSONB
1385+
if err := jsonb.Set([]byte("{}")); err != nil {
1386+
a.logger.Error("failed to convert WidgetProps to JSONB", zap.Error(err))
1387+
}
1388+
return jsonb
1389+
}(),
1390+
Description: "dummy credential for demo integrations",
1391+
}
1392+
1393+
err = a.database.CreateCredential(&dummyCredential)
1394+
if err != nil {
1395+
a.logger.Error("failed to create credential", zap.Error(err))
1396+
return echo.NewHTTPError(http.StatusInternalServerError, "failed to create credential")
1397+
}
1398+
1399+
for _, i := range integrations {
1400+
integrationId, err := uuid.Parse(i.IntegrationID)
1401+
if err != nil {
1402+
a.logger.Error("failed to parse integration id", zap.Error(err))
1403+
return echo.NewHTTPError(http.StatusInternalServerError, "failed to parse integration id")
1404+
}
1405+
dbIntegration := models2.Integration{
1406+
Integration: integration.Integration{
1407+
IntegrationID: integrationId,
1408+
ProviderID: i.ProviderID,
1409+
Name: i.Name,
1410+
IntegrationType: plugin.IntegrationType,
1411+
Annotations: func() pgtype.JSONB {
1412+
var jsonb pgtype.JSONB
1413+
if err := jsonb.Set(i.Annotations); err != nil {
1414+
a.logger.Error("failed to convert WidgetProps to JSONB", zap.Error(err))
1415+
}
1416+
return jsonb
1417+
}(),
1418+
Labels: func() pgtype.JSONB {
1419+
var jsonb pgtype.JSONB
1420+
if err := jsonb.Set(i.Labels); err != nil {
1421+
a.logger.Error("failed to convert WidgetProps to JSONB", zap.Error(err))
1422+
}
1423+
return jsonb
1424+
}(),
1425+
CredentialID: dummyCredentialID,
1426+
State: integration.IntegrationStateSample,
1427+
},
1428+
}
1429+
err = a.database.CreateIntegration(&dbIntegration)
1430+
if err != nil {
1431+
a.logger.Error("failed to create integration", zap.Error(err))
1432+
return echo.NewHTTPError(http.StatusInternalServerError, "failed to create integration")
1433+
}
1434+
}
1435+
1436+
return c.NoContent(http.StatusOK)
1437+
}
1438+
1439+
// RemovePluginDemoData godoc
1440+
//
1441+
// @Summary Remove demo data for plugin
1442+
// @Description Remove demo data for plugin by the given url
1443+
// @Security BearerToken
1444+
// @Tags integration_types
1445+
// @Produce json
1446+
// @Param id path string true "plugin id"
1447+
// @Success 200
1448+
// @Router /integration/api/v1/plugin/{id}/demo/remove [put]
1449+
func (a *API) RemovePluginDemoData(c echo.Context) error {
1450+
id := c.Param("id")
1451+
1452+
plugin, err := a.database.GetPluginByID(id)
1453+
if err != nil {
1454+
a.logger.Error("failed to get plugin", zap.Error(err))
1455+
return echo.NewHTTPError(http.StatusInternalServerError, "failed to get plugin")
1456+
}
1457+
if plugin == nil {
1458+
return echo.NewHTTPError(http.StatusNotFound, "plugin not found")
1459+
}
1460+
1461+
if !plugin.DemoDataLoaded {
1462+
return echo.NewHTTPError(http.StatusConflict, "plugin demo data not loaded")
1463+
}
1464+
1465+
if err = a.database.DeletePluginSampleIntegrations(plugin.IntegrationType); err != nil {
1466+
a.logger.Error("failed to delete plugin sample integration", zap.Error(err))
1467+
return echo.NewHTTPError(http.StatusInternalServerError, "failed to delete plugin sample integration")
1468+
}
13581469

13591470
return c.NoContent(http.StatusOK)
13601471
}

services/integration/db/integration.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ func (db Database) DeleteIntegration(IntegrationID uuid.UUID) error {
3939
return nil
4040
}
4141

42+
// DeletePluginSampleIntegrations deletes sample integrations for a plugin
43+
func (db Database) DeletePluginSampleIntegrations(integrationType integration.Type) error {
44+
tx := db.Orm.
45+
Where("state = ?", integration.IntegrationStateSample).
46+
Where("integration_type = ?", integrationType).
47+
Unscoped().
48+
Delete(&models.Integration{})
49+
if tx.Error != nil {
50+
return tx.Error
51+
}
52+
53+
return nil
54+
}
55+
4256
// DeleteSampleIntegrations deletes sample integrations
4357
func (db Database) DeleteSampleIntegrations() error {
4458
tx := db.Orm.

services/integration/db/integration_plugin.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,30 @@ func (db Database) GetPluginByID(pluginID string) (*models.IntegrationPlugin, er
3232
return &plugin, nil
3333
}
3434

35+
func (db Database) PluginDemoDataLoad(pluginID string) error {
36+
err := db.IntegrationTypeOrm.Model(models.IntegrationPlugin{}).Where("plugin_id = ?", pluginID).
37+
Update("demo_data_loaded = ?", true).Error
38+
if err != nil {
39+
if errors.Is(err, gorm.ErrRecordNotFound) {
40+
return nil
41+
}
42+
return err
43+
}
44+
return nil
45+
}
46+
47+
func (db Database) PluginDemoDataUnLoad(pluginID string) error {
48+
err := db.IntegrationTypeOrm.Model(models.IntegrationPlugin{}).Where("plugin_id = ?", pluginID).
49+
Update("demo_data_loaded = ?", false).Error
50+
if err != nil {
51+
if errors.Is(err, gorm.ErrRecordNotFound) {
52+
return nil
53+
}
54+
return err
55+
}
56+
return nil
57+
}
58+
3559
func (db Database) UpdatePluginInstallTimedOut(pluginInstallTime int64) error {
3660
tx := db.IntegrationTypeOrm.
3761
Model(&models.IntegrationPlugin{}).

services/integration/demo-import/import.go

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package demo_import
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"github.com/opengovern/og-util/pkg/integration"
57
"go.uber.org/zap"
68
"io"
79
"net/http"
@@ -25,14 +27,23 @@ type Config struct {
2527
ElasticsearchAddr string
2628
}
2729

28-
func LoadDemoData(cfg Config, logger *zap.Logger) error {
30+
type Integration struct {
31+
IntegrationID string
32+
ProviderID string
33+
Name string
34+
IntegrationType integration.Type
35+
Annotations map[string]string
36+
Labels map[string]string
37+
}
38+
39+
func LoadDemoData(cfg Config, logger *zap.Logger) ([]Integration, error) {
2940
logger.Info("Starting data loading process with provided config...")
3041

3142
wd, err := os.Getwd()
3243
if err != nil {
3344
// Log error before returning
3445
logger.Error("Failed to get current working directory", zap.Error(err))
35-
return fmt.Errorf("failed to get current working directory: %w", err)
46+
return nil, fmt.Errorf("failed to get current working directory: %w", err)
3647
}
3748
workDir := wd
3849

@@ -42,7 +53,13 @@ func LoadDemoData(cfg Config, logger *zap.Logger) error {
4253
decryptedFilePath := filepath.Join(workDir, "demo_data.tar.gz")
4354
// Assuming tar extracts relative paths inside the archive into the current dir (workDir).
4455
inputPathForDump := filepath.Join(workDir, "/demo-data/es-demo/")
45-
//:= filepath.Join(workDir, "/demo-data/integrations.json")
56+
integrationsJsonFilePath := filepath.Join(workDir, "/demo-data/integrations.json")
57+
58+
integrations, err := loadIntegrationsFromJSON(integrationsJsonFilePath)
59+
if err != nil {
60+
logger.Error("Failed to load integrations.", zap.Error(err))
61+
return nil, fmt.Errorf("failed to load integrations.: %w", err)
62+
}
4663

4764
// --- Ensure cleanup of intermediate files ---
4865
defer func() {
@@ -67,7 +84,7 @@ func LoadDemoData(cfg Config, logger *zap.Logger) error {
6784
zap.String("destination", encryptedFilePath))
6885
err = downloadFile(encryptedFilePath, cfg.DemoDataURL, logger)
6986
if err != nil {
70-
return fmt.Errorf("failed to download file: %w", err)
87+
return nil, fmt.Errorf("failed to download file: %w", err)
7188
}
7289
logger.Info("Successfully downloaded file", zap.String("path", encryptedFilePath))
7390

@@ -84,7 +101,7 @@ func LoadDemoData(cfg Config, logger *zap.Logger) error {
84101
}
85102
err = runCommand(workDir, "openssl", logger, opensslArgs...) // Pass logger
86103
if err != nil {
87-
return fmt.Errorf("failed to run openssl command: %w", err)
104+
return nil, fmt.Errorf("failed to run openssl command: %w", err)
88105
}
89106
logger.Info("Successfully decrypted file", zap.String("path", decryptedFilePath))
90107

@@ -95,7 +112,7 @@ func LoadDemoData(cfg Config, logger *zap.Logger) error {
95112
tarArgs := []string{"-xvf", decryptedFilePath}
96113
err = runCommand(workDir, "tar", logger, tarArgs...) // Pass logger
97114
if err != nil {
98-
return fmt.Errorf("failed to run tar command: %w", err)
115+
return nil, fmt.Errorf("failed to run tar command: %w", err)
99116
}
100117
logger.Info("Successfully extracted tarball", zap.String("path", decryptedFilePath))
101118

@@ -140,12 +157,12 @@ func LoadDemoData(cfg Config, logger *zap.Logger) error {
140157
err = cmd.Run()
141158
if err != nil {
142159
logger.Error("multielasticdump command failed", zap.Error(err))
143-
return fmt.Errorf("failed to run multielasticdump command: %w", err)
160+
return nil, fmt.Errorf("failed to run multielasticdump command: %w", err)
144161
}
145162
logger.Info("Successfully ran multielasticdump.")
146163

147164
logger.Info("Data loading process completed successfully.")
148-
return nil // Success
165+
return integrations, nil
149166
}
150167

151168
// downloadFile downloads a file from a URL and saves it locally, using zap for logging.
@@ -219,3 +236,23 @@ func runCommand(workDir string, name string, logger *zap.Logger, args ...string)
219236
logger.Debug("Command executed successfully", zap.String("command", name))
220237
return nil
221238
}
239+
240+
func loadIntegrationsFromJSON(filePath string) ([]Integration, error) {
241+
jsonData, err := os.ReadFile(filePath)
242+
if err != nil {
243+
return nil, fmt.Errorf("failed to read file %s: %w", filePath, err)
244+
}
245+
246+
if len(jsonData) == 0 {
247+
return []Integration{}, nil
248+
}
249+
250+
var integrations []Integration
251+
252+
err = json.Unmarshal(jsonData, &integrations)
253+
if err != nil {
254+
return nil, fmt.Errorf("failed to unmarshal JSON from %s: %w", filePath, err)
255+
}
256+
257+
return integrations, nil
258+
}

services/integration/models/integration_plugin.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type IntegrationPlugin struct {
5757
URL string
5858
DescriberURL string
5959
DemoDataURL string
60+
DemoDataLoaded bool
6061
DescriberTag string
6162
OperationalStatusUpdates pgtype.JSONB `gorm:"default:'[]'"`
6263
Tags pgtype.JSONB

services/tasks/http.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ func (r *httpRoutes) ListTaskRunResults(ctx echo.Context) error {
364364
var result map[string]interface{}
365365
err = json.Unmarshal(task.Result.Bytes, &result)
366366
if err != nil {
367-
r.logger.Error("failed to unmarshal result", zap.Error(err))
367+
r.logger.Error("failed to unmarshal result json", zap.Error(err))
368368
return ctx.JSON(http.StatusInternalServerError, "failed to unmarshal result")
369369
}
370370
taskRunResponses = append(taskRunResponses, api.TaskRun{

0 commit comments

Comments
 (0)