1 package services
2
3 import (
4 "context"
5 _ "embed"
6 "encoding/base64"
7 "encoding/json"
8 "fmt"
9 "net/http"
10 "net/http/httptest"
11 "strings"
12 "testing"
13 "time"
14
15 pubSub "cloud.google.com/go/pubsub"
16 "github.com/DATA-DOG/go-sqlmock"
17 helmApi "github.com/fluxcd/helm-controller/api/v2"
18 "github.com/fluxcd/pkg/apis/meta"
19 helmRepositoryApi "github.com/fluxcd/source-controller/api/v1"
20 "github.com/golang/mock/gomock"
21 "github.com/stretchr/testify/assert"
22 "github.com/thoas/go-funk"
23 "google.golang.org/api/option"
24 "helm.sh/helm/v3/pkg/chart"
25 "helm.sh/helm/v3/pkg/repo"
26 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 "sigs.k8s.io/yaml"
29
30 sqlerr "edge-infra.dev/pkg/edge/api/apierror/sql"
31 "edge-infra.dev/pkg/edge/api/bsl/types"
32 "edge-infra.dev/pkg/edge/api/graph/mapper"
33 "edge-infra.dev/pkg/edge/api/graph/model"
34 "edge-infra.dev/pkg/edge/api/middleware"
35 "edge-infra.dev/pkg/edge/api/mocks"
36 sqlquery "edge-infra.dev/pkg/edge/api/sql"
37 "edge-infra.dev/pkg/edge/api/status"
38 edgetypes "edge-infra.dev/pkg/edge/api/types"
39 helmTypes "edge-infra.dev/pkg/edge/api/types"
40 chariotAPI "edge-infra.dev/pkg/edge/chariot/client"
41 "edge-infra.dev/pkg/edge/constants"
42 "edge-infra.dev/pkg/edge/externalsecrets"
43 chariotClientApiTestutils "edge-infra.dev/test/framework/gcp/pubsub"
44 )
45
46 const (
47 apiVersion = "clusterregistry.k8s.io/v1alpha1"
48 bannerEdgeID = "banner_edge_id"
49 clusterEdgeID = "cluster_edge_id"
50 clusterExternalSecret = "ClusterExternalSecret"
51 chartName = "helm_chart"
52 chartVersion = "1.0.0"
53 testTime = "2022-01-01 12:00:00"
54 helmSecret = "helm_secret"
55 helmRepoKind = "HelmRepository"
56 helmRepoURL = "https://example.com"
57 readme = `# Helm Application`
58 testChariotPubsubTopic = "chariot-pubsub-topic"
59 testChariotPubsubSubscription = "chariot-pubsub-subscription"
60 testHelmRepo = "helm_repo"
61 helmRelease = "HelmRelease"
62 namespace = "Namespace"
63 externalSecret = "ExternalSecret"
64 configSchema = `
65 {
66 "$id": "https://example.com/geographical-location.schema.json",
67 "$schema": "https://json-schema.org/draft/2020-12/schema",
68 "title": "Longitude and Latitude Values",
69 "description": "geographical coordinates.",
70 "required": [ "latitude", "longitude" ],
71 "type": "object",
72 "properties": {
73 "latitude": {
74 "type": "number",
75 "minimum": -90,
76 "maximum": 90
77 },
78 "longitude": {
79 "type": "number",
80 "minimum": -180,r
81 "maximum": 180
82 }
83 }
84 }
85 `
86 configValue = `
87 {
88 "latitude": 50,
89 "longitude": 30
90 }
91 `
92 helmEdgeID = "be8536ff-d463-4aff-8fa9-fe81fec1ddc1"
93 testClusterEdgeID = "3396a52c-6a22-4049-9593-5a63b596a200"
94 testBannerEdgeID = "3396a52c-6a22-4049-9593-5a63b596a201"
95 )
96
97 var ns = "default"
98 var appConfig = &edgetypes.Config{Chariot: edgetypes.ChariotConfig{}}
99 var jsonConfig = "{\"version\":10}"
100
101
102 var zippedChart string
103
104 func TestHelmService_CreateAndDeleteBannerHelmRepo(t *testing.T) {
105 name := "test-repo"
106
107 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
108 if err != nil {
109 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
110 }
111 defer db.Close()
112 mock.MatchExpectationsInOrder(true)
113
114 helmWorkload := getTestHelmWorkloadQuery()
115
116 mock.ExpectQuery(sqlquery.GetHelmWorkloadsByBannerEdgeID).
117 WithArgs(bannerEdgeID).
118 WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id", "banner_edge_id", "helm_edge_id", "workload_name", " workload_namespace", "helm_chart", "helm_repo", "helm_chart_version", "helm_config", "installed_by", "workload_installation_type", "created_at", "updated_at", "helm_repo_secret", "project_id", "deleted"}).
119 AddRow(
120 helmWorkload.ClusterEdgeID,
121 helmWorkload.BannerEdgeID,
122 helmWorkload.HelmEdgeID,
123 helmWorkload.Name,
124 helmWorkload.Namespace,
125 helmWorkload.HelmChart,
126 helmWorkload.HelmRepository,
127 helmWorkload.HelmChartVersion,
128 helmWorkload.HelmConfig,
129 helmWorkload.InstalledBy,
130 helmWorkload.WorkloadInstallationType,
131 helmWorkload.CreatedAt,
132 helmWorkload.UpdatedAt,
133 helmWorkload.HelmRepoSecret,
134 helmWorkload.ProjectID, false))
135
136 mock.ExpectQuery(sqlquery.GetHelmWorkloadsByBannerEdgeID).
137 WithArgs(bannerEdgeID).
138 WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id", "banner_edge_id", "helm_edge_id", "workload_name", " workload_namespace", "helm_chart", "helm_repo", "helm_chart_version", "helm_config", "installed_by", "workload_installation_type", "created_at", "updated_at", "helm_repo_secret", "project_id", "deleted"}).
139 AddRow(
140 helmWorkload.ClusterEdgeID,
141 helmWorkload.BannerEdgeID,
142 helmWorkload.HelmEdgeID,
143 helmWorkload.Name,
144 helmWorkload.Namespace,
145 helmWorkload.HelmChart,
146 "",
147 helmWorkload.HelmChartVersion,
148 helmWorkload.HelmConfig,
149 helmWorkload.InstalledBy,
150 helmWorkload.WorkloadInstallationType,
151 helmWorkload.CreatedAt,
152 helmWorkload.UpdatedAt,
153 helmWorkload.HelmRepoSecret,
154 helmWorkload.ProjectID, false))
155
156 assertSubscriptionMessage := func(message *pubSub.Message) {
157 msg := &chariotAPI.ChariotMessage{}
158 err := json.Unmarshal(message.Data, msg)
159 if err != nil {
160 fmt.Println(err)
161 }
162 assert.Equal(t, projectID, msg.Banner)
163 if len(msg.Objects) > 0 {
164 for _, obj := range msg.Objects {
165 decoded, err := base64.StdEncoding.DecodeString(obj)
166 assert.NoError(t, err)
167 res := strings.Split(string(decoded), ",")
168 objKind := res[0][9 : len(res[0])-1]
169 switch objKind {
170 case clusterExternalSecret:
171 helmRepoMsg := &helmRepositoryApi.HelmRepository{}
172 err = json.Unmarshal(decoded, &helmRepoMsg)
173 assert.NoError(t, err)
174 assert.Equal(t, clusterExternalSecret, helmRepoMsg.Kind)
175 assert.Equal(t, name, helmRepoMsg.ObjectMeta.Name)
176 assert.Equal(t, constants.FluxSystem, helmRepoMsg.ObjectMeta.Namespace)
177 assert.Equal(t, projectID, helmRepoMsg.ObjectMeta.Labels[constants.Tenant])
178 default:
179 fmt.Println("obj kind not supported")
180 }
181 }
182 }
183 }
184 done := make(chan bool)
185 chariotPubsubClient, err := createChariotV2TestTopic(done, assertSubscriptionMessage)
186 assert.NoError(t, err)
187 chariotService := NewChariotService(projectID, testChariotPubsubTopic, chariotPubsubClient)
188
189 service := NewHelmService(appConfig, chariotService, nil, db, nil, nil)
190 assert.NoError(t, service.CreateBannerHelmRepository(context.Background(), name, "test_url", nil, projectID))
191 assert.Error(t, service.DeleteHelmRepo(context.Background(), name, projectID, bannerEdgeID))
192
193 assert.NoError(t, service.DeleteHelmRepo(context.Background(), name, projectID, bannerEdgeID))
194 }
195
196 func TestHelmService_GetHelmReleasesStatus(t *testing.T) {
197 clusterName := "test_cluster2"
198 testCluster := getTestCluster(clusterName)
199
200 helm1 := getTestHelmReleaseWithStatus("helm_release_1", true)
201 helm2 := getTestHelmReleaseWithStatus("helm_release_2", false)
202 repo1 := getTestHelmRepository("helm_release_1")
203 repo2 := getTestHelmRepository("helm_release_2")
204
205 srv := createHelmRepoClient(t, map[string][]byte{})
206 getSecret := func(_ context.Context, name *string, owner, _type *string, getValues bool, _projectID string) ([]*model.SecretManagerResponse, error) {
207 assert.Equal(t, helmSecret, *name)
208 assert.Nil(t, owner)
209 assert.Equal(t, helmRepoSecretType, *_type)
210 assert.True(t, getValues)
211 assert.Equal(t, projectID, _projectID)
212 return []*model.SecretManagerResponse{getSecretManagerResponse(*name, _projectID, srv.URL, helmRepoSecretType)}, nil
213 }
214
215 getKubeResource := func(_ context.Context, _projectID string, cluster *model.Cluster, input model.LoqRequest) ([]string, error) {
216 assert.Equal(t, projectID, _projectID)
217 assert.Equal(t, clusterName, cluster.Name)
218 assert.Contains(t, []model.LoqRequest{mapper.GetHelmReleases()}, input)
219
220 if input == mapper.GetHelmRepositories() {
221 res1, err := json.Marshal(repo1)
222 assert.NoError(t, err)
223
224 res2, err := json.Marshal(repo2)
225 assert.NoError(t, err)
226 return []string{string(res1), string(res2)}, err
227 }
228
229 res1, err := json.Marshal(helm1)
230 assert.NoError(t, err)
231
232 res2, err := json.Marshal(helm2)
233 assert.NoError(t, err)
234 return []string{string(res1), string(res2)}, err
235 }
236 gcpService := createGCPServiceMock(t, getSecret)
237 bqClientMock := createMockBQClient(t, getKubeResource)
238 service := NewHelmService(appConfig, nil, gcpService, nil, bqClientMock, nil)
239
240 releases, err := service.GetHelmReleasesStatus(context.Background(), testCluster)
241 assert.NoError(t, err)
242 assert.Len(t, releases, 2)
243
244 h1 := releases[0]
245 assert.Equal(t, "helm_release_1", h1.Name)
246 assert.Equal(t, "Succeeded", h1.StatusType)
247 assert.Nil(t, h1.InstallCondition)
248 assert.NotNil(t, h1.ReadyCondition)
249
250 h2 := releases[1]
251 assert.Equal(t, "helm_release_2", h2.Name)
252 assert.Equal(t, "Failed", h2.StatusType)
253 assert.NotNil(t, h2.InstallCondition)
254 assert.Nil(t, h2.ReadyCondition)
255
256 for _, release := range releases {
257 assert.NotEmpty(t, release.LastActionTime)
258 assert.Equal(t, chartVersion, release.VersionInstalled)
259 assert.Equal(t, chartVersion, release.VersionRequested)
260 assert.NotNil(t, release.ConfigValues)
261 }
262 }
263
264 func TestSendExternalSecretToChariot(t *testing.T) {
265 testExternalSecretOne := externalsecrets.DefaultExternalSecret().
266 Name("test-ext-scrt-1").
267 Namespace("default").
268 ProjectID(projectID).
269 Path(chariotPath)
270 testExternalSecretTwo := externalsecrets.DefaultExternalSecret().
271 Name("test-ext-scrt-2").
272 Namespace("default").
273 ProjectID(projectID).
274 Path(chariotPath)
275
276 testExternalSecretOneBuilt, err := testExternalSecretOne.Build()
277 assert.NoError(t, err)
278 externalSecretOneByte, err := json.Marshal(testExternalSecretOneBuilt)
279 assert.NoError(t, err)
280
281 testExternalSecretTwoBuilt, err := testExternalSecretTwo.Build()
282 assert.NoError(t, err)
283 externalSecretTwoByte, err := json.Marshal(testExternalSecretTwoBuilt)
284 assert.NoError(t, err)
285 assertFunc := func(message *pubSub.Message) {
286 msg := &chariotAPI.ChariotMessage{}
287 err := json.Unmarshal(message.Data, msg)
288 if err != nil {
289 fmt.Println(err)
290 }
291 assert.Equal(t, msg.Operation, chariotAPI.Create.String())
292 assert.Equal(t, msg.Owner, ComponentOwner)
293 assert.Equal(t, len(msg.Objects), 2)
294 for _, obj := range msg.Objects {
295 externalSrtByte, err := base64.StdEncoding.DecodeString(obj)
296 assert.NoError(t, err)
297 assert.True(t, (string(externalSrtByte) == string(externalSecretOneByte)) || (string(externalSrtByte) == string(externalSecretTwoByte)))
298 }
299 }
300 done := make(chan bool)
301 chariotPubsubClient, err := createChariotV2TestTopic(done, assertFunc)
302 assert.NoError(t, err)
303 chariotService := NewChariotService(projectID, testChariotPubsubTopic, chariotPubsubClient)
304 assert.NoError(t, err)
305 service := NewHelmService(appConfig, chariotService, nil, nil, nil, nil)
306 externalSecrets := []*externalsecrets.ExternalSecret{
307 testExternalSecretOne,
308 testExternalSecretTwo,
309 }
310 err = service.SendExternalSecretToChariot(context.Background(), projectID, "test-org", externalSecrets)
311 assert.NoError(t, err)
312 <-done
313 }
314
315 func TestGenerateHelmReleaseExternalSecretsWithExternalSecrets(t *testing.T) {
316 helmReleasName := "helm-release-with-external-secret"
317 clusterName := "test-cluster"
318 testSecret1 := "test-secret-1"
319 testSecret2 := "test-secret-2"
320 testCluster := getTestCluster(clusterName)
321 clusterEdgeID := &testCluster.ClusterEdgeID
322 payload := getHelmPayload(nil, clusterEdgeID, helmReleasName, jsonConfig, testSecret1, testSecret2)
323
324 getSecret := func(_ context.Context, _ *string, _, _ *string, getValues bool, _projectID string) ([]*model.SecretManagerResponse, error) {
325 assert.True(t, getValues)
326 assert.Equal(t, testCluster.ProjectID, _projectID)
327 return generateSecrets(testCluster.ProjectID, payload.Secrets), nil
328 }
329 gcpService := createGCPServiceMock(t, getSecret)
330
331 chariotService := NewChariotService(projectID, testChariotPubsubTopic, nil)
332 service := NewHelmService(appConfig, chariotService, gcpService, nil, nil, nil)
333
334 externalSecrets, err := service.GenerateHelmReleaseExternalSecrets(context.Background(), testCluster.ProjectID, payload.Namespace, []string{testSecret1, testSecret2})
335 assert.NoError(t, err)
336 assert.NotEmpty(t, externalSecrets)
337 }
338
339 func TestGenerateHelmReleaseExternalSecrets(t *testing.T) {
340 dp := externalsecrets.DockerPullSecretType
341 res := createExternalSecretByType(projectID, namespace, &model.SecretManagerResponse{
342 Name: "docker-pull",
343 Project: projectID,
344 Values: []*model.KeyValuesOutput{{
345 Key: "dockerconfigjson",
346 Value: "config",
347 }},
348 Type: &dp,
349 })
350 sec, err := res.Build()
351 assert.NoError(t, err)
352 assert.Equal(t, "dockerconfigjson", sec.Spec.Data[0].SecretKey)
353 }
354
355 func generateSecrets(projectID string, secrets []string) []*model.SecretManagerResponse {
356 secretResp := make([]*model.SecretManagerResponse, 0)
357 for _, name := range secrets {
358 secretResp = append(secretResp, getSecretManagerResponse(name, projectID, "test_helmUrl", helmRepoSecretType))
359 }
360 dp := externalsecrets.DockerPullSecretType
361 secretResp = append(secretResp, &model.SecretManagerResponse{
362 Name: "docker-pull",
363 Project: projectID,
364 Values: []*model.KeyValuesOutput{{
365 Key: ".dockerconfigjson",
366 Value: "config",
367 }},
368 Type: &dp,
369 })
370 return secretResp
371 }
372
373 func TestHelmService_GetHelmCharts(t *testing.T) {
374 srv := createHelmRepoClient(t, map[string][]byte{})
375 getSecret := func(_ context.Context, name *string, owner, _type *string, getValues bool, _projectID string) ([]*model.SecretManagerResponse, error) {
376 assert.Equal(t, helmSecret, *name)
377 assert.Nil(t, owner)
378 assert.Equal(t, helmRepoSecretType, *_type)
379 assert.True(t, getValues)
380 assert.Equal(t, projectID, _projectID)
381 return []*model.SecretManagerResponse{getSecretManagerResponse(*name, _projectID, srv.URL, helmRepoSecretType)}, nil
382 }
383
384 gcpService := createGCPServiceMock(t, getSecret)
385
386 service := NewHelmService(appConfig, nil, gcpService, nil, nil, nil)
387
388 helmCharts, err := service.GetHelmCharts(context.Background(), helmSecret, projectID)
389 assert.NoError(t, err)
390 assert.Len(t, helmCharts, 2)
391 actual := funk.Find(helmCharts, func(chart *model.HelmChart) bool { return chart.Name == chartName }).(*model.HelmChart)
392 expected := getHelmManifestResponse(srv.URL).Entries[chartName][0]
393 assert.Equal(t, expected.Name, actual.Name)
394 assert.Equal(t, expected.Description, actual.Description)
395 assert.Equal(t, expected.Version, actual.Version)
396 assert.Equal(t, expected.AppVersion, actual.AppVersion)
397 assert.Equal(t, expected.Icon, actual.Icon)
398 assert.Equal(t, expected.Keywords, actual.Keywords)
399 assert.Equal(t, expected.Sources, actual.Sources)
400 }
401
402 func TestHelmService_GetHelmChartVersion(t *testing.T) {
403 srv := createHelmRepoClient(t, map[string][]byte{})
404 getSecret := func(_ context.Context, name *string, owner, _type *string, getValues bool, _projectID string) ([]*model.SecretManagerResponse, error) {
405 assert.Equal(t, helmSecret, *name)
406 assert.Nil(t, owner)
407 assert.Equal(t, helmRepoSecretType, *_type)
408 assert.True(t, getValues)
409 assert.Equal(t, projectID, _projectID)
410 return []*model.SecretManagerResponse{getSecretManagerResponse(*name, _projectID, srv.URL, helmRepoSecretType)}, nil
411 }
412
413 gcpService := createGCPServiceMock(t, getSecret)
414
415 service := NewHelmService(appConfig, nil, gcpService, nil, nil, nil)
416
417 helmVersions, err := service.GetHelmChartVersion(context.Background(), chartName, helmSecret, projectID)
418 assert.NoError(t, err)
419 assert.Len(t, helmVersions.Versions, 2)
420 versions := funk.Map(helmVersions.Versions, func(s *string) string { return *s }).([]string)
421 assert.Contains(t, []string{chartVersion, "1.1"}, versions[0])
422 assert.Contains(t, []string{chartVersion, "1.1"}, versions[1])
423 }
424
425 func TestHelmService_GetDefaultConfigSchema(t *testing.T) {
426 params := getHelmConfigSchemaParams()
427 configValueURL := fmt.Sprintf("/%s-%s/values.yaml", params.ChartName, params.ChartVersion)
428 schemaURL := fmt.Sprintf("/%s-%s/values.schema.json", params.ChartName, params.ChartVersion)
429 srv := createHelmRepoClient(t, map[string][]byte{configValueURL: []byte(configValue), schemaURL: []byte(configSchema)})
430
431 getSecret := func(_ context.Context, name *string, owner, _type *string, getValues bool, _projectID string) ([]*model.SecretManagerResponse, error) {
432 assert.Equal(t, helmSecret, *name)
433 assert.Nil(t, owner)
434 assert.Equal(t, helmRepoSecretType, *_type)
435 assert.True(t, getValues)
436 assert.Equal(t, projectID, _projectID)
437 return []*model.SecretManagerResponse{getSecretManagerResponse(*name, _projectID, srv.URL, helmRepoSecretType)}, nil
438 }
439
440 gcpService := createGCPServiceMock(t, getSecret)
441
442 service := NewHelmService(appConfig, nil, gcpService, nil, nil, nil)
443
444 helmConfig, err := service.GetDefaultConfigSchema(context.Background(), params.ChartName, params.SecretName, params.ChartVersion, projectID)
445
446 assert.NoError(t, err)
447 assert.NotNil(t, helmConfig)
448 assert.NotEmpty(t, helmConfig.ConfigVals)
449 assert.Equal(t, *helmConfig.ConfigVals, `# The pod name
450 Name: my-alpine
451 `)
452 }
453
454 func TestHelmService_GetHelmRepositoryInfo(t *testing.T) {
455 params := getHelmConfigSchemaParams()
456 url := fmt.Sprintf("/%s-%s/README.md", params.ChartName, params.ChartVersion)
457 srv := createHelmRepoClient(t, map[string][]byte{url: []byte(readme)})
458
459 getSecret := func(_ context.Context, name *string, owner, _type *string, getValues bool, _projectID string) ([]*model.SecretManagerResponse, error) {
460 assert.Equal(t, helmSecret, *name)
461 assert.Nil(t, owner)
462 assert.Equal(t, helmRepoSecretType, *_type)
463 assert.True(t, getValues)
464 assert.Equal(t, projectID, _projectID)
465 return []*model.SecretManagerResponse{getSecretManagerResponse(*name, _projectID, srv.URL, helmRepoSecretType)}, nil
466 }
467
468 gcpService := createGCPServiceMock(t, getSecret)
469
470 service := NewHelmService(appConfig, nil, gcpService, nil, nil, nil)
471
472 repoInfo, err := service.GetHelmRepositoryInfo(context.Background(), params, projectID)
473
474 assert.NoError(t, err)
475 assert.NotNil(t, repoInfo)
476 assert.Nil(t, repoInfo.Metadata)
477 assert.NotEmpty(t, repoInfo.Readme)
478 }
479 func TestHelmService_GetHelmWorkloads(t *testing.T) {
480 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
481 helmEdgeID := "be8536ff-d463-4aff-8fa9-fe81fec1ddc1"
482 clusterEdgeID := testClusterEdgeID
483 bannerEdgeID := testBannerEdgeID
484
485 if err != nil {
486 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
487 }
488 defer db.Close()
489
490 params := getHelmConfigSchemaParams()
491 url := fmt.Sprintf("/%s-%s/README.md", params.ChartName, params.ChartVersion)
492 srv := createHelmRepoClient(t, map[string][]byte{url: []byte(readme)})
493
494 getSecret := func(_ context.Context, name *string, owner, _type *string, getValues bool, _projectID string) ([]*model.SecretManagerResponse, error) {
495 assert.Equal(t, "test-helm-workload", *name)
496 assert.Nil(t, owner)
497 assert.Equal(t, helmRepoSecretType, *_type)
498 assert.True(t, getValues)
499 assert.Equal(t, projectID, _projectID)
500 return []*model.SecretManagerResponse{getSecretManagerResponse(*name, _projectID, srv.URL, helmRepoSecretType)}, nil
501 }
502
503 gcpService := createGCPServiceMock(t, getSecret)
504 secret := &model.HelmSecrets{
505 SecretEdgeID: "af7351a3-22e0-4b76-aeeb-2f9d77a2b642",
506 Name: "test-secret2",
507 CreatedAt: "2022-10-19 17:33:07.347283+00",
508 UpdatedAt: "2022-10-19 17:33:07.347283+00",
509 }
510
511 helmWorkload := getTestHelmWorkloadQuery()
512
513 service := NewHelmService(appConfig, nil, gcpService, db, nil, nil)
514
515 type test struct {
516 testName string
517 clusterEdgeID string
518 bannerEdgeID string
519 expectedCount int
520 mockSQLQueries []func() *sqlmock.ExpectedQuery
521 }
522 tests := []test{
523 {testName: "GetHelmWorkloadsByClusterEdgeID", clusterEdgeID: clusterEdgeID, bannerEdgeID: bannerEdgeID, expectedCount: 1,
524 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
525 func() *sqlmock.ExpectedQuery {
526 return mock.ExpectQuery(sqlquery.GetHelmWorkloadsByClusterEdgeID).
527 WithArgs(clusterEdgeID).
528 WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id", "banner_edge_id", "helm_edge_id", "workload_name", " workload_namespace", "helm_chart", "helm_repo", "helm_chart_version", "helm_config", "installed_by", "workload_installation_type", "created_at", "updated_at", "helm_repo_secret", "project_id", "deleted"}).
529 AddRow(
530 clusterEdgeID,
531 bannerEdgeID,
532 helmWorkload.HelmEdgeID,
533 helmWorkload.Name,
534 helmWorkload.Namespace,
535 helmWorkload.HelmChart,
536 helmWorkload.HelmRepository,
537 helmWorkload.HelmChartVersion,
538 helmWorkload.HelmConfig,
539 helmWorkload.InstalledBy,
540 helmWorkload.WorkloadInstallationType,
541 helmWorkload.CreatedAt,
542 helmWorkload.UpdatedAt,
543 helmWorkload.HelmRepoSecret,
544 helmWorkload.ProjectID, false))
545 },
546 func() *sqlmock.ExpectedQuery {
547 return mock.ExpectQuery(sqlquery.GetAttachedHelmSecretByHelmEdgeID).
548 WithArgs(helmEdgeID).
549 WillReturnRows(sqlmock.NewRows([]string{"secret_edge_id", "secret_name", "created_at", "updated_at"}).
550 AddRow(secret.SecretEdgeID, secret.Name, secret.CreatedAt, secret.UpdatedAt))
551 },
552 func() *sqlmock.ExpectedQuery {
553 return mock.ExpectQuery(sqlquery.GetHelmWorkloadConfigmaps).
554 WithArgs(helmEdgeID).
555 WillReturnRows(sqlmock.NewRows([]string{"helm_workload_configmap_edge_id", "helm_edge_id", "namespace", "config_map", "created_at", "updated_at"}).
556 AddRow("helm_workload_configmap_edge_id", helmEdgeID, "namespace", "config_map", "created_at", "updated_at"))
557 },
558 func() *sqlmock.ExpectedQuery {
559 return mock.ExpectQuery(sqlquery.SelectEdgeLabelsForHelmEdgeID).
560 WithArgs(helmEdgeID).
561 WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}).
562 AddRow("label_edge_id", "test-label-key", "color", true, true, nil, true, "description", "label_type"))
563 },
564 },
565 },
566 {testName: "GetHelmWorkloadsByBannerEdgeID", clusterEdgeID: "", bannerEdgeID: bannerEdgeID, expectedCount: 1,
567 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
568 func() *sqlmock.ExpectedQuery {
569 return mock.ExpectQuery(sqlquery.GetHelmWorkloadsByBannerEdgeID).
570 WithArgs(bannerEdgeID).
571 WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id", "banner_edge_id", "helm_edge_id", "workload_name", " workload_namespace", "helm_chart", "helm_repo", "helm_chart_version", "helm_config", "installed_by", "workload_installation_type", "created_at", "updated_at", "helm_repo_secret", "project_id", "deleted"}).
572 AddRow(
573 clusterEdgeID,
574 bannerEdgeID,
575 helmWorkload.HelmEdgeID,
576 helmWorkload.Name,
577 helmWorkload.Namespace,
578 helmWorkload.HelmChart,
579 helmWorkload.HelmRepository,
580 helmWorkload.HelmChartVersion,
581 helmWorkload.HelmConfig,
582 helmWorkload.InstalledBy,
583 helmWorkload.WorkloadInstallationType,
584 helmWorkload.CreatedAt,
585 helmWorkload.UpdatedAt,
586 helmWorkload.HelmRepoSecret,
587 helmWorkload.ProjectID, false))
588 },
589 func() *sqlmock.ExpectedQuery {
590 return mock.ExpectQuery(sqlquery.GetAttachedHelmSecretByHelmEdgeID).
591 WithArgs(helmEdgeID).
592 WillReturnRows(sqlmock.NewRows([]string{"secret_edge_id", "secret_name", "created_at", "updated_at"}).
593 AddRow(secret.SecretEdgeID, secret.Name, secret.CreatedAt, secret.UpdatedAt))
594 },
595 func() *sqlmock.ExpectedQuery {
596 return mock.ExpectQuery(sqlquery.GetHelmWorkloadConfigmaps).
597 WithArgs(helmEdgeID).
598 WillReturnRows(sqlmock.NewRows([]string{"helm_workload_configmap_edge_id", "helm_edge_id", "namespace", "config_map", "created_at", "updated_at"}).
599 AddRow("helm_workload_configmap_edge_id", helmEdgeID, "namespace", "config_map", "created_at", "updated_at"))
600 },
601 func() *sqlmock.ExpectedQuery {
602 return mock.ExpectQuery(sqlquery.SelectEdgeLabelsForHelmEdgeID).
603 WithArgs(helmEdgeID).
604 WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}).
605 AddRow("label_edge_id", "test-label-key", "color", true, true, nil, true, "description", "label_type"))
606 },
607 },
608 },
609 }
610
611 for _, tc := range tests {
612 for _, mockSQLFn := range tc.mockSQLQueries {
613 mockSQLFn()
614 }
615 t.Run(tc.testName, func(t *testing.T) {
616 var response []*model.HelmWorkload
617 var err error
618 if tc.testName == "GetHelmWorkloadsByClusterEdgeID" {
619 response, err = service.GetHelmWorkloads(context.Background(), &clusterEdgeID, &bannerEdgeID, true)
620 } else {
621 var emptyClusterEdgeID *string
622 response, err = service.GetHelmWorkloads(context.Background(), emptyClusterEdgeID, &bannerEdgeID, true)
623 }
624
625 responseMap := make(map[string]bool, 0)
626 for i := 0; i < len(response); i++ {
627 if responseMap[response[i].HelmEdgeID] == true {
628 assert.Fail(t, fmt.Sprintf("duplicate helm release returned: %s", response[i].Name))
629 } else {
630 responseMap[response[i].HelmEdgeID] = true
631 }
632 }
633 assert.NoError(t, err)
634 assert.Equal(t, len(response), tc.expectedCount)
635
636 assert.Equal(t, len(response[0].Configmaps), 1)
637 assert.Equal(t, response[0].Configmaps[0].ConfigMap, "config_map")
638 })
639 }
640
641 t.Run("GetHelmWorkloadsFailureScenario", func(t *testing.T) {
642 var emptyClusterEdgeID *string
643 var emptyBannerEdgeID *string
644 _, err := service.GetHelmWorkloads(context.Background(), emptyClusterEdgeID, emptyBannerEdgeID, true)
645 assert.EqualError(t, err, "please provide clusterEdgeId or bannerEdgeId")
646 })
647 }
648
649 func TestHelmService_GetAttachedHelmSecrets(t *testing.T) {
650 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
651 helmEdgeID := "be8536ff-d463-4aff-8fa9-fe81fec1ddc1"
652 if err != nil {
653 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
654 }
655 defer db.Close()
656 secret := &model.HelmSecrets{
657 SecretEdgeID: "af7351a3-22e0-4b76-aeeb-2f9d77a2b642",
658 Name: "test-secret2",
659 CreatedAt: "2022-10-19 17:33:07.347283+00",
660 UpdatedAt: "2022-10-19 17:33:07.347283+00",
661 }
662
663 mock.ExpectQuery(sqlquery.GetAttachedHelmSecretByHelmEdgeID).
664 WithArgs("be8536ff-d463-4aff-8fa9-fe81fec1ddc1").
665 WillReturnRows(sqlmock.NewRows([]string{"secret_edge_id", "secret_name", "created_at", "updated_at"}).
666 AddRow(secret.SecretEdgeID, secret.Name, secret.CreatedAt, secret.UpdatedAt))
667 mock.ExpectQuery(sqlquery.GetHelmWorkloadConfigmaps).
668 WithArgs(helmEdgeID).
669 WillReturnRows(sqlmock.NewRows([]string{"helm_workload_configmap_edge_id", "helm_edge_id", "namespace", "config_map", "created_at", "updated_at"}).
670 AddRow("helm_workload_configmap_edge_id", helmEdgeID, "namespace", "config_map", "created_at", "updated_at"))
671 mock.ExpectQuery(sqlquery.SelectEdgeLabelsForHelmEdgeID).
672 WithArgs(helmEdgeID).
673 WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}).
674 AddRow("label_edge_id", "test-label-key", "color", true, true, nil, true, "description", "label_type"))
675
676 service := NewHelmService(appConfig, nil, nil, db, nil, nil)
677 response, err := service.GetAttachedHelmSecrets(context.Background(), &helmEdgeID)
678 assert.NoError(t, err)
679 assert.Equal(t, len(response), 1)
680 }
681
682 func TestHelmService_GetHelmWorkloadsData(t *testing.T) {
683 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
684 clusterEdgeID := testClusterEdgeID
685 bannerEdgeID := testBannerEdgeID
686 if err != nil {
687 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
688 }
689 defer db.Close()
690
691 helmWorkload := getTestHelmWorkloadQuery()
692
693 mock.ExpectQuery(sqlquery.GetHelmWorkloadsByClusterEdgeID).
694 WithArgs(clusterEdgeID).
695 WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id", "banner_edge_id", "helm_edge_id", "workload_name", " workload_namespace", "helm_chart", "helm_repo", "helm_chart_version", "helm_config", "installed_by", "workload_installation_type", "created_at", "updated_at", "helm_repo_secret", "project_id", "deleted"}).
696 AddRow(
697 clusterEdgeID,
698 bannerEdgeID,
699 helmWorkload.HelmEdgeID,
700 helmWorkload.Name,
701 helmWorkload.Namespace,
702 helmWorkload.HelmChart,
703 helmWorkload.HelmRepository,
704 helmWorkload.HelmChartVersion,
705 helmWorkload.HelmConfig,
706 helmWorkload.InstalledBy,
707 helmWorkload.WorkloadInstallationType,
708 helmWorkload.CreatedAt,
709 helmWorkload.UpdatedAt,
710 helmWorkload.HelmRepoSecret,
711 helmWorkload.ProjectID, false))
712
713 service := NewHelmService(appConfig, nil, nil, db, nil, nil)
714 response, err := service.GetHelmWorkloadsData(context.Background(), &clusterEdgeID, &bannerEdgeID, true)
715 assert.NoError(t, err)
716 assert.Equal(t, len(response), 1)
717 }
718 func TestHelmService_checkNamespaceToDelete(t *testing.T) {
719 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
720 clusterEdgeID := testClusterEdgeID
721 bannerEdgeID := testBannerEdgeID
722
723 if err != nil {
724 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
725 }
726 defer db.Close()
727
728 var helmWorkload = getTestHelmWorkloadQuery()
729
730 service := NewHelmService(appConfig, nil, nil, db, nil, nil)
731
732 type test struct {
733 testName string
734 clusterEdgeID string
735 workloadName string
736 want bool
737 mockSQLQuery func() *sqlmock.ExpectedQuery
738 }
739
740 tests := []test{
741
742 {testName: "deleteNamespace", clusterEdgeID: clusterEdgeID, workloadName: helmWorkload.Name, want: true,
743 mockSQLQuery: func() *sqlmock.ExpectedQuery {
744 return mock.ExpectQuery(sqlquery.GetHelmWorkloadsByClusterEdgeID).
745 WithArgs(clusterEdgeID).
746 WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id", "banner_edge_id", "helm_edge_id", "workload_name", " workload_namespace", "helm_chart", "helm_repo", "helm_chart_version", "helm_config", "installed_by", "workload_installation_type", "created_at", "updated_at", "helm_repo_secret", "project_id", "deleted"}).
747 AddRow(
748 clusterEdgeID,
749 bannerEdgeID,
750 helmWorkload.HelmEdgeID,
751 helmWorkload.Name,
752 helmWorkload.Namespace,
753 helmWorkload.HelmChart,
754 helmWorkload.HelmRepository,
755 helmWorkload.HelmChartVersion,
756 helmWorkload.HelmConfig,
757 helmWorkload.InstalledBy,
758 helmWorkload.WorkloadInstallationType,
759 helmWorkload.CreatedAt,
760 helmWorkload.UpdatedAt,
761 helmWorkload.HelmRepoSecret,
762 helmWorkload.ProjectID, false))
763 },
764 },
765
766 {testName: "notDeleteNamespace", clusterEdgeID: clusterEdgeID, workloadName: helmWorkload.Name, want: false,
767 mockSQLQuery: func() *sqlmock.ExpectedQuery {
768 return mock.ExpectQuery(sqlquery.GetHelmWorkloadsByClusterEdgeID).
769 WithArgs(clusterEdgeID).
770 WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id", "banner_edge_id", "helm_edge_id", "workload_name", " workload_namespace", "helm_chart", "helm_repo", "helm_chart_version", "helm_config", "installed_by", "workload_installation_type", "created_at", "updated_at", "helm_repo_secret", "project_id", "deleted"}).
771 AddRow(clusterEdgeID, bannerEdgeID, helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, helmWorkload.HelmChart, helmWorkload.HelmRepository, helmWorkload.HelmChartVersion, helmWorkload.HelmConfig, helmWorkload.InstalledBy, helmWorkload.WorkloadInstallationType, helmWorkload.CreatedAt, helmWorkload.UpdatedAt, helmWorkload.HelmRepoSecret, helmWorkload.ProjectID, false).
772 AddRow(clusterEdgeID, bannerEdgeID, helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, helmWorkload.HelmChart, helmWorkload.HelmRepository, helmWorkload.HelmChartVersion, helmWorkload.HelmConfig, helmWorkload.InstalledBy, helmWorkload.WorkloadInstallationType, helmWorkload.CreatedAt, helmWorkload.UpdatedAt, helmWorkload.HelmRepoSecret, helmWorkload.ProjectID, false))
773 },
774 },
775 }
776
777 for i, tc := range tests {
778 tc.mockSQLQuery()
779 t.Run(tc.testName, func(t *testing.T) {
780 workload, isDeleteNamespace, err := service.checkNamespaceToDelete(context.Background(), &tests[i].clusterEdgeID, tc.workloadName)
781 assert.Equal(t, tc.workloadName, workload.Name)
782 assert.Equal(t, tc.want, isDeleteNamespace)
783 assert.NoError(t, err)
784 })
785 }
786 }
787 func TestHelmService_addSecretsToDeleteToChariotMessage(t *testing.T) {
788 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
789 clusterEdgeID := testClusterEdgeID
790 if err != nil {
791 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
792 }
793 defer db.Close()
794 defaultValue := ""
795
796 helmWorkload := &model.HelmWorkload{
797 HelmEdgeID: "be8536ff-d463-4aff-8fa9-fe81fec1ddc1",
798 Name: "test-helm-workload",
799 Namespace: "nginx",
800 HelmChart: "nginx",
801 HelmRepository: "test-repo",
802 HelmChartVersion: "2.3.1",
803 ConfigValues: &defaultValue,
804 InstalledBy: &defaultValue,
805 HelmRepoSecret: "test-helm-workload",
806 }
807
808 service := NewHelmService(appConfig, nil, nil, db, nil, nil)
809
810 type test struct {
811 testName string
812 clusterEdgeID string
813 workload *model.HelmWorkload
814 messageLength int
815 want []string
816 mockSQLQuery func() *sqlmock.ExpectedQuery
817 }
818
819 tests := []test{
820
821 {testName: "oneSecret", clusterEdgeID: clusterEdgeID, workload: helmWorkload, messageLength: 2,
822 want: []string{"eyJraW5kIjoiSGVsbVJlbGVhc2UiLCJhcGlWZXJzaW9uIjoiaGVsbS50b29sa2l0LmZsdXhjZC5pby92MiIsIm1ldGFkYXRhIjp7Im5hbWUiOiJ0ZXN0LWhlbG0td29ya2xvYWQiLCJuYW1lc3BhY2UiOiJmbHV4LXN5c3RlbSIsImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJsYWJlbHMiOnsicGFyZW50LWNsdXN0ZXIiOiJyZWdpb24taW5mcmEiLCJzZWNyZXQtbWFtYWdlci5lZGdlLm5jci5jb20iOiIifX0sInNwZWMiOnsiY2hhcnQiOnsic3BlYyI6eyJjaGFydCI6IiIsInNvdXJjZVJlZiI6eyJraW5kIjoiSGVsbVJlcG9zaXRvcnkiLCJuYW1lIjoiIn19fSwiaW50ZXJ2YWwiOiIybTBzIiwicmVsZWFzZU5hbWUiOiJ0ZXN0LWhlbG0td29ya2xvYWQiLCJ0aW1lb3V0IjoiMTVtMHMiLCJkcmlmdERldGVjdGlvbiI6eyJtb2RlIjoiZW5hYmxlZCJ9LCJpbnN0YWxsIjp7InJlbWVkaWF0aW9uIjp7InJldHJpZXMiOjN9fSwidXBncmFkZSI6eyJyZW1lZGlhdGlvbiI6eyJyZXRyaWVzIjozfX0sInZhbHVlcyI6bnVsbCwicG9zdFJlbmRlcmVycyI6W3sia3VzdG9taXplIjp7InBhdGNoZXMiOlt7InBhdGNoIjoiLSBvcDogYWRkXG4gIHBhdGg6IC9tZXRhZGF0YS9hbm5vdGF0aW9ucy9oZWxtLnRvb2xraXQuZmx1eGNkLmlvfjFkcmlmdERldGVjdGlvblxuICB2YWx1ZTogZGlzYWJsZWQiLCJ0YXJnZXQiOnsidmVyc2lvbiI6InYxIiwia2luZCI6IklFTlBhdGNoIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL21ldGFkYXRhL2Fubm90YXRpb25zL2hlbG0udG9vbGtpdC5mbHV4Y2QuaW9+MWRyaWZ0RGV0ZWN0aW9uXG4gIHZhbHVlOiBkaXNhYmxlZCIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiU3RhdGVmdWxTZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvbWV0YWRhdGEvYW5ub3RhdGlvbnMvaGVsbS50b29sa2l0LmZsdXhjZC5pb34xZHJpZnREZXRlY3Rpb25cbiAgdmFsdWU6IGRpc2FibGVkIiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJEYWVtb25TZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJEZXBsb3ltZW50In19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZToge1wibm9kZUFmZmluaXR5XCI6IHtcInByZWZlcnJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uXCI6W3tcIndlaWdodFwiOjEsXCJwcmVmZXJlbmNlXCI6e1wibWF0Y2hFeHByZXNzaW9uc1wiOlt7XCJrZXlcIjpcIm5vZGUubmNyLmNvbS9jbGFzc1wiLFwib3BlcmF0b3JcIjpcIkluXCIsXCJ2YWx1ZXNcIjpbXCJzZXJ2ZXJcIl19XX19XX0gfSIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiU3RhdGVmdWxTZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJSZXBsaWNhU2V0In19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZToge1wibm9kZUFmZmluaXR5XCI6IHtcInByZWZlcnJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uXCI6W3tcIndlaWdodFwiOjEsXCJwcmVmZXJlbmNlXCI6e1wibWF0Y2hFeHByZXNzaW9uc1wiOlt7XCJrZXlcIjpcIm5vZGUubmNyLmNvbS9jbGFzc1wiLFwib3BlcmF0b3JcIjpcIkluXCIsXCJ2YWx1ZXNcIjpbXCJzZXJ2ZXJcIl19XX19XX0gfSIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiSm9iIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvam9iVGVtcGxhdGUvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJDcm9uSm9iIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZTpcbiAgICBub2RlQWZmaW5pdHk6XG4gICAgICBwcmVmZXJyZWREdXJpbmdTY2hlZHVsaW5nSWdub3JlZER1cmluZ0V4ZWN1dGlvbjpcbiAgICAgIC0gcHJlZmVyZW5jZTpcbiAgICAgICAgICBtYXRjaEV4cHJlc3Npb25zOlxuICAgICAgICAgIC0ga2V5OiBub2RlLm5jci5jb20vY2xhc3NcbiAgICAgICAgICAgIG9wZXJhdG9yOiBJblxuICAgICAgICAgICAgdmFsdWVzOlxuICAgICAgICAgICAgLSBzZXJ2ZXJcbiAgICAgICAgd2VpZ2h0OiAxXG4tIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvbWV0YWRhdGEvYW5ub3RhdGlvbnMvZWRnZS5uY3IuY29tfjFoZWxtLWVkZ2UtaWRcbiAgdmFsdWU6IFwiXCJcbiIsInRhcmdldCI6eyJncm91cCI6Imt1YmV2aXJ0LmlvIiwidmVyc2lvbiI6InYxIiwia2luZCI6IlZpcnR1YWxNYWNoaW5lIn19XX19XX0sInN0YXR1cyI6e319", "eyJraW5kIjoiRXh0ZXJuYWxTZWNyZXQiLCJhcGlWZXJzaW9uIjoiZXh0ZXJuYWwtc2VjcmV0cy5pby92MWJldGExIiwibWV0YWRhdGEiOnsibmFtZSI6IkV4dGVybmFsU2VjcmV0IiwibmFtZXNwYWNlIjoibmdpbngiLCJjcmVhdGlvblRpbWVzdGFtcCI6bnVsbH0sInNwZWMiOnsic2VjcmV0U3RvcmVSZWYiOnsibmFtZSI6IiJ9LCJ0YXJnZXQiOnt9fSwic3RhdHVzIjp7InJlZnJlc2hUaW1lIjpudWxsLCJiaW5kaW5nIjp7fX19"},
823 mockSQLQuery: func() *sqlmock.ExpectedQuery {
824 return mock.ExpectQuery(sqlquery.GetNamespacesAndSecretsNamesByClusterEdgeID).
825 WithArgs(clusterEdgeID, helmWorkload.Namespace).
826 WillReturnRows(sqlmock.NewRows([]string{"helm_workloads.helm_edge_id", "helm_workloads.workload_name", "helm_workloads.workload_namespace", "helm_secrets.secret_name"}).
827 AddRow(helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, externalSecret))
828 },
829 },
830
831 {testName: "twoSecrets", clusterEdgeID: clusterEdgeID, workload: helmWorkload, messageLength: 3,
832 want: []string{"eyJraW5kIjoiSGVsbVJlbGVhc2UiLCJhcGlWZXJzaW9uIjoiaGVsbS50b29sa2l0LmZsdXhjZC5pby92MiIsIm1ldGFkYXRhIjp7Im5hbWUiOiJ0ZXN0LWhlbG0td29ya2xvYWQiLCJuYW1lc3BhY2UiOiJmbHV4LXN5c3RlbSIsImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJsYWJlbHMiOnsicGFyZW50LWNsdXN0ZXIiOiJyZWdpb24taW5mcmEiLCJzZWNyZXQtbWFtYWdlci5lZGdlLm5jci5jb20iOiIifX0sInNwZWMiOnsiY2hhcnQiOnsic3BlYyI6eyJjaGFydCI6IiIsInNvdXJjZVJlZiI6eyJraW5kIjoiSGVsbVJlcG9zaXRvcnkiLCJuYW1lIjoiIn19fSwiaW50ZXJ2YWwiOiIybTBzIiwicmVsZWFzZU5hbWUiOiJ0ZXN0LWhlbG0td29ya2xvYWQiLCJ0aW1lb3V0IjoiMTVtMHMiLCJkcmlmdERldGVjdGlvbiI6eyJtb2RlIjoiZW5hYmxlZCJ9LCJpbnN0YWxsIjp7InJlbWVkaWF0aW9uIjp7InJldHJpZXMiOjN9fSwidXBncmFkZSI6eyJyZW1lZGlhdGlvbiI6eyJyZXRyaWVzIjozfX0sInZhbHVlcyI6bnVsbCwicG9zdFJlbmRlcmVycyI6W3sia3VzdG9taXplIjp7InBhdGNoZXMiOlt7InBhdGNoIjoiLSBvcDogYWRkXG4gIHBhdGg6IC9tZXRhZGF0YS9hbm5vdGF0aW9ucy9oZWxtLnRvb2xraXQuZmx1eGNkLmlvfjFkcmlmdERldGVjdGlvblxuICB2YWx1ZTogZGlzYWJsZWQiLCJ0YXJnZXQiOnsidmVyc2lvbiI6InYxIiwia2luZCI6IklFTlBhdGNoIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL21ldGFkYXRhL2Fubm90YXRpb25zL2hlbG0udG9vbGtpdC5mbHV4Y2QuaW9+MWRyaWZ0RGV0ZWN0aW9uXG4gIHZhbHVlOiBkaXNhYmxlZCIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiU3RhdGVmdWxTZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvbWV0YWRhdGEvYW5ub3RhdGlvbnMvaGVsbS50b29sa2l0LmZsdXhjZC5pb34xZHJpZnREZXRlY3Rpb25cbiAgdmFsdWU6IGRpc2FibGVkIiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJEYWVtb25TZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJEZXBsb3ltZW50In19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZToge1wibm9kZUFmZmluaXR5XCI6IHtcInByZWZlcnJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uXCI6W3tcIndlaWdodFwiOjEsXCJwcmVmZXJlbmNlXCI6e1wibWF0Y2hFeHByZXNzaW9uc1wiOlt7XCJrZXlcIjpcIm5vZGUubmNyLmNvbS9jbGFzc1wiLFwib3BlcmF0b3JcIjpcIkluXCIsXCJ2YWx1ZXNcIjpbXCJzZXJ2ZXJcIl19XX19XX0gfSIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiU3RhdGVmdWxTZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJSZXBsaWNhU2V0In19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZToge1wibm9kZUFmZmluaXR5XCI6IHtcInByZWZlcnJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uXCI6W3tcIndlaWdodFwiOjEsXCJwcmVmZXJlbmNlXCI6e1wibWF0Y2hFeHByZXNzaW9uc1wiOlt7XCJrZXlcIjpcIm5vZGUubmNyLmNvbS9jbGFzc1wiLFwib3BlcmF0b3JcIjpcIkluXCIsXCJ2YWx1ZXNcIjpbXCJzZXJ2ZXJcIl19XX19XX0gfSIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiSm9iIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvam9iVGVtcGxhdGUvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJDcm9uSm9iIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZTpcbiAgICBub2RlQWZmaW5pdHk6XG4gICAgICBwcmVmZXJyZWREdXJpbmdTY2hlZHVsaW5nSWdub3JlZER1cmluZ0V4ZWN1dGlvbjpcbiAgICAgIC0gcHJlZmVyZW5jZTpcbiAgICAgICAgICBtYXRjaEV4cHJlc3Npb25zOlxuICAgICAgICAgIC0ga2V5OiBub2RlLm5jci5jb20vY2xhc3NcbiAgICAgICAgICAgIG9wZXJhdG9yOiBJblxuICAgICAgICAgICAgdmFsdWVzOlxuICAgICAgICAgICAgLSBzZXJ2ZXJcbiAgICAgICAgd2VpZ2h0OiAxXG4tIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvbWV0YWRhdGEvYW5ub3RhdGlvbnMvZWRnZS5uY3IuY29tfjFoZWxtLWVkZ2UtaWRcbiAgdmFsdWU6IFwiXCJcbiIsInRhcmdldCI6eyJncm91cCI6Imt1YmV2aXJ0LmlvIiwidmVyc2lvbiI6InYxIiwia2luZCI6IlZpcnR1YWxNYWNoaW5lIn19XX19XX0sInN0YXR1cyI6e319", "eyJraW5kIjoiRXh0ZXJuYWxTZWNyZXQiLCJhcGlWZXJzaW9uIjoiZXh0ZXJuYWwtc2VjcmV0cy5pby92MWJldGExIiwibWV0YWRhdGEiOnsibmFtZSI6IkV4dGVybmFsU2VjcmV0IiwibmFtZXNwYWNlIjoibmdpbngiLCJjcmVhdGlvblRpbWVzdGFtcCI6bnVsbH0sInNwZWMiOnsic2VjcmV0U3RvcmVSZWYiOnsibmFtZSI6IiJ9LCJ0YXJnZXQiOnt9fSwic3RhdHVzIjp7InJlZnJlc2hUaW1lIjpudWxsLCJiaW5kaW5nIjp7fX19", "eyJraW5kIjoiRXh0ZXJuYWxTZWNyZXQiLCJhcGlWZXJzaW9uIjoiZXh0ZXJuYWwtc2VjcmV0cy5pby92MWJldGExIiwibWV0YWRhdGEiOnsibmFtZSI6IkV4dGVybmFsU2VjcmV0MiIsIm5hbWVzcGFjZSI6Im5naW54IiwiY3JlYXRpb25UaW1lc3RhbXAiOm51bGx9LCJzcGVjIjp7InNlY3JldFN0b3JlUmVmIjp7Im5hbWUiOiIifSwidGFyZ2V0Ijp7fX0sInN0YXR1cyI6eyJyZWZyZXNoVGltZSI6bnVsbCwiYmluZGluZyI6e319fQ=="},
833 mockSQLQuery: func() *sqlmock.ExpectedQuery {
834 return mock.ExpectQuery(sqlquery.GetNamespacesAndSecretsNamesByClusterEdgeID).
835 WithArgs(clusterEdgeID, helmWorkload.Namespace).
836 WillReturnRows(sqlmock.NewRows([]string{"helm_workloads.helm_edge_id", "helm_workloads.workload_name", "helm_workloads.workload_namespace", "helm_secrets.secret_name"}).
837 AddRow(helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, externalSecret).
838 AddRow(helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, "ExternalSecret2"))
839 },
840 },
841
842 {testName: "twoSecretsBothUsed1", clusterEdgeID: clusterEdgeID, workload: helmWorkload, messageLength: 2,
843 want: []string{"eyJraW5kIjoiSGVsbVJlbGVhc2UiLCJhcGlWZXJzaW9uIjoiaGVsbS50b29sa2l0LmZsdXhjZC5pby92MiIsIm1ldGFkYXRhIjp7Im5hbWUiOiJ0ZXN0LWhlbG0td29ya2xvYWQiLCJuYW1lc3BhY2UiOiJmbHV4LXN5c3RlbSIsImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJsYWJlbHMiOnsicGFyZW50LWNsdXN0ZXIiOiJyZWdpb24taW5mcmEiLCJzZWNyZXQtbWFtYWdlci5lZGdlLm5jci5jb20iOiIifX0sInNwZWMiOnsiY2hhcnQiOnsic3BlYyI6eyJjaGFydCI6IiIsInNvdXJjZVJlZiI6eyJraW5kIjoiSGVsbVJlcG9zaXRvcnkiLCJuYW1lIjoiIn19fSwiaW50ZXJ2YWwiOiIybTBzIiwicmVsZWFzZU5hbWUiOiJ0ZXN0LWhlbG0td29ya2xvYWQiLCJ0aW1lb3V0IjoiMTVtMHMiLCJkcmlmdERldGVjdGlvbiI6eyJtb2RlIjoiZW5hYmxlZCJ9LCJpbnN0YWxsIjp7InJlbWVkaWF0aW9uIjp7InJldHJpZXMiOjN9fSwidXBncmFkZSI6eyJyZW1lZGlhdGlvbiI6eyJyZXRyaWVzIjozfX0sInZhbHVlcyI6bnVsbCwicG9zdFJlbmRlcmVycyI6W3sia3VzdG9taXplIjp7InBhdGNoZXMiOlt7InBhdGNoIjoiLSBvcDogYWRkXG4gIHBhdGg6IC9tZXRhZGF0YS9hbm5vdGF0aW9ucy9oZWxtLnRvb2xraXQuZmx1eGNkLmlvfjFkcmlmdERldGVjdGlvblxuICB2YWx1ZTogZGlzYWJsZWQiLCJ0YXJnZXQiOnsidmVyc2lvbiI6InYxIiwia2luZCI6IklFTlBhdGNoIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL21ldGFkYXRhL2Fubm90YXRpb25zL2hlbG0udG9vbGtpdC5mbHV4Y2QuaW9+MWRyaWZ0RGV0ZWN0aW9uXG4gIHZhbHVlOiBkaXNhYmxlZCIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiU3RhdGVmdWxTZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvbWV0YWRhdGEvYW5ub3RhdGlvbnMvaGVsbS50b29sa2l0LmZsdXhjZC5pb34xZHJpZnREZXRlY3Rpb25cbiAgdmFsdWU6IGRpc2FibGVkIiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJEYWVtb25TZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJEZXBsb3ltZW50In19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZToge1wibm9kZUFmZmluaXR5XCI6IHtcInByZWZlcnJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uXCI6W3tcIndlaWdodFwiOjEsXCJwcmVmZXJlbmNlXCI6e1wibWF0Y2hFeHByZXNzaW9uc1wiOlt7XCJrZXlcIjpcIm5vZGUubmNyLmNvbS9jbGFzc1wiLFwib3BlcmF0b3JcIjpcIkluXCIsXCJ2YWx1ZXNcIjpbXCJzZXJ2ZXJcIl19XX19XX0gfSIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiU3RhdGVmdWxTZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJSZXBsaWNhU2V0In19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZToge1wibm9kZUFmZmluaXR5XCI6IHtcInByZWZlcnJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uXCI6W3tcIndlaWdodFwiOjEsXCJwcmVmZXJlbmNlXCI6e1wibWF0Y2hFeHByZXNzaW9uc1wiOlt7XCJrZXlcIjpcIm5vZGUubmNyLmNvbS9jbGFzc1wiLFwib3BlcmF0b3JcIjpcIkluXCIsXCJ2YWx1ZXNcIjpbXCJzZXJ2ZXJcIl19XX19XX0gfSIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiSm9iIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvam9iVGVtcGxhdGUvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJDcm9uSm9iIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZTpcbiAgICBub2RlQWZmaW5pdHk6XG4gICAgICBwcmVmZXJyZWREdXJpbmdTY2hlZHVsaW5nSWdub3JlZER1cmluZ0V4ZWN1dGlvbjpcbiAgICAgIC0gcHJlZmVyZW5jZTpcbiAgICAgICAgICBtYXRjaEV4cHJlc3Npb25zOlxuICAgICAgICAgIC0ga2V5OiBub2RlLm5jci5jb20vY2xhc3NcbiAgICAgICAgICAgIG9wZXJhdG9yOiBJblxuICAgICAgICAgICAgdmFsdWVzOlxuICAgICAgICAgICAgLSBzZXJ2ZXJcbiAgICAgICAgd2VpZ2h0OiAxXG4tIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvbWV0YWRhdGEvYW5ub3RhdGlvbnMvZWRnZS5uY3IuY29tfjFoZWxtLWVkZ2UtaWRcbiAgdmFsdWU6IFwiXCJcbiIsInRhcmdldCI6eyJncm91cCI6Imt1YmV2aXJ0LmlvIiwidmVyc2lvbiI6InYxIiwia2luZCI6IlZpcnR1YWxNYWNoaW5lIn19XX19XX0sInN0YXR1cyI6e319", "eyJraW5kIjoiRXh0ZXJuYWxTZWNyZXQiLCJhcGlWZXJzaW9uIjoiZXh0ZXJuYWwtc2VjcmV0cy5pby92MWJldGExIiwibWV0YWRhdGEiOnsibmFtZSI6IkV4dGVybmFsU2VjcmV0MiIsIm5hbWVzcGFjZSI6Im5naW54IiwiY3JlYXRpb25UaW1lc3RhbXAiOm51bGx9LCJzcGVjIjp7InNlY3JldFN0b3JlUmVmIjp7Im5hbWUiOiIifSwidGFyZ2V0Ijp7fX0sInN0YXR1cyI6eyJyZWZyZXNoVGltZSI6bnVsbCwiYmluZGluZyI6e319fQ=="},
844 mockSQLQuery: func() *sqlmock.ExpectedQuery {
845 return mock.ExpectQuery(sqlquery.GetNamespacesAndSecretsNamesByClusterEdgeID).
846 WithArgs(clusterEdgeID, helmWorkload.Namespace).
847 WillReturnRows(sqlmock.NewRows([]string{"helm_workloads.helm_edge_id", "helm_workloads.workload_name", "helm_workloads.workload_namespace", "helm_secrets.secret_name"}).
848 AddRow(helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, externalSecret).
849 AddRow(helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, "ExternalSecret2").
850 AddRow("be8536ff-d463-4aff-8fa9-fe81fec1ddc2", "workload2", helmWorkload.Namespace, externalSecret))
851 },
852 },
853
854 {testName: "twoSecretsBothUsed2", clusterEdgeID: clusterEdgeID, workload: helmWorkload, messageLength: 1,
855 want: []string{"eyJraW5kIjoiSGVsbVJlbGVhc2UiLCJhcGlWZXJzaW9uIjoiaGVsbS50b29sa2l0LmZsdXhjZC5pby92MiIsIm1ldGFkYXRhIjp7Im5hbWUiOiJ0ZXN0LWhlbG0td29ya2xvYWQiLCJuYW1lc3BhY2UiOiJmbHV4LXN5c3RlbSIsImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJsYWJlbHMiOnsicGFyZW50LWNsdXN0ZXIiOiJyZWdpb24taW5mcmEiLCJzZWNyZXQtbWFtYWdlci5lZGdlLm5jci5jb20iOiIifX0sInNwZWMiOnsiY2hhcnQiOnsic3BlYyI6eyJjaGFydCI6IiIsInNvdXJjZVJlZiI6eyJraW5kIjoiSGVsbVJlcG9zaXRvcnkiLCJuYW1lIjoiIn19fSwiaW50ZXJ2YWwiOiIybTBzIiwicmVsZWFzZU5hbWUiOiJ0ZXN0LWhlbG0td29ya2xvYWQiLCJ0aW1lb3V0IjoiMTVtMHMiLCJkcmlmdERldGVjdGlvbiI6eyJtb2RlIjoiZW5hYmxlZCJ9LCJpbnN0YWxsIjp7InJlbWVkaWF0aW9uIjp7InJldHJpZXMiOjN9fSwidXBncmFkZSI6eyJyZW1lZGlhdGlvbiI6eyJyZXRyaWVzIjozfX0sInZhbHVlcyI6bnVsbCwicG9zdFJlbmRlcmVycyI6W3sia3VzdG9taXplIjp7InBhdGNoZXMiOlt7InBhdGNoIjoiLSBvcDogYWRkXG4gIHBhdGg6IC9tZXRhZGF0YS9hbm5vdGF0aW9ucy9oZWxtLnRvb2xraXQuZmx1eGNkLmlvfjFkcmlmdERldGVjdGlvblxuICB2YWx1ZTogZGlzYWJsZWQiLCJ0YXJnZXQiOnsidmVyc2lvbiI6InYxIiwia2luZCI6IklFTlBhdGNoIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL21ldGFkYXRhL2Fubm90YXRpb25zL2hlbG0udG9vbGtpdC5mbHV4Y2QuaW9+MWRyaWZ0RGV0ZWN0aW9uXG4gIHZhbHVlOiBkaXNhYmxlZCIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiU3RhdGVmdWxTZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvbWV0YWRhdGEvYW5ub3RhdGlvbnMvaGVsbS50b29sa2l0LmZsdXhjZC5pb34xZHJpZnREZXRlY3Rpb25cbiAgdmFsdWU6IGRpc2FibGVkIiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJEYWVtb25TZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJEZXBsb3ltZW50In19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZToge1wibm9kZUFmZmluaXR5XCI6IHtcInByZWZlcnJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uXCI6W3tcIndlaWdodFwiOjEsXCJwcmVmZXJlbmNlXCI6e1wibWF0Y2hFeHByZXNzaW9uc1wiOlt7XCJrZXlcIjpcIm5vZGUubmNyLmNvbS9jbGFzc1wiLFwib3BlcmF0b3JcIjpcIkluXCIsXCJ2YWx1ZXNcIjpbXCJzZXJ2ZXJcIl19XX19XX0gfSIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiU3RhdGVmdWxTZXQifX0seyJwYXRjaCI6Ii0gb3A6IGFkZFxuICBwYXRoOiAvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJSZXBsaWNhU2V0In19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZToge1wibm9kZUFmZmluaXR5XCI6IHtcInByZWZlcnJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uXCI6W3tcIndlaWdodFwiOjEsXCJwcmVmZXJlbmNlXCI6e1wibWF0Y2hFeHByZXNzaW9uc1wiOlt7XCJrZXlcIjpcIm5vZGUubmNyLmNvbS9jbGFzc1wiLFwib3BlcmF0b3JcIjpcIkluXCIsXCJ2YWx1ZXNcIjpbXCJzZXJ2ZXJcIl19XX19XX0gfSIsInRhcmdldCI6eyJ2ZXJzaW9uIjoidjEiLCJraW5kIjoiSm9iIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvam9iVGVtcGxhdGUvc3BlYy90ZW1wbGF0ZS9zcGVjL2FmZmluaXR5XG4gIHZhbHVlOiB7XCJub2RlQWZmaW5pdHlcIjoge1wicHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb25cIjpbe1wid2VpZ2h0XCI6MSxcInByZWZlcmVuY2VcIjp7XCJtYXRjaEV4cHJlc3Npb25zXCI6W3tcImtleVwiOlwibm9kZS5uY3IuY29tL2NsYXNzXCIsXCJvcGVyYXRvclwiOlwiSW5cIixcInZhbHVlc1wiOltcInNlcnZlclwiXX1dfX1dfSB9IiwidGFyZ2V0Ijp7InZlcnNpb24iOiJ2MSIsImtpbmQiOiJDcm9uSm9iIn19LHsicGF0Y2giOiItIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvc3BlYy9hZmZpbml0eVxuICB2YWx1ZTpcbiAgICBub2RlQWZmaW5pdHk6XG4gICAgICBwcmVmZXJyZWREdXJpbmdTY2hlZHVsaW5nSWdub3JlZER1cmluZ0V4ZWN1dGlvbjpcbiAgICAgIC0gcHJlZmVyZW5jZTpcbiAgICAgICAgICBtYXRjaEV4cHJlc3Npb25zOlxuICAgICAgICAgIC0ga2V5OiBub2RlLm5jci5jb20vY2xhc3NcbiAgICAgICAgICAgIG9wZXJhdG9yOiBJblxuICAgICAgICAgICAgdmFsdWVzOlxuICAgICAgICAgICAgLSBzZXJ2ZXJcbiAgICAgICAgd2VpZ2h0OiAxXG4tIG9wOiBhZGRcbiAgcGF0aDogL3NwZWMvdGVtcGxhdGUvbWV0YWRhdGEvYW5ub3RhdGlvbnMvZWRnZS5uY3IuY29tfjFoZWxtLWVkZ2UtaWRcbiAgdmFsdWU6IFwiXCJcbiIsInRhcmdldCI6eyJncm91cCI6Imt1YmV2aXJ0LmlvIiwidmVyc2lvbiI6InYxIiwia2luZCI6IlZpcnR1YWxNYWNoaW5lIn19XX19XX0sInN0YXR1cyI6e319"},
856 mockSQLQuery: func() *sqlmock.ExpectedQuery {
857 return mock.ExpectQuery(sqlquery.GetNamespacesAndSecretsNamesByClusterEdgeID).
858 WithArgs(clusterEdgeID, helmWorkload.Namespace).
859 WillReturnRows(sqlmock.NewRows([]string{"helm_workloads.helm_edge_id", "helm_workloads.workload_name", "helm_workloads.workload_namespace", "helm_secrets.secret_name"}).
860 AddRow(helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, externalSecret).
861 AddRow(helmWorkload.HelmEdgeID, helmWorkload.Name, helmWorkload.Namespace, "ExternalSecret2").
862 AddRow("be8536ff-d463-4aff-8fa9-fe81fec1ddc2", "workload2", helmWorkload.Namespace, externalSecret).
863 AddRow("be8536ff-d463-4aff-8fa9-fe81fec1ddc2", "workload2", helmWorkload.Namespace, "ExternalSecret2"))
864 },
865 },
866 }
867
868 for _, tc := range tests {
869 tc.mockSQLQuery()
870 t.Run(tc.testName, func(t *testing.T) {
871 var message []string
872 installationType := model.WorkloadInstallationTypeServerPreferred
873 helmRelease, err := mapper.ToCreateHelmReleaseBase64String(helmWorkload.Name, "", "", "", "", "", []byte{}, installationType, nil, "latest", "")
874 assert.NoError(t, err)
875 message = append(message, helmRelease)
876 message, err = service.addSecretsToDeleteToChariotMessage(context.Background(), helmWorkload, clusterEdgeID, message)
877 assert.Equal(t, tc.want, message)
878 assert.Equal(t, len(message), tc.messageLength)
879 assert.NoError(t, err)
880 })
881 }
882 }
883
884
885
886 func TestParseRepoURLYaml(t *testing.T) {
887 jsn := getHelmManifestResponse("ip")
888 response, _ := yaml.Marshal(&jsn)
889 _, err := parseRepoURLYaml(response)
890 if err != nil {
891 t.Fatalf(`Got error %v`, err)
892 }
893 }
894
895 func TestGetWorkloadsByName(t *testing.T) {
896 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
897 if err != nil {
898 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
899 }
900 defer db.Close()
901 service := NewHelmService(nil, nil, nil, db, nil, nil)
902
903 var (
904 helmEdgeID = helmEdgeID
905 clusterEdgeID = testClusterEdgeID
906 workloadName = "test-workload-name"
907 )
908 testCases := []struct {
909 title string
910 helmEdgeID *string
911 workloadName string
912 clusterEdgeID string
913 mockSQLQuery func() *sqlmock.ExpectedQuery
914 }{
915 {
916 title: "GetHelmWorkloadsByNameAndID",
917 workloadName: workloadName,
918 clusterEdgeID: clusterEdgeID,
919
920
921
922
923
924
925 mockSQLQuery: func() *sqlmock.ExpectedQuery {
926 return mock.ExpectQuery(sqlquery.GetWorkloadsByNameAndID).
927 WithArgs(clusterEdgeID, workloadName).
928 WillReturnRows(sqlmock.NewRows([]string{"workload_name", "helm_edge_id", "cluster_edge_id"}).
929 AddRow(workloadName, helmEdgeID, clusterEdgeID))
930 },
931 },
932 }
933
934 for _, tc := range testCases {
935 tc.mockSQLQuery()
936
937 t.Run(tc.title, func(t *testing.T) {
938 helmWorkloads, err := service.GetHelmWorkloadsByName(context.Background(), tc.clusterEdgeID, tc.workloadName)
939 assert.NoError(t, err)
940 assert.NotEmpty(t, helmWorkloads)
941 })
942 }
943 }
944
945 func TestSoftDeleteHelmReleaseSQLEntry(t *testing.T) {
946 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
947 if err != nil {
948 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
949 }
950 defer db.Close()
951 service := NewHelmService(nil, nil, nil, db, nil, nil)
952
953 var (
954 helmEdgeID = helmEdgeID
955 clusterEdgeID = testClusterEdgeID
956
957 )
958 testCases := []struct {
959 title string
960 helmEdgeID *string
961 workloadName *string
962 clusterEdgeID *string
963 mockSQLQueries []func() *sqlmock.ExpectedQuery
964 mockSQLExec func() *sqlmock.ExpectedExec
965 expectErr bool
966 }{
967 {
968 title: "Pass in helmEdgeID only",
969 helmEdgeID: &helmEdgeID,
970 workloadName: nil,
971 clusterEdgeID: nil,
972 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
973 func() *sqlmock.ExpectedQuery {
974 return mock.ExpectQuery(sqlquery.GetClusterEdgeIDsUsingHelmWorkloadLabels).
975 WithArgs(helmEdgeID).
976 WillReturnRows(sqlmock.NewRows([]string{"cluster_edge_id"}).
977 AddRow(clusterEdgeID))
978 },
979 },
980 mockSQLExec: func() *sqlmock.ExpectedExec {
981 return mock.ExpectExec(sqlquery.DeleteHelmWorkload).WithArgs(helmEdgeID).
982 WillReturnResult(sqlmock.NewResult(1, 1))
983 },
984 expectErr: true,
985 },
986 {
987 title: "Pass in nil only",
988 helmEdgeID: nil,
989 workloadName: nil,
990 clusterEdgeID: nil,
991 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
992 func() *sqlmock.ExpectedQuery {
993 return nil
994 },
995 },
996 mockSQLExec: func() *sqlmock.ExpectedExec {
997 return nil
998 },
999 expectErr: true,
1000 },
1001 }
1002
1003 for _, tc := range testCases {
1004 for _, mockSQLFn := range tc.mockSQLQueries {
1005 mockSQLFn()
1006 }
1007
1008 tc.mockSQLExec()
1009
1010 t.Run(tc.title, func(t *testing.T) {
1011 err := service.SoftDeleteHelmReleaseSQL(context.Background(), tc.helmEdgeID, tc.workloadName, tc.clusterEdgeID)
1012 if tc.expectErr {
1013 assert.Error(t, err)
1014 } else {
1015 assert.NoError(t, err)
1016 }
1017 })
1018 }
1019 }
1020
1021 func TestUpdateHelmReleaseSQLEntry(t *testing.T) {
1022 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1023 if err != nil {
1024 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1025 }
1026 defer db.Close()
1027 service := NewHelmService(nil, nil, nil, db, nil, nil)
1028
1029 username := "test-user"
1030 version := "1.2.2"
1031 configValues := "configValues"
1032 helmEdgeID := "aa46d745-adf3-4482-955d-c046178a67ea"
1033 namespace := "test-ns"
1034 now := time.Now()
1035 ctx := middleware.NewContext(context.Background(), &types.AuthUser{
1036 Username: "test-user",
1037 })
1038
1039 type testCase struct {
1040 title string
1041 version *string
1042 configValues *string
1043 configMaps []model.InjectableConfigmaps
1044 mockSQLQueries func() []interface{}
1045 }
1046 testCases := []testCase{
1047 {
1048 title: "Version and config values are provided, no config map(s) selected",
1049 version: &version,
1050 configValues: &configValues,
1051 configMaps: nil,
1052 mockSQLQueries: func() []interface{} {
1053 return []interface{}{
1054 mock.ExpectQuery(sqlquery.UpdateHelmWorkload).WithArgs(version, configValues, username, helmEdgeID).WillReturnRows(sqlmock.NewRows([]string{"workload_namespace"}).AddRow(namespace)),
1055 mock.ExpectExec(sqlquery.DeleteHelmConfigmaps).WithArgs(helmEdgeID).WillReturnResult(sqlmock.NewResult(1, 1)),
1056 }
1057 },
1058 },
1059 {
1060 title: "Version and config values are not provided, no config map(s) selected",
1061 version: nil,
1062 configValues: nil,
1063 configMaps: nil,
1064 mockSQLQueries: func() []interface{} {
1065 return []interface{}{
1066 mock.ExpectQuery(sqlquery.GetHelmWorkloadInfoByHelmEdgeID).WithArgs(helmEdgeID).WillReturnRows(sqlmock.NewRows([]string{"helm_chart_version", "helm_config"}).AddRow(version, configValues)),
1067 mock.ExpectQuery(sqlquery.UpdateHelmWorkload).WithArgs(version, configValues, username, helmEdgeID).WillReturnRows(sqlmock.NewRows([]string{"workload_namespace"}).AddRow(namespace)),
1068 mock.ExpectExec(sqlquery.DeleteHelmConfigmaps).WithArgs(helmEdgeID).WillReturnResult(sqlmock.NewResult(1, 1)),
1069 }
1070 },
1071 },
1072 {
1073 title: "Version and config values are provided, EdgeInfo and BSLInfo config maps selected",
1074 version: &version,
1075 configValues: &configValues,
1076 configMaps: []model.InjectableConfigmaps{model.InjectableConfigmapsEdgeInfo, model.InjectableConfigmapsBSLInfo},
1077 mockSQLQueries: func() []interface{} {
1078 return []interface{}{
1079 mock.ExpectQuery(sqlquery.UpdateHelmWorkload).WithArgs(version, configValues, username, helmEdgeID).WillReturnRows(sqlmock.NewRows([]string{"workload_namespace"}).AddRow(namespace)),
1080 mock.ExpectQuery(sqlquery.GetHelmWorkloadConfigmaps).WithArgs(helmEdgeID).WillReturnRows(sqlmock.NewRows([]string{"helm_workload_configmap_edge_id", "helm_edge_id", "namespace", "config_map", "created_at", "updated_at"})),
1081 mock.ExpectBegin(),
1082 mock.ExpectExec(sqlquery.CreateHelmConfigmaps).WithArgs(helmEdgeID, namespace, model.InjectableConfigmapsEdgeInfo.String()).WillReturnResult(sqlmock.NewResult(1, 1)),
1083 mock.ExpectExec(sqlquery.CreateHelmConfigmaps).WithArgs(helmEdgeID, namespace, model.InjectableConfigmapsBSLInfo.String()).WillReturnResult(sqlmock.NewResult(1, 1)),
1084 mock.ExpectCommit(),
1085 }
1086 },
1087 },
1088 {
1089 title: "Version and config values are provided, EdgeInfo config map selected and BSLInfo config map deselected",
1090 version: &version,
1091 configValues: &configValues,
1092 configMaps: []model.InjectableConfigmaps{model.InjectableConfigmapsEdgeInfo},
1093 mockSQLQueries: func() []interface{} {
1094 return []interface{}{
1095 mock.ExpectQuery(sqlquery.UpdateHelmWorkload).WithArgs(version, configValues, username, helmEdgeID).WillReturnRows(sqlmock.NewRows([]string{"workload_namespace"}).AddRow(namespace)),
1096 mock.ExpectQuery(sqlquery.GetHelmWorkloadConfigmaps).WithArgs(helmEdgeID).WillReturnRows(sqlmock.NewRows([]string{"helm_workload_configmap_edge_id", "helm_edge_id", "namespace", "config_map", "created_at", "updated_at"}).
1097 AddRow("test-edge-id", helmEdgeID, namespace, model.InjectableConfigmapsBSLInfo.String(), now, now)),
1098 mock.ExpectBegin(),
1099 mock.ExpectExec(sqlquery.DeleteHelmConfigmap).WithArgs(helmEdgeID, model.InjectableConfigmapsBSLInfo.String()).WillReturnResult(sqlmock.NewResult(1, 1)),
1100 mock.ExpectExec(sqlquery.CreateHelmConfigmaps).WithArgs(helmEdgeID, namespace, model.InjectableConfigmapsEdgeInfo.String()).WillReturnResult(sqlmock.NewResult(1, 1)),
1101 mock.ExpectCommit(),
1102 }
1103 },
1104 },
1105 }
1106
1107 for _, tc := range testCases {
1108 tc.mockSQLQueries()
1109
1110 t.Run(tc.title, func(t *testing.T) {
1111 err := service.UpdateHelmReleaseSQL(ctx, helmEdgeID, tc.version, tc.configValues, tc.configMaps)
1112 assert.NoError(t, err)
1113 assert.NoError(t, mock.ExpectationsWereMet())
1114 })
1115 }
1116 }
1117
1118 func TestCreateHelmReleaseSQLEntry(t *testing.T) {
1119 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1120 if err != nil {
1121 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1122 }
1123 defer db.Close()
1124 service := NewHelmService(nil, nil, nil, db, nil, nil)
1125
1126
1127 defaultInstallationType := model.WorkloadInstallationTypeServerPreferred
1128 name := "hr-name"
1129 configValues := "configValues"
1130 secrets := []string{"secret1", "secret2"}
1131 cluster := getTestCluster("test-cluster")
1132 hrPayload := getHelmPayload(&cluster.BannerEdgeID, &cluster.ClusterEdgeID, name, configValues, secrets...)
1133 hrPayloadNoBanner := getHelmPayload(nil, &cluster.ClusterEdgeID, name, configValues, secrets...)
1134 hrPayloadNoCluster := getHelmPayload(&cluster.BannerEdgeID, nil, name, configValues, secrets...)
1135 hrPayloadNoIDs := getHelmPayload(nil, nil, name, configValues, secrets...)
1136 ctx := middleware.NewContext(context.Background(), &types.AuthUser{
1137 Username: "test-user",
1138 })
1139
1140 type testCase struct {
1141 title string
1142 expectErr bool
1143 payload model.HelmReleasePayload
1144 cluster *model.Cluster
1145 mockSQLQueries func() []interface{}
1146 }
1147 testCases := []testCase{
1148 {
1149 title: "HelmReleasePayload has both bannerEdgeID and clusterEdgeID",
1150 expectErr: false,
1151 payload: hrPayload,
1152 cluster: cluster,
1153 mockSQLQueries: func() []interface{} {
1154 return []interface{}{
1155 mock.ExpectBegin(),
1156 mock.ExpectQuery(sqlquery.CreateHelmWorkload).WithArgs(*hrPayload.BannerEdgeID, hrPayload.Name, hrPayload.Namespace, hrPayload.HelmChart, hrPayload.HelmRepository, hrPayload.Version, *hrPayload.ConfigValues, "test-user", defaultInstallationType, hrPayload.Secret).
1157 WillReturnRows(mock.NewRows([]string{"helm_edge_id"}).AddRow(helmEdgeID)),
1158 mock.ExpectExec(sqlquery.CreateWorkloadClusterMapper).WithArgs(helmEdgeID, *hrPayload.ClusterEdgeID).WillReturnResult(sqlmock.NewResult(1, 1)),
1159 mock.ExpectExec(sqlquery.CreateHelmSecret).WithArgs(helmEdgeID, "secret1").WillReturnResult(sqlmock.NewResult(1, 1)),
1160 mock.ExpectExec(sqlquery.CreateHelmSecret).WithArgs(helmEdgeID, "secret2").WillReturnResult(sqlmock.NewResult(1, 1)),
1161 mock.ExpectExec(sqlquery.CreateHelmConfigmaps).WithArgs(helmEdgeID, hrPayload.Namespace, hrPayload.InjectConfigmaps[0].String()).WillReturnResult(sqlmock.NewResult(1, 1)),
1162 mock.ExpectCommit(),
1163 }
1164 },
1165 },
1166 {
1167
1168 title: "HelmReleasePayload only has bannerEdgeID",
1169 expectErr: false,
1170 payload: hrPayloadNoCluster,
1171 cluster: nil,
1172 mockSQLQueries: func() []interface{} {
1173 return []interface{}{
1174 mock.ExpectBegin(),
1175 mock.ExpectQuery(sqlquery.CreateHelmWorkload).WithArgs(*hrPayloadNoCluster.BannerEdgeID, hrPayloadNoCluster.Name, hrPayloadNoCluster.Namespace, hrPayloadNoCluster.HelmChart, hrPayloadNoCluster.HelmRepository, hrPayloadNoCluster.Version, *hrPayloadNoCluster.ConfigValues, "test-user", defaultInstallationType, hrPayloadNoCluster.Secret).
1176 WillReturnRows(mock.NewRows([]string{"helm_edge_id"}).AddRow(helmEdgeID)),
1177 mock.ExpectExec(sqlquery.CreateHelmSecret).WithArgs(helmEdgeID, "secret1").WillReturnResult(sqlmock.NewResult(1, 1)),
1178 mock.ExpectExec(sqlquery.CreateHelmSecret).WithArgs(helmEdgeID, "secret2").WillReturnResult(sqlmock.NewResult(1, 1)),
1179 mock.ExpectExec(sqlquery.CreateHelmConfigmaps).WithArgs(helmEdgeID, hrPayloadNoCluster.Namespace, hrPayloadNoCluster.InjectConfigmaps[0].String()).WillReturnResult(sqlmock.NewResult(1, 1)),
1180 mock.ExpectCommit(),
1181 }
1182 },
1183 },
1184 {
1185 title: "HelmReleasePayload only has clusterEdgeID",
1186 expectErr: false,
1187 payload: hrPayloadNoBanner,
1188 cluster: cluster,
1189 mockSQLQueries: func() []interface{} {
1190 return []interface{}{
1191 mock.ExpectBegin(),
1192 mock.ExpectQuery(sqlquery.CreateHelmWorkload).WithArgs(cluster.BannerEdgeID, hrPayloadNoBanner.Name, hrPayloadNoBanner.Namespace, hrPayloadNoBanner.HelmChart, hrPayloadNoBanner.HelmRepository, hrPayloadNoBanner.Version, *hrPayloadNoBanner.ConfigValues, "test-user", defaultInstallationType, hrPayloadNoBanner.Secret).
1193 WillReturnRows(mock.NewRows([]string{"helm_edge_id"}).AddRow(helmEdgeID)),
1194 mock.ExpectExec(sqlquery.CreateWorkloadClusterMapper).WithArgs(helmEdgeID, *hrPayloadNoBanner.ClusterEdgeID).WillReturnResult(sqlmock.NewResult(1, 1)),
1195 mock.ExpectExec(sqlquery.CreateHelmSecret).WithArgs(helmEdgeID, "secret1").WillReturnResult(sqlmock.NewResult(1, 1)),
1196 mock.ExpectExec(sqlquery.CreateHelmSecret).WithArgs(helmEdgeID, "secret2").WillReturnResult(sqlmock.NewResult(1, 1)),
1197 mock.ExpectExec(sqlquery.CreateHelmConfigmaps).WithArgs(helmEdgeID, hrPayloadNoBanner.Namespace, hrPayloadNoBanner.InjectConfigmaps[0].String()).WillReturnResult(sqlmock.NewResult(1, 1)),
1198 mock.ExpectCommit(),
1199 }
1200 },
1201 },
1202 {
1203 title: "HelmReleasePayload does not have bannerEdgeID nor clusterEdgeID",
1204 expectErr: true,
1205 payload: hrPayloadNoIDs,
1206 cluster: nil,
1207 mockSQLQueries: func() []interface{} {
1208 return nil
1209 },
1210 },
1211 }
1212
1213 for _, tc := range testCases {
1214 tc.mockSQLQueries()
1215
1216 t.Run(tc.title, func(t *testing.T) {
1217 err := service.CreateHelmReleaseSQL(ctx, tc.payload, tc.cluster)
1218 if tc.expectErr {
1219 assert.Error(t, err)
1220 } else {
1221 assert.NoError(t, err)
1222 assert.NoError(t, mock.ExpectationsWereMet())
1223 }
1224 })
1225 }
1226 }
1227
1228 func TestHelmService_GetHelmWorkload(t *testing.T) {
1229 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1230
1231 if err != nil {
1232 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1233 }
1234 defer db.Close()
1235
1236 params := getHelmConfigSchemaParams()
1237 url := fmt.Sprintf("/%s-%s/README.md", params.ChartName, params.ChartVersion)
1238 srv := createHelmRepoClient(t, map[string][]byte{url: []byte(readme)})
1239
1240 getSecret := func(_ context.Context, name *string, owner, _type *string, getValues bool, _projectID string) ([]*model.SecretManagerResponse, error) {
1241 assert.Equal(t, "test-helm-workload", *name)
1242 assert.Nil(t, owner)
1243 assert.Equal(t, helmRepoSecretType, *_type)
1244 assert.True(t, getValues)
1245 assert.Equal(t, projectID, _projectID)
1246 return []*model.SecretManagerResponse{getSecretManagerResponse(*name, _projectID, srv.URL, helmRepoSecretType)}, nil
1247 }
1248
1249 gcpService := createGCPServiceMock(t, getSecret)
1250 secret := &model.HelmSecrets{
1251 SecretEdgeID: "af7351a3-22e0-4b76-aeeb-2f9d77a2b642",
1252 Name: "test-secret2",
1253 CreatedAt: "2022-10-19 17:33:07.347283+00",
1254 UpdatedAt: "2022-10-19 17:33:07.347283+00",
1255 }
1256 defaultValue := ""
1257 deleted := false
1258
1259 helmWorkload := helmTypes.HelmWorkloadQuery{
1260 ClusterEdgeID: testClusterEdgeID,
1261 BannerEdgeID: testBannerEdgeID,
1262 HelmEdgeID: helmEdgeID,
1263 Name: "test-helm-workload",
1264 Namespace: "nginx",
1265 HelmChart: "nginx",
1266 HelmRepository: "test-repo",
1267 HelmChartVersion: "2.3.1",
1268 HelmConfig: &defaultValue,
1269 InstalledBy: &defaultValue,
1270 WorkloadInstallationType: "mockInstallationType",
1271 CreatedAt: "mockCreatedAt",
1272 UpdatedAt: "mockUpdatedAt",
1273 HelmRepoSecret: "test-helm-workload",
1274 ProjectID: "test-org",
1275 Deleted: &deleted,
1276 }
1277 service := NewHelmService(appConfig, nil, gcpService, db, nil, nil)
1278
1279 mock.ExpectQuery(sqlquery.GetHelmWorkload).
1280 WithArgs(helmEdgeID, testClusterEdgeID).
1281 WillReturnRows(sqlmock.NewRows([]string{"clusters.cluster_edge_id", "helm_workloads.banner_edge_id", "helm_workloads.helm_edge_id",
1282 "workload_name", " workload_namespace", "helm_chart", "helm_repo", "helm_chart_version", "helm_config", "installed_by", "workload_installation_type", "created_at", "updated_at", "helm_repo_secret", "project_id", "deleted"}).
1283 AddRow(
1284 helmWorkload.ClusterEdgeID,
1285 helmWorkload.BannerEdgeID,
1286 helmWorkload.HelmEdgeID,
1287 helmWorkload.Name,
1288 helmWorkload.Namespace,
1289 helmWorkload.HelmChart,
1290 helmWorkload.HelmRepository,
1291 helmWorkload.HelmChartVersion,
1292 helmWorkload.HelmConfig,
1293 helmWorkload.InstalledBy,
1294 helmWorkload.WorkloadInstallationType,
1295 helmWorkload.CreatedAt,
1296 helmWorkload.UpdatedAt,
1297 helmWorkload.HelmRepoSecret,
1298 helmWorkload.ProjectID,
1299 helmWorkload.Deleted))
1300
1301 mock.ExpectQuery(sqlquery.GetAttachedHelmSecretByHelmEdgeID).
1302 WithArgs(helmWorkload.HelmEdgeID).
1303 WillReturnRows(sqlmock.NewRows([]string{"secret_edge_id", "secret_name", "created_at", "updated_at"}).
1304 AddRow(secret.SecretEdgeID, secret.Name, secret.CreatedAt, secret.UpdatedAt))
1305
1306 mock.ExpectQuery(sqlquery.GetHelmWorkloadConfigmaps).
1307 WithArgs(helmWorkload.HelmEdgeID).
1308 WillReturnRows(sqlmock.NewRows([]string{"helm_workload_configmap_edge_id", "helm_edge_id", "namespace", "config_map", "created_at", "updated_at"}).
1309 AddRow("helm_workload_configmap_edge_id", helmEdgeID, "namespace", "config_map", "created_at", "updated_at"))
1310
1311 mock.ExpectQuery(sqlquery.SelectEdgeLabelsForHelmEdgeID).
1312 WithArgs(helmWorkload.HelmEdgeID).
1313 WillReturnRows(mock.NewRows([]string{"label_edge_id", "label_key", "color", "visible", "editable", "banner_edge_id", "label_unique", "description", "label_type"}).
1314 AddRow("label_edge_id", "test-label-key", "color", true, true, nil, true, "description", "label_type"))
1315
1316 response, err := service.GetHelmWorkload(context.Background(), helmEdgeID, testClusterEdgeID)
1317 assert.NoError(t, err)
1318 assert.NoError(t, mock.ExpectationsWereMet())
1319 assert.Equal(t, "test-helm-workload", response.Name)
1320 }
1321
1322 func TestHelmService_GetHelmWorkloadConfigmaps(t *testing.T) {
1323 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1324 clusterEdgeID := testClusterEdgeID
1325 testHelmEdgeID := helmEdgeID
1326
1327 if err != nil {
1328 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1329 }
1330 defer db.Close()
1331
1332 service := NewHelmService(appConfig, nil, nil, db, nil, nil)
1333
1334 type test struct {
1335 testName string
1336 clusterEdgeID *string
1337 helmEdgeID string
1338 expectedCount int
1339 mockSQLQueries []func() *sqlmock.ExpectedQuery
1340 }
1341
1342 tests := []test{
1343 {testName: "GetHelmworkloadConfigMapCountOne",
1344 clusterEdgeID: &clusterEdgeID,
1345 helmEdgeID: testHelmEdgeID,
1346 expectedCount: 1,
1347 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1348 func() *sqlmock.ExpectedQuery {
1349 return mock.ExpectQuery(sqlquery.GetHelmWorkloadConfigmaps).
1350 WithArgs(helmEdgeID).
1351 WillReturnRows(sqlmock.NewRows([]string{"helm_workload_configmap_edge_id", "helm_edge_id", "namespace", "config_map", "created_at", "updated_at"}).
1352 AddRow("helm_workload_configmap_edge_id", helmEdgeID, "namespace", "config_map", "created_at", "updated_at"))
1353 },
1354 },
1355 },
1356 {testName: "GetHelmworkloadConfigMapCountZero",
1357 clusterEdgeID: &clusterEdgeID,
1358 helmEdgeID: testHelmEdgeID,
1359 expectedCount: 0,
1360 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1361 func() *sqlmock.ExpectedQuery {
1362 return mock.ExpectQuery(sqlquery.GetHelmWorkloadConfigmaps).
1363 WithArgs(helmEdgeID).
1364 WillReturnRows(sqlmock.NewRows([]string{"helm_workload_configmap_edge_id", "helm_edge_id", "namespace", "config_map", "created_at", "updated_at"}))
1365 },
1366 },
1367 },
1368 }
1369
1370 for _, tc := range tests {
1371 for _, mockSQLFn := range tc.mockSQLQueries {
1372 mockSQLFn()
1373 }
1374
1375 t.Run(tc.testName, func(t *testing.T) {
1376 response, err := service.GetHelmWorkloadConfigmaps(context.Background(), tc.helmEdgeID)
1377 assert.NoError(t, err)
1378 assert.Equal(t, tc.expectedCount, len(response))
1379
1380 if tc.expectedCount == 0 {
1381 emptyConfigMapList := make([]*model.HelmWorkloadConfigmaps, 0)
1382 assert.Equal(t, emptyConfigMapList, response)
1383 }
1384 })
1385 }
1386 }
1387
1388 func TestHelmService_DeleteHelmWorkloadSecrets(t *testing.T) {
1389 testSecretNames := []string{"test-secret-02"}
1390 testHelmID := helmEdgeID
1391
1392 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1393 if err != nil {
1394 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1395 }
1396 defer db.Close()
1397
1398 mock.ExpectExec(sqlquery.DeleteHelmSecret).WithArgs(testHelmID, testSecretNames[0]).
1399 WillReturnResult(sqlmock.NewResult(1, 1))
1400
1401 service := NewHelmService(appConfig, nil, nil, db, nil, nil)
1402
1403 if _, err = service.DeleteHelmSecrets(context.Background(), testHelmID, testSecretNames); err != nil {
1404 t.Errorf("error deleting secrets: %s", err)
1405 }
1406 assert.NoError(t, err)
1407 if err := mock.ExpectationsWereMet(); err != nil {
1408 t.Errorf("there were unfulfilled expectations: %s", err)
1409 }
1410 }
1411
1412 func TestHelmService_GetHelmStatus(t *testing.T) {
1413 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1414 if err != nil {
1415 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1416 }
1417 defer db.Close()
1418
1419 ctx := middleware.NewContext(context.Background(), &types.AuthUser{
1420 Username: "test-user",
1421 })
1422 workloadName := "test-helm-release"
1423 workloadNamespace := "test-helm-release-ns"
1424 helmChartName := "test-chart"
1425 helmRepoName := "test-repository"
1426 testCluster := "test-cluster-123"
1427 updatedTime, _ := time.Parse(time.RFC3339, "2024-01-01T01:00:00.000000-00:00")
1428 service := NewHelmService(nil, nil, nil, db, nil, nil)
1429
1430 type test struct {
1431 testName string
1432 clusterEdgeID string
1433 createdAt string
1434 updatedAt string
1435 expected *model.HelmStatus
1436 mockSQLQueries []func() *sqlmock.ExpectedQuery
1437 }
1438 tests := []test{{
1439 testName: "successful-helm-release",
1440 clusterEdgeID: testCluster,
1441 createdAt: "2024-01-01T01:00:00.000000-00:00",
1442 updatedAt: "2024-01-01T01:00:00.000000-00:00",
1443 expected: &model.HelmStatus{
1444 Status: status.Ready,
1445 Message: status.WorkloadReadyStatusMessage,
1446 Pods: []*model.Pods{
1447 {Name: "test-helm-pod1", Status: status.Running, Message: "Pod is ready"},
1448 {Name: "test-helm-pod2", Status: status.Running, Message: "Pod is ready"},
1449 },
1450 },
1451 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1452 func() *sqlmock.ExpectedQuery {
1453 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsStatus).WithArgs(testCluster, workloadNamespace).
1454 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}).
1455 AddRow("test-helm-pod1", "\"True\"", "false").
1456 AddRow("test-helm-pod2", "\"True\"", "false"))
1457 },
1458 func() *sqlmock.ExpectedQuery {
1459 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsReason).WithArgs(testCluster, workloadNamespace).
1460 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}).
1461 AddRow("test-helm-pod1", "", "true").
1462 AddRow("test-helm-pod2", "", "true"))
1463 },
1464 func() *sqlmock.ExpectedQuery {
1465 return mock.ExpectQuery(sqlquery.GetHelmWorkloadWatchedTime).WithArgs(workloadName, testCluster).
1466 WillReturnRows(mock.NewRows([]string{"watched_at"}).AddRow(updatedTime))
1467 },
1468 func() *sqlmock.ExpectedQuery {
1469 return mock.ExpectQuery(sqlquery.GetHelmConditionStatus).WithArgs("HelmRelease", workloadName, testCluster).
1470 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"True\"", "false"))
1471 },
1472 func() *sqlmock.ExpectedQuery {
1473 return mock.ExpectQuery(sqlquery.GetHelmConditionReason).WithArgs("HelmRelease", workloadName, testCluster).
1474 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"UpgradeSucceeded\"", "false"))
1475 },
1476 },
1477 },
1478 {
1479 testName: "failed-helm-release",
1480 clusterEdgeID: testCluster,
1481 createdAt: "2024-01-01T01:00:00.000000-00:00",
1482 updatedAt: "2024-01-01T01:00:00.000000-00:00",
1483 expected: &model.HelmStatus{
1484 Status: status.Error,
1485 Message: "HelmRelease: UpgradeFailed, helmChart: Failed to get Helm Chart, helmRepo: Failed to get Helm Repo",
1486 Pods: []*model.Pods{
1487 {Name: "test-helm-pod1", Status: status.Error, Message: "Pod Failed"},
1488 },
1489 },
1490 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1491 func() *sqlmock.ExpectedQuery {
1492 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsStatus).WithArgs(testCluster, workloadNamespace).
1493 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}).
1494 AddRow("test-helm-pod1", "\"False\"", "false"))
1495 },
1496 func() *sqlmock.ExpectedQuery {
1497 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsReason).WithArgs(testCluster, workloadNamespace).
1498 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}).
1499 AddRow("test-helm-pod1", "Pod Failed", "false"))
1500 },
1501 func() *sqlmock.ExpectedQuery {
1502 return mock.ExpectQuery(sqlquery.GetHelmWorkloadWatchedTime).WithArgs(workloadName, testCluster).
1503 WillReturnRows(mock.NewRows([]string{"watched_at"}).AddRow(updatedTime))
1504 },
1505 func() *sqlmock.ExpectedQuery {
1506 return mock.ExpectQuery(sqlquery.GetHelmConditionStatus).WithArgs("HelmRelease", workloadName, testCluster).
1507 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"False\"", "false"))
1508 },
1509 func() *sqlmock.ExpectedQuery {
1510 return mock.ExpectQuery(sqlquery.GetHelmConditionReason).WithArgs("HelmRelease", workloadName, testCluster).
1511 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"UpgradeFailed\"", "false"))
1512 },
1513 func() *sqlmock.ExpectedQuery {
1514 return mock.ExpectQuery(sqlquery.GetHelmConditionStatus).WithArgs("HelmChart", helmChartName, testCluster).
1515 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"False\"", "false"))
1516 },
1517 func() *sqlmock.ExpectedQuery {
1518 return mock.ExpectQuery(sqlquery.GetHelmConditionReason).WithArgs("HelmChart", helmChartName, testCluster).
1519 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"Failed to get Helm Chart\"", "false"))
1520 },
1521 func() *sqlmock.ExpectedQuery {
1522 return mock.ExpectQuery(sqlquery.GetHelmConditionStatus).WithArgs("HelmRepo", helmRepoName, testCluster).
1523 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"False\"", "false"))
1524 },
1525 func() *sqlmock.ExpectedQuery {
1526 return mock.ExpectQuery(sqlquery.GetHelmConditionReason).WithArgs("HelmRepo", helmRepoName, testCluster).
1527 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"Failed to get Helm Repo\"", "false"))
1528 },
1529 },
1530 },
1531 {
1532 testName: "installing-helm-release",
1533 clusterEdgeID: testCluster,
1534 createdAt: "2024-01-01T01:00:00.000000-00:00",
1535 updatedAt: "2024-01-01T01:00:00.000000-00:00",
1536 expected: &model.HelmStatus{
1537 Status: status.Installing,
1538 Message: status.InstallingStatusMessage,
1539 Pods: []*model.Pods{},
1540 },
1541 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1542 func() *sqlmock.ExpectedQuery {
1543 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsStatus).WithArgs(testCluster, workloadNamespace).
1544 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}))
1545 },
1546 func() *sqlmock.ExpectedQuery {
1547 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsReason).WithArgs(testCluster, workloadNamespace).
1548 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}))
1549 },
1550 func() *sqlmock.ExpectedQuery {
1551 return mock.ExpectQuery(sqlquery.GetHelmWorkloadWatchedTime).WithArgs(workloadName, testCluster).
1552 WillReturnRows(mock.NewRows([]string{"watched_at"}).AddRow(updatedTime))
1553 },
1554 func() *sqlmock.ExpectedQuery {
1555 return mock.ExpectQuery(sqlquery.GetHelmConditionStatus).WithArgs("HelmRelease", workloadName, testCluster).
1556 WillReturnRows(mock.NewRows([]string{"watched_field_values.value", "watched_field_values.missing"}).AddRow("\"\"", "true"))
1557 },
1558 },
1559 },
1560 {
1561 testName: "installing-helm-release-no-watched-entry",
1562 clusterEdgeID: testCluster,
1563 createdAt: "2024-01-01T01:00:00.000000-00:00",
1564 updatedAt: "2024-01-01T01:00:00.000000-00:00",
1565 expected: &model.HelmStatus{
1566 Status: status.Installing,
1567 Message: status.InstallingStatusMessage,
1568 Pods: []*model.Pods{},
1569 },
1570 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1571 func() *sqlmock.ExpectedQuery {
1572 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsStatus).WithArgs(testCluster, workloadNamespace).
1573 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}))
1574 },
1575 func() *sqlmock.ExpectedQuery {
1576 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsReason).WithArgs(testCluster, workloadNamespace).
1577 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}))
1578 },
1579 func() *sqlmock.ExpectedQuery {
1580 return mock.ExpectQuery(sqlquery.GetHelmWorkloadWatchedTime).WithArgs(workloadName, testCluster).
1581 WillReturnRows(mock.NewRows([]string{"watched_at"}))
1582 },
1583 },
1584 },
1585 {
1586 testName: "updating-helm-release",
1587 clusterEdgeID: testCluster,
1588 createdAt: "2024-01-01T01:00:00.000000-00:00",
1589 updatedAt: "2024-01-02T01:00:00.000000-00:00",
1590 expected: &model.HelmStatus{
1591 Status: status.Updating,
1592 Message: status.UpdatingStatusMessage,
1593 Pods: []*model.Pods{
1594 {Name: "test-helm-pod1", Status: status.Running, Message: "Pod is ready"},
1595 {Name: "test-helm-pod2", Status: status.Error, Message: "Pod Failed"},
1596 },
1597 },
1598 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1599 func() *sqlmock.ExpectedQuery {
1600 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsStatus).WithArgs(testCluster, workloadNamespace).
1601 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}).
1602 AddRow("test-helm-pod1", "\"True\"", "false").
1603 AddRow("test-helm-pod2", "\"False\"", "false"))
1604 },
1605 func() *sqlmock.ExpectedQuery {
1606 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsReason).WithArgs(testCluster, workloadNamespace).
1607 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}).
1608 AddRow("test-helm-pod1", "", "true").
1609 AddRow("test-helm-pod2", "Pod Failed", "false"))
1610 },
1611 func() *sqlmock.ExpectedQuery {
1612 return mock.ExpectQuery(sqlquery.GetHelmWorkloadWatchedTime).WithArgs(workloadName, testCluster).
1613 WillReturnRows(mock.NewRows([]string{"watched_at"}).AddRow(updatedTime))
1614 },
1615 },
1616 },
1617 {
1618 testName: "updating-helm-release-no-watched-entry",
1619 clusterEdgeID: testCluster,
1620 createdAt: "2024-01-01T01:00:00.000000-00:00",
1621 updatedAt: "2024-01-02T01:00:00.000000-00:00",
1622 expected: &model.HelmStatus{
1623 Status: status.Updating,
1624 Message: status.UpdatingStatusMessage,
1625 Pods: []*model.Pods{
1626 {Name: "test-helm-pod1", Status: status.Running, Message: "Pod is ready"},
1627 {Name: "test-helm-pod2", Status: status.Running, Message: "Pod is ready"},
1628 },
1629 },
1630 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1631 func() *sqlmock.ExpectedQuery {
1632 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsStatus).WithArgs(testCluster, workloadNamespace).
1633 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}).
1634 AddRow("test-helm-pod1", "\"True\"", "false").
1635 AddRow("test-helm-pod2", "\"True\"", "false"))
1636 },
1637 func() *sqlmock.ExpectedQuery {
1638 return mock.ExpectQuery(sqlquery.GetHelmWorkloadPodsReason).WithArgs(testCluster, workloadNamespace).
1639 WillReturnRows(mock.NewRows([]string{"watched_field_objects.name", "watched_field_values.value", "watched_field_values.missing"}).
1640 AddRow("test-helm-pod1", "", "true").
1641 AddRow("test-helm-pod2", "", "true"))
1642 },
1643 func() *sqlmock.ExpectedQuery {
1644 return mock.ExpectQuery(sqlquery.GetHelmWorkloadWatchedTime).WithArgs(workloadName, testCluster).
1645 WillReturnRows(mock.NewRows([]string{"watched_at"}))
1646 },
1647 },
1648 },
1649 }
1650
1651 for _, tc := range tests {
1652 for _, mockSQLFn := range tc.mockSQLQueries {
1653 mockSQLFn()
1654 }
1655
1656 t.Run(tc.testName, func(t *testing.T) {
1657 combinedStatus, err := service.GetHelmStatus(ctx, testCluster, workloadName, workloadNamespace, helmChartName, helmRepoName, tc.createdAt, tc.updatedAt, &falseValue)
1658 assert.NoError(t, err)
1659 assert.Equal(t, tc.expected.Status, combinedStatus.Status)
1660 assert.Equal(t, tc.expected.Message, combinedStatus.Message)
1661 assert.Equal(t, len(tc.expected.Pods), len(combinedStatus.Pods))
1662 for _, pod1 := range tc.expected.Pods {
1663 for _, pod2 := range combinedStatus.Pods {
1664 if pod1.Name == pod2.Name {
1665 assert.Equal(t, pod1.Status, pod2.Status)
1666 assert.Equal(t, pod1.Message, pod2.Message)
1667 }
1668 }
1669 }
1670 })
1671 }
1672 }
1673
1674 func TestHelmService_GetHelmStatusWithoutClusterID(t *testing.T) {
1675 db, _, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1676 if err != nil {
1677 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1678 }
1679 defer db.Close()
1680
1681 ctx := middleware.NewContext(context.Background(), &types.AuthUser{
1682 Username: "test-user",
1683 })
1684 workloadName := "test-helm-release"
1685 workloadNamespace := "test-helm-release-ns"
1686 helmChartName := "test-chart"
1687 helmRepoName := "test-repository"
1688
1689 includeDeleted := false
1690
1691 service := NewHelmService(nil, nil, nil, db, nil, nil)
1692
1693 type test struct {
1694 testName string
1695 clusterEdgeID string
1696 createdAt string
1697 updatedAt string
1698 deleted *bool
1699 expected *model.HelmStatus
1700 mockSQLQueries []func() *sqlmock.ExpectedQuery
1701 }
1702 tests := []test{
1703 {
1704 testName: "passing-in-empty-clusterEdgeID",
1705 clusterEdgeID: "",
1706 deleted: &includeDeleted,
1707 expected: &model.HelmStatus{
1708 Status: status.NotAvailable,
1709 Message: status.NotDeployedStatusMessage,
1710 },
1711 mockSQLQueries: []func() *sqlmock.ExpectedQuery{
1712 func() *sqlmock.ExpectedQuery {
1713 return nil
1714 },
1715 },
1716 },
1717 }
1718
1719 for _, tc := range tests {
1720 for _, mockSQLFn := range tc.mockSQLQueries {
1721 mockSQLFn()
1722 }
1723
1724 t.Run(tc.testName, func(t *testing.T) {
1725 combinedStatus, err := service.GetHelmStatus(ctx, tc.clusterEdgeID, workloadName, workloadNamespace, helmChartName, helmRepoName, tc.createdAt, tc.updatedAt, tc.deleted)
1726
1727 assert.NoError(t, err)
1728 assert.Equal(t, tc.expected.Status, combinedStatus.Status)
1729 assert.Equal(t, tc.expected.Message, combinedStatus.Message)
1730 assert.Empty(t, combinedStatus.Pods)
1731 })
1732 }
1733 }
1734
1735 func TestDeleteLabelFromHelmWorkload(t *testing.T) {
1736 testHelmID := "test-helm-delete"
1737 testLabelID := "test-label-id-delete"
1738
1739 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1740 if err != nil {
1741 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1742 }
1743 defer db.Close()
1744
1745 service := NewHelmService(nil, nil, nil, db, nil, nil)
1746 errMock := fmt.Errorf("ExecQuery 'DELETE FROM helm_workload_labels WHERE label_edge_id = $1 AND helm_edge_id=$2', arguments do not match: argument 0 expected [string - dsadadasdasdsa] does not match actual [string - jibberish]")
1747 errMsg := sqlerr.Wrap(errMock)
1748
1749 type result struct {
1750 result bool
1751 err error
1752 }
1753
1754 type test struct {
1755 testName string
1756 expected result
1757 testLabel string
1758 mockSQLQueries []func() *sqlmock.ExpectedExec
1759 }
1760
1761 tests := []test{
1762 {
1763 testName: "Delete single valid label",
1764 expected: result{
1765 result: true,
1766 err: nil,
1767 },
1768 testLabel: testLabelID,
1769 mockSQLQueries: []func() *sqlmock.ExpectedExec{
1770 func() *sqlmock.ExpectedExec {
1771 testRes := mock.ExpectExec(sqlquery.DeleteLabelFromHelmWorkload).WithArgs(testLabelID, testHelmID).
1772 WillReturnResult(sqlmock.NewResult(1, 1))
1773 return testRes
1774 },
1775 },
1776 },
1777 {
1778 testName: "Delete single invalid label",
1779 expected: result{
1780 result: false,
1781 err: errMsg,
1782 },
1783 testLabel: "jibberish",
1784 mockSQLQueries: []func() *sqlmock.ExpectedExec{
1785 func() *sqlmock.ExpectedExec {
1786 testRes := mock.ExpectExec(sqlquery.DeleteLabelFromHelmWorkload).WithArgs("dsadadasdasdsa", testHelmID).
1787 WillReturnResult(sqlmock.NewResult(1, 1))
1788 return testRes
1789 },
1790 },
1791 },
1792 }
1793 for _, tc := range tests {
1794 for _, mockSQLFn := range tc.mockSQLQueries {
1795 mockSQLFn()
1796 }
1797 t.Run(tc.testName, func(t *testing.T) {
1798 res, err := service.DeleteWorkloadLabel(context.Background(), testHelmID, tc.testLabel)
1799 if err != nil {
1800 assert.Error(t, err)
1801 }
1802 assert.Equal(t, tc.expected.result, res)
1803 assert.Equal(t, tc.expected.err, err)
1804 })
1805 }
1806 }
1807
1808 func TestAddLabelToHelmWorkload(t *testing.T) {
1809 testLabelIDForAdd := "test-label-id-add"
1810 helmWorkload := getTestHelmWorkloadQuery()
1811
1812 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1813 if err != nil {
1814 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1815 }
1816 defer db.Close()
1817
1818 service := NewHelmService(nil, nil, nil, db, nil, nil)
1819
1820 type result struct {
1821 result bool
1822 err error
1823 }
1824
1825 type testAddWorkloadLabel struct {
1826 testName string
1827 expected result
1828 testLabel string
1829 mockSQLQueries []func() *sqlmock.ExpectedExec
1830 }
1831 errMsg := fmt.Errorf("[{\"message\":\"Invalid input syntax for type\",\"extensions\":{\"additional\":{\"errorType\":\"EDGE_SQL_STATE\",\"severity\":\"\",\"statusCode\":\"Unknown\"},\"operationID\":\"\",\"version\":\"0.20.0\"}}]")
1832 sqlErr := sqlerr.Wrap(errMsg)
1833
1834 testAdd := []testAddWorkloadLabel{
1835 {
1836 testName: "Add valid label",
1837 expected: result{
1838 result: true,
1839 err: nil,
1840 },
1841 testLabel: testLabelIDForAdd,
1842 mockSQLQueries: []func() *sqlmock.ExpectedExec{
1843 func() *sqlmock.ExpectedExec {
1844 testRes := mock.ExpectExec(sqlquery.CreateHelmWorkloadLabels).WithArgs(helmWorkload.HelmEdgeID, testLabelIDForAdd).
1845 WillReturnResult(sqlmock.NewResult(1, 1))
1846 return testRes
1847 },
1848 },
1849 },
1850 {
1851 testName: "Add invalid label",
1852 expected: result{
1853 result: false,
1854 err: sqlErr,
1855 },
1856 testLabel: "",
1857 mockSQLQueries: []func() *sqlmock.ExpectedExec{
1858 func() *sqlmock.ExpectedExec {
1859 testRes := mock.ExpectExec(sqlquery.CreateHelmWorkloadLabels).WithArgs(helmWorkload.HelmEdgeID, "").
1860 WillReturnError(errMsg)
1861 return testRes
1862 },
1863 },
1864 },
1865 }
1866 for _, tc := range testAdd {
1867 for _, mockSQLFn := range tc.mockSQLQueries {
1868 mockSQLFn()
1869 }
1870 t.Run(tc.testName, func(t *testing.T) {
1871 res, err := service.AddWorkloadLabel(context.Background(), helmWorkload.HelmEdgeID, tc.testLabel)
1872 if err != nil {
1873 assert.Error(t, err)
1874 }
1875 assert.Equal(t, tc.expected.result, res)
1876 assert.Equal(t, tc.expected.err, err)
1877 })
1878 }
1879 }
1880
1881 func GetBannerByHelmEdgeID(t *testing.T) {
1882 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
1883 if err != nil {
1884 t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
1885 }
1886 defer db.Close()
1887
1888 expectedProjectID := projectID
1889 mock.ExpectQuery(sqlquery.GetBannerByHelmEdgeID).WithArgs(helmEdgeID).
1890 WillReturnRows(mock.NewRows([]string{"project_id", "banner_edge_id"}).
1891 AddRow(expectedProjectID, bannerEdgeID))
1892
1893 service := NewHelmService(appConfig, nil, nil, db, nil, nil)
1894 banner, err := service.GetBannerByHelmEdgeID(context.Background(), helmEdgeID)
1895 assert.NoError(t, err)
1896 assert.Equal(t, expectedProjectID, banner.ProjectID)
1897 assert.Equal(t, bannerEdgeID, banner.BannerEdgeID)
1898
1899 if err := mock.ExpectationsWereMet(); err != nil {
1900 t.Errorf("there were unfulfilled expectations: %s", err)
1901 }
1902 }
1903
1904 func getTestHelmReleaseWithStatus(name string, succeededStatus bool) *helmApi.HelmRelease {
1905 helmRelease := &helmApi.HelmRelease{
1906 TypeMeta: metav1.TypeMeta{
1907 APIVersion: helmApi.GroupVersion.String(),
1908 Kind: helmRelease,
1909 },
1910 ObjectMeta: metav1.ObjectMeta{
1911 Name: name,
1912 Namespace: ns,
1913 Labels: map[string]string{
1914 mapper.SecretManagerSecretLabel: helmSecret,
1915 },
1916 },
1917 Spec: helmApi.HelmReleaseSpec{
1918 Interval: metav1.Duration{
1919 Duration: time.Duration(2) * time.Minute,
1920 },
1921 ReleaseName: name,
1922 TargetNamespace: ns,
1923 Chart: &helmApi.HelmChartTemplate{
1924 Spec: helmApi.HelmChartTemplateSpec{
1925 Chart: chartName,
1926 Version: chartVersion,
1927 SourceRef: helmApi.CrossNamespaceObjectReference{
1928 Kind: helmRepoKind,
1929 Name: name,
1930 },
1931 },
1932 },
1933 Values: &apiextensionsv1.JSON{
1934 Raw: []byte(configValue),
1935 },
1936 Timeout: &metav1.Duration{
1937 Duration: time.Duration(15) * time.Minute,
1938 },
1939 },
1940 Status: helmApi.HelmReleaseStatus{
1941 ObservedGeneration: 0,
1942 History: helmApi.Snapshots{
1943 &helmApi.Snapshot{
1944 ChartVersion: chartVersion,
1945 },
1946 },
1947 },
1948 }
1949 if succeededStatus {
1950 condition := metav1.Condition{
1951 Type: "Ready",
1952 Status: "True",
1953 LastTransitionTime: metav1.Now(),
1954 Reason: "test reason",
1955 Message: "reconciliation successful",
1956 }
1957 helmRelease.Status.Conditions = append(helmRelease.Status.Conditions, condition)
1958 } else {
1959 condition := metav1.Condition{
1960 Type: helmApi.ReleasedCondition,
1961 Status: "False",
1962 LastTransitionTime: metav1.Now(),
1963 Reason: "test failure",
1964 Message: "install failed",
1965 }
1966 helmRelease.Status.Conditions = append(helmRelease.Status.Conditions, condition)
1967 }
1968 return helmRelease
1969 }
1970
1971 func getTestHelmRepository(name string) *helmRepositoryApi.HelmRepository {
1972 return &helmRepositoryApi.HelmRepository{
1973 TypeMeta: metav1.TypeMeta{
1974 APIVersion: helmRepositoryApi.GroupVersion.String(),
1975 Kind: helmRepoKind,
1976 },
1977 ObjectMeta: metav1.ObjectMeta{
1978 Name: name,
1979 Namespace: ns,
1980 CreationTimestamp: metav1.Now(),
1981 },
1982 Spec: helmRepositoryApi.HelmRepositorySpec{
1983 URL: helmRepoURL,
1984 SecretRef: &meta.LocalObjectReference{Name: helmSecret},
1985 Interval: metav1.Duration{Duration: 2 * time.Minute},
1986 },
1987 }
1988 }
1989
1990 func createHelmRepoClient(t *testing.T, mapping map[string][]byte) *httptest.Server {
1991 return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1992 assert.Equal(t, http.MethodGet, r.Method)
1993 mapping["/index.yaml"] = getHelmCharts(t, r.Host)
1994 mapping[".tgz"] = []byte(zippedChart)
1995 for url, response := range mapping {
1996 if strings.HasSuffix(r.URL.String(), url) {
1997 w.WriteHeader(200)
1998 _, err := w.Write(response)
1999 assert.NoError(t, err)
2000 return
2001 }
2002 }
2003 }))
2004 }
2005
2006 func getHelmPayload(bannerEdgeID, clusterEdgeID *string, name, configValues string, secrets ...string) model.HelmReleasePayload {
2007 return model.HelmReleasePayload{
2008 Name: name,
2009 Secret: helmSecret,
2010 HelmRepository: testHelmRepo,
2011 HelmChart: chartName,
2012 Version: chartVersion,
2013 BannerEdgeID: bannerEdgeID,
2014 ClusterEdgeID: clusterEdgeID,
2015 ConfigValues: &configValues,
2016 Namespace: ns,
2017 Secrets: secrets,
2018 InjectConfigmaps: []model.InjectableConfigmaps{model.InjectableConfigmapsEdgeInfo},
2019 }
2020 }
2021
2022 func getTestCluster(name string) *model.Cluster {
2023 return &model.Cluster{
2024 ProjectID: projectID,
2025 Name: name,
2026 ClusterEdgeID: clusterEdgeID,
2027 BannerEdgeID: bannerEdgeID,
2028 }
2029 }
2030
2031 func getSecretManagerResponse(name, project, URL, secretType string) *model.SecretManagerResponse {
2032
2033 var testKeyValues = []*model.KeyValuesOutput{
2034 {
2035 Key: constants.HelmUsername,
2036 Value: "test_username",
2037 },
2038 {
2039 Key: constants.HelmPassword,
2040 Value: "test_password",
2041 },
2042 {
2043 Key: constants.HelmURL,
2044 Value: URL,
2045 },
2046 {
2047 Key: constants.HelmRepoName,
2048 Value: name,
2049 },
2050 }
2051 return &model.SecretManagerResponse{
2052 Name: name,
2053 Project: project,
2054 Values: testKeyValues,
2055 Type: &secretType,
2056 }
2057 }
2058
2059 func getHelmCharts(t *testing.T, url string) []byte {
2060 hmr := getHelmManifestResponse(url)
2061 res, err := yaml.Marshal(&hmr)
2062 assert.NoError(t, err)
2063 return res
2064 }
2065
2066 func getHelmManifestResponse(host string) repo.IndexFile {
2067 return repo.IndexFile{
2068 APIVersion: "v1",
2069 Entries: map[string]repo.ChartVersions{
2070 chartName: {
2071 {
2072 Metadata: &chart.Metadata{
2073
2074 Description: "test description 1",
2075 Name: chartName,
2076 Version: chartVersion,
2077 AppVersion: "v1",
2078 Icon: "icon",
2079 Home: "home",
2080 Sources: []string{"source1", "source2"},
2081 Keywords: []string{"key1", "key2"},
2082 },
2083 URLs: []string{"http://" + host + "/charts.tgz", "http://" + host + "/charts.tgz"},
2084
2085 },
2086 {Metadata: &chart.Metadata{Description: "test description 2", Name: "test name 2", Version: "1.1"}},
2087 },
2088 "helm_chart2": {
2089 {Metadata: &chart.Metadata{Description: "test description 3", Name: "test name 3", Version: "2.0.0"}},
2090 },
2091 },
2092 }
2093 }
2094
2095 func getHelmConfigSchemaParams() model.HelmConfigSchemaParams {
2096 return model.HelmConfigSchemaParams{
2097 SecretName: helmSecret,
2098 BannerEdgeID: bannerEdgeID,
2099 ChartName: chartName,
2100 ChartVersion: chartVersion,
2101 }
2102 }
2103
2104 type GetSecretsFunc = func(ctx context.Context, name *string, owner, t *string, getValues bool, projectID string) ([]*model.SecretManagerResponse, error)
2105 type GetKubeResourceFunc = func(ctx context.Context, projectID string, cluster *model.Cluster, input model.LoqRequest) ([]string, error)
2106
2107 func createGCPServiceMock(t *testing.T, getSecret GetSecretsFunc) *mocks.MockGCPService {
2108 mock := gomock.NewController(t)
2109 service := mocks.NewMockGCPService(mock)
2110
2111 service.EXPECT().
2112 GetSecrets(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
2113 DoAndReturn(getSecret).AnyTimes()
2114 return service
2115 }
2116
2117 func createMockBQClient(t *testing.T, getKubeResource GetKubeResourceFunc) *mocks.MockBQClient {
2118 mock := gomock.NewController(t)
2119 service := mocks.NewMockBQClient(mock)
2120
2121 service.EXPECT().
2122 GetKubeResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
2123 DoAndReturn(getKubeResource).AnyTimes()
2124 return service
2125 }
2126
2127 func createChariotV2TestTopic(done chan bool, assertSubscriptionMessage func(message *pubSub.Message)) (option.ClientOption, error) {
2128 chariotPubsubClient, err := chariotClientApiTestutils.NewMockPubsubServer()
2129 if err != nil {
2130 return nil, err
2131 }
2132 _, err = chariotClientApiTestutils.CreateMockTopic(context.Background(), projectID, testChariotPubsubTopic, chariotPubsubClient)
2133 if err != nil {
2134 return nil, err
2135 }
2136
2137 go func() {
2138 err := chariotClientApiTestutils.CreateMockSubscription(context.Background(), done, projectID, testChariotPubsubTopic, testChariotPubsubSubscription, 20*time.Second, "", assertSubscriptionMessage, chariotPubsubClient)
2139 if err != nil {
2140 fmt.Println(err)
2141 }
2142 }()
2143 return chariotPubsubClient, nil
2144 }
2145
2146 func getTestHelmWorkloadQuery() helmTypes.HelmWorkloadQuery {
2147 defaultValue := ""
2148
2149 return helmTypes.HelmWorkloadQuery{
2150 ClusterEdgeID: testClusterEdgeID,
2151 BannerEdgeID: testBannerEdgeID,
2152 HelmEdgeID: "be8536ff-d463-4aff-8fa9-fe81fec1ddc1",
2153 Name: "test-helm-workload",
2154 Namespace: "nginx",
2155 HelmChart: "nginx",
2156 HelmRepository: "test-repo",
2157 HelmChartVersion: "2.3.1",
2158 HelmConfig: &defaultValue,
2159 InstalledBy: &defaultValue,
2160 WorkloadInstallationType: "mockInstallationType",
2161 CreatedAt: "mockCreatedAt",
2162 UpdatedAt: "mockUpdatedAt",
2163 HelmRepoSecret: "test-helm-workload",
2164 ProjectID: "test-org",
2165 }
2166 }
2167
View as plain text