diff --git a/pkg/db/db.go b/pkg/db/db.go index cbceb7038..f0fcd8c1e 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -4881,10 +4881,6 @@ func (h *DBHandler) DBWriteEnvironment(ctx context.Context, tx *sql.Tx, environm if err != nil { return fmt.Errorf("could not write environment %s with config %v to environments table, error: %w", environmentName, environmentConfig, err) } - err = h.ForceOverviewRecalculation(ctx, tx) - if err != nil { - return fmt.Errorf("error while forcing overview recalculation, error: %w", err) - } return nil } diff --git a/pkg/db/overview.go b/pkg/db/overview.go index 34a40c84a..ecb5a9d64 100644 --- a/pkg/db/overview.go +++ b/pkg/db/overview.go @@ -250,6 +250,9 @@ func (h *DBHandler) UpdateOverviewRelease(ctx context.Context, transaction *sql. } app := getApplicationByName(latestOverview.Applications, release.App) if app == nil { + if release.Deleted { + return nil + } return fmt.Errorf("could not find application '%s' in overview", release.App) } apiRelease := &api.Release{ @@ -279,34 +282,11 @@ func (h *DBHandler) UpdateOverviewRelease(ctx context.Context, transaction *sql. app.Releases = append(app.Releases, apiRelease) } - if release.Metadata.UndeployVersion { //We need to force recalculation as we need to determine undeploySummary - err = h.ForceOverviewRecalculation(ctx, transaction) - } else { - err = h.WriteOverviewCache(ctx, transaction, latestOverview) + if release.Metadata.UndeployVersion { + app.UndeploySummary = deriveUndeploySummary(app.Name, latestOverview.EnvironmentGroups) } - if err != nil { - return err - } - return nil -} - -func (h *DBHandler) ForceOverviewRecalculation(ctx context.Context, transaction *sql.Tx) error { - latestOverview, err := h.ReadLatestOverviewCache(ctx, transaction) - if err != nil { - return err - } - if h.IsOverviewEmpty(latestOverview) { - return nil - } - emptyOverview := &api.GetOverviewResponse{ - Applications: map[string]*api.Application{}, - EnvironmentGroups: []*api.EnvironmentGroup{}, - GitRevision: "", - Branch: "", - ManifestRepoUrl: "", - } - err = h.WriteOverviewCache(ctx, transaction, emptyOverview) + err = h.WriteOverviewCache(ctx, transaction, latestOverview) if err != nil { return err } diff --git a/pkg/db/overview_test.go b/pkg/db/overview_test.go index 3a2ef4e6c..321ba5e20 100644 --- a/pkg/db/overview_test.go +++ b/pkg/db/overview_test.go @@ -1251,41 +1251,6 @@ func TestUpdateOverviewRelease(t *testing.T) { } } -func TestForceOverviewRecalculation(t *testing.T) { - tcs := []struct { - Name string - }{ - { - Name: "Check if ForceOverviewRecalculation creates an empty overview", - }, - } - - for _, tc := range tcs { - t.Run("ForceOverviewRecalculation", func(t *testing.T) { - t.Parallel() - ctx := testutil.MakeTestContext() - dbHandler := setupDB(t) - err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error { - err := dbHandler.ForceOverviewRecalculation(ctx, transaction) - if err != nil { - return err - } - latestOverview, err := dbHandler.ReadLatestOverviewCache(ctx, transaction) - if err != nil { - return err - } - if !dbHandler.IsOverviewEmpty(latestOverview) { - t.Fatalf("%s overview should be empty", tc.Name) - } - return nil - }) - if err != nil { - t.Fatal(err) - } - }) - } -} - func makeApps(apps ...*api.Environment_Application) map[string]*api.Environment_Application { var result map[string]*api.Environment_Application = map[string]*api.Environment_Application{} for i := 0; i < len(apps); i++ { diff --git a/services/cd-service/pkg/argocd/reposerver/reposerver_test.go b/services/cd-service/pkg/argocd/reposerver/reposerver_test.go index 35c56f532..9cabd7793 100644 --- a/services/cd-service/pkg/argocd/reposerver/reposerver_test.go +++ b/services/cd-service/pkg/argocd/reposerver/reposerver_test.go @@ -18,6 +18,7 @@ package reposerver import ( "context" + "database/sql" "fmt" "github.com/freiheit-com/kuberpult/pkg/db" "github.com/freiheit-com/kuberpult/pkg/testutil" @@ -641,6 +642,9 @@ func SetupRepositoryTestWithDBOptions(t *testing.T, writeEslOnly bool) (reposito if err != nil { t.Fatal(err) } + repo.State().DBHandler.InsertAppFun = func(ctx context.Context, transaction *sql.Tx, appName string, previousEslVersion db.EslVersion, stateChange db.AppStateChange, metaData db.DBAppMetaData) error { + return repo.State().DBInsertApplicationWithOverview(ctx, transaction, appName, previousEslVersion, stateChange, metaData) + } return repo, &repoCfg } diff --git a/services/cd-service/pkg/repository/repository.go b/services/cd-service/pkg/repository/repository.go index a1f0d1cbf..f82126289 100644 --- a/services/cd-service/pkg/repository/repository.go +++ b/services/cd-service/pkg/repository/repository.go @@ -2521,6 +2521,19 @@ func getEnvironmentByName(groups []*api.EnvironmentGroup, envNameToReturn string return nil } +func getEnvironmentInGroup(groups []*api.EnvironmentGroup, groupNameToReturn string, envNameToReturn string) *api.Environment { + for _, currentGroup := range groups { + if currentGroup.EnvironmentGroupName == groupNameToReturn { + for _, currentEnv := range currentGroup.Environments { + if currentEnv.Name == envNameToReturn { + return currentEnv + } + } + } + } + return nil +} + /* CalculateWarnings returns warnings for the User to be displayed in the UI. For really unusual configurations, these will be logged and not returned. @@ -2730,6 +2743,79 @@ func (s *State) UpdateOneAppEnvInOverview(ctx context.Context, transaction *sql. return &app, nil } +func (s *State) UpdateEnvironmentsInOverview(ctx context.Context, transaction *sql.Tx, result *api.GetOverviewResponse) error { + if envs, err := s.GetAllEnvironmentConfigs(ctx, transaction); err != nil { + return err + } else { + result.EnvironmentGroups = mapper.MapEnvironmentsToGroups(envs) + for envName, config := range envs { + var groupName = mapper.DeriveGroupName(config, envName) + var envInGroup = getEnvironmentInGroup(result.EnvironmentGroups, groupName, envName) + + argocd := &api.EnvironmentConfig_ArgoCD{ + SyncWindows: []*api.EnvironmentConfig_ArgoCD_SyncWindows{}, + Destination: &api.EnvironmentConfig_ArgoCD_Destination{ + Name: "", + Server: "", + Namespace: nil, + AppProjectNamespace: nil, + ApplicationNamespace: nil, + }, + AccessList: []*api.EnvironmentConfig_ArgoCD_AccessEntry{}, + ApplicationAnnotations: map[string]string{}, + IgnoreDifferences: []*api.EnvironmentConfig_ArgoCD_IgnoreDifferences{}, + SyncOptions: []string{}, + } + if config.ArgoCd != nil { + argocd = mapper.TransformArgocd(*config.ArgoCd) + } + env := api.Environment{ + DistanceToUpstream: 0, + Priority: api.Priority_PROD, + Name: envName, + Config: &api.EnvironmentConfig{ + Upstream: mapper.TransformUpstream(config.Upstream), + Argocd: argocd, + EnvironmentGroup: &groupName, + }, + Locks: map[string]*api.Lock{}, + Applications: map[string]*api.Environment_Application{}, + } + envInGroup.Config = env.Config + if locks, err := s.GetEnvironmentLocks(ctx, transaction, envName); err != nil { + return err + } else { + for lockId, lock := range locks { + env.Locks[lockId] = &api.Lock{ + Message: lock.Message, + LockId: lockId, + CreatedAt: timestamppb.New(lock.CreatedAt), + CreatedBy: &api.Actor{ + Name: lock.CreatedBy.Name, + Email: lock.CreatedBy.Email, + }, + } + } + envInGroup.Locks = env.Locks + } + + if apps, err := s.GetEnvironmentApplications(ctx, transaction, envName); err != nil { + return err + } else { + for _, appName := range apps { + app, err2 := s.UpdateOneAppEnvInOverview(ctx, transaction, appName, envName, &config, map[string]*int64{}) + if err2 != nil { + return err + } + env.Applications[appName] = app + } + } + envInGroup.Applications = env.Applications + } + } + return nil +} + func (s *State) GetAppsAndTeams() (map[string]string, error) { result, err := s.GetApplicationsFromFile() if err != nil { diff --git a/services/cd-service/pkg/repository/transformer.go b/services/cd-service/pkg/repository/transformer.go index 4b58acf86..d99ddb5ad 100644 --- a/services/cd-service/pkg/repository/transformer.go +++ b/services/cd-service/pkg/repository/transformer.go @@ -2748,6 +2748,27 @@ func (c *CreateEnvironment) Transform( return "", fmt.Errorf("unable to write to all_environments table, error: %w", err) } } + overview, err := state.DBHandler.ReadLatestOverviewCache(ctx, transaction) + if overview == nil { + overview = &api.GetOverviewResponse{ + Branch: "", + ManifestRepoUrl: "", + Applications: map[string]*api.Application{}, + EnvironmentGroups: []*api.EnvironmentGroup{}, + GitRevision: "0000000000000000000000000000000000000000", + } + } + if err != nil { + return "", fmt.Errorf("Unable to read overview cache, error: %w", err) + } + err = state.UpdateEnvironmentsInOverview(ctx, transaction, overview) + if err != nil { + return "", fmt.Errorf("Unable to udpate overview cache, error: %w", err) + } + err = state.DBHandler.WriteOverviewCache(ctx, transaction, overview) + if err != nil { + return "", fmt.Errorf("Unable to write overview cache, error: %w", err) + } } else { fs := state.Filesystem envDir := fs.Join("environments", c.Environment) diff --git a/services/cd-service/pkg/repository/transformer_db_test.go b/services/cd-service/pkg/repository/transformer_db_test.go index 9f0afaac1..e1e935868 100644 --- a/services/cd-service/pkg/repository/transformer_db_test.go +++ b/services/cd-service/pkg/repository/transformer_db_test.go @@ -26,6 +26,7 @@ import ( "testing" gotime "time" + "github.com/freiheit-com/kuberpult/pkg/api/v1" "github.com/freiheit-com/kuberpult/pkg/event" "github.com/freiheit-com/kuberpult/pkg/config" @@ -35,6 +36,7 @@ import ( "github.com/freiheit-com/kuberpult/pkg/time" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/protobuf/testing/protocmp" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/google/go-cmp/cmp" ) @@ -1602,6 +1604,223 @@ func TestCreateEnvironmentTransformer(t *testing.T) { } } +func TestCreateEnvironmentUpdatesOverview(t *testing.T) { + upstreamLatest := true + developmentEnvGroup := "development" + stagingEnvGroup := "staging" + type TestCase struct { + Name string + Transformers []Transformer + ExpectedOverviewCache *api.GetOverviewResponse + } + + testCases := []TestCase{ + { + Name: "create a single environment", + Transformers: []Transformer{ + &CreateEnvironment{ + Environment: "development", + Config: testutil.MakeEnvConfigLatest(nil), + }, + }, + ExpectedOverviewCache: &api.GetOverviewResponse{ + GitRevision: "0000000000000000000000000000000000000000", + EnvironmentGroups: []*api.EnvironmentGroup{ + &api.EnvironmentGroup{ + EnvironmentGroupName: "development", + Environments: []*api.Environment{ + { + Name: "development", + Config: &api.EnvironmentConfig{ + Upstream: &api.EnvironmentConfig_Upstream{ + Latest: &upstreamLatest, + }, + Argocd: &api.EnvironmentConfig_ArgoCD{ + Destination: &api.EnvironmentConfig_ArgoCD_Destination{}, + }, + EnvironmentGroup: &developmentEnvGroup, + }, + Priority: api.Priority_YOLO, + }, + }, + Priority: api.Priority_YOLO, + }, + }, + }, + }, + { + Name: "two environments in the same group", + Transformers: []Transformer{ + &CreateEnvironment{ + Environment: "development", + Config: testutil.MakeEnvConfigLatestWithGroup(nil, &developmentEnvGroup), + }, + &CreateEnvironment{ + Environment: "development2", + Config: testutil.MakeEnvConfigLatestWithGroup(nil, &developmentEnvGroup), + }, + }, + ExpectedOverviewCache: &api.GetOverviewResponse{ + GitRevision: "0000000000000000000000000000000000000000", + EnvironmentGroups: []*api.EnvironmentGroup{ + { + EnvironmentGroupName: "development", + Environments: []*api.Environment{ + { + Name: "development", + Config: &api.EnvironmentConfig{ + Upstream: &api.EnvironmentConfig_Upstream{ + Latest: &upstreamLatest, + }, + Argocd: &api.EnvironmentConfig_ArgoCD{ + Destination: &api.EnvironmentConfig_ArgoCD_Destination{}, + }, + EnvironmentGroup: &developmentEnvGroup, + }, + Priority: api.Priority_YOLO, + }, + { + Name: "development2", + Config: &api.EnvironmentConfig{ + Upstream: &api.EnvironmentConfig_Upstream{ + Latest: &upstreamLatest, + }, + Argocd: &api.EnvironmentConfig_ArgoCD{ + Destination: &api.EnvironmentConfig_ArgoCD_Destination{}, + }, + EnvironmentGroup: &developmentEnvGroup, + }, + Priority: api.Priority_YOLO, + }, + }, + Priority: api.Priority_YOLO, + }, + }, + }, + }, + { + Name: "create an environment, create an application, then create another environment", + Transformers: []Transformer{ + &CreateEnvironment{ + Environment: "development", + Config: testutil.MakeEnvConfigLatest(nil), + }, + &CreateApplicationVersion{ + Application: "app", + SourceCommitId: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + Manifests: map[string]string{ + "development": "some manifest", + }, + WriteCommitData: false, + Version: 1, + }, + &CreateEnvironment{ + Environment: "staging", + Config: testutil.MakeEnvConfigLatestWithGroup(nil, &stagingEnvGroup), + }, + }, + ExpectedOverviewCache: &api.GetOverviewResponse{ + GitRevision: "0000000000000000000000000000000000000000", + Applications: map[string]*api.Application{ + "app": &api.Application{ + Name: "app", + Releases: []*api.Release{ + { + Version: 1, + SourceCommitId: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + CreatedAt: timestamppb.Now(), + }, + }, + }, + }, + EnvironmentGroups: []*api.EnvironmentGroup{ + &api.EnvironmentGroup{ + EnvironmentGroupName: "development", + Environments: []*api.Environment{ + { + Name: "development", + Config: &api.EnvironmentConfig{ + Upstream: &api.EnvironmentConfig_Upstream{ + Latest: &upstreamLatest, + }, + Argocd: &api.EnvironmentConfig_ArgoCD{ + Destination: &api.EnvironmentConfig_ArgoCD_Destination{}, + }, + EnvironmentGroup: &developmentEnvGroup, + }, + Applications: map[string]*api.Environment_Application{ + "app": &api.Environment_Application{ + Name: "app", + DeploymentMetaData: &api.Environment_Application_DeploymentMetaData{ + DeployAuthor: "testmail@example.com", + DeployTime: timestamppb.Now().String(), + }, + Version: uint64(1), + }, + }, + Priority: api.Priority_YOLO, + }, + }, + Priority: api.Priority_YOLO, + }, + &api.EnvironmentGroup{ + EnvironmentGroupName: "staging", + Environments: []*api.Environment{ + { + Name: "staging", + Config: &api.EnvironmentConfig{ + Upstream: &api.EnvironmentConfig_Upstream{ + Latest: &upstreamLatest, + }, + Argocd: &api.EnvironmentConfig_ArgoCD{ + Destination: &api.EnvironmentConfig_ArgoCD_Destination{}, + }, + EnvironmentGroup: &stagingEnvGroup, + }, + Priority: api.Priority_YOLO, + Applications: map[string]*api.Environment_Application{ + "app": &api.Environment_Application{ + Name: "app", + DeploymentMetaData: &api.Environment_Application_DeploymentMetaData{}, + }, + }, + }, + }, + Priority: api.Priority_YOLO, + }, + }, + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.Name, func(t *testing.T) { + t.Parallel() + ctxWithTime := time.WithTimeNow(testutil.MakeTestContext(), timeNowOld) + repo := SetupRepositoryTestWithDB(t) + state := repo.State() + err := state.DBHandler.WithTransaction(ctxWithTime, false, func(ctx context.Context, transaction *sql.Tx) error { + _, _, _, transformerBatchErr := repo.ApplyTransformersInternal(ctx, transaction, tc.Transformers...) + if transformerBatchErr != nil { + return transformerBatchErr + } + overview, err := state.DBHandler.ReadLatestOverviewCache(ctx, transaction) + if err != nil { + return err + } + if diff := cmp.Diff(tc.ExpectedOverviewCache, overview, protocmp.Transform(), protocmp.IgnoreFields(&api.Release{}, "created_at"), protocmp.IgnoreFields(&api.Environment_Application_DeploymentMetaData{}, "deploy_time")); diff != "" { + t.Errorf("error mismatch (-want, +got):\n%s", diff) + } + return nil + }) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + }) + } +} + func TestEventGenerationFromTransformers(t *testing.T) { type TestCase struct { Name string @@ -1903,6 +2122,7 @@ func TestEvents(t *testing.T) { } func TestDeleteEnvFromAppWithDB(t *testing.T) { + appName := "app" setupTransformers := []Transformer{ &CreateEnvironment{ Environment: "env", @@ -1937,52 +2157,28 @@ func TestDeleteEnvFromAppWithDB(t *testing.T) { }, }, } - firstRelease := db.DBReleaseWithMetaData{ - EslVersion: 1, - ReleaseNumber: 10, - App: "app", - Manifests: db.DBReleaseManifests{ - Manifests: map[string]string{ - "env": "testenvmanifest", - "env2": "testenvmanifest2", - }, - }, - Metadata: db.DBReleaseMetaData{ - SourceAuthor: testAppName, - SourceMessage: testAppName, - SourceCommitId: testAppName, - DisplayVersion: testAppName, - }, - } - secondRelease := db.DBReleaseWithMetaData{ - EslVersion: 1, - ReleaseNumber: 11, - App: "app", - Manifests: db.DBReleaseManifests{ - Manifests: map[string]string{ - "env1": "testenvmanifest", - "env2": "testenvmanifest2", - }, - }, - Metadata: db.DBReleaseMetaData{ - SourceAuthor: testAppName, - SourceMessage: testAppName, - SourceCommitId: testAppName, - DisplayVersion: testAppName, - }, - } tcs := []struct { Name string - PrevReleases []db.DBReleaseWithMetaData Transforms []Transformer ExpectedManifests map[string]string }{ { - Name: "Simple Delete Env From App", - PrevReleases: []db.DBReleaseWithMetaData{firstRelease}, + Name: "Simple Delete Env From App", Transforms: []Transformer{ + &CreateApplicationVersion{ + Version: 10, + Application: appName, + Manifests: map[string]string{ + "env": "testenvmanifest", + "env2": "testenvmanifest2", + }, + SourceCommitId: "0000000000000000000000000000000000000000", + SourceAuthor: "testmail@example.com", + SourceMessage: "test", + DisplayVersion: "10", + }, &DeleteEnvFromApp{ - Application: firstRelease.App, + Application: appName, Environment: "env", }, }, @@ -1991,22 +2187,59 @@ func TestDeleteEnvFromAppWithDB(t *testing.T) { }, }, { - Name: "Delete Env that doesn't exist", - PrevReleases: []db.DBReleaseWithMetaData{firstRelease}, + Name: "Delete Env that doesn't exist", Transforms: []Transformer{ + &CreateApplicationVersion{ + Version: 10, + Application: appName, + Manifests: map[string]string{ + "env": "testenvmanifest", + "env2": "testenvmanifest2", + }, + SourceCommitId: "0000000000000000000000000000000000000000", + SourceAuthor: "testmail@example.com", + SourceMessage: "test", + DisplayVersion: "10", + }, &DeleteEnvFromApp{ - Application: firstRelease.App, + Application: appName, Environment: "env3", }, }, - ExpectedManifests: firstRelease.Manifests.Manifests, + ExpectedManifests: map[string]string{ + "env": "testenvmanifest", + "env2": "testenvmanifest2", + }, }, { - Name: "Multiple Manifests", - PrevReleases: []db.DBReleaseWithMetaData{firstRelease, secondRelease}, + Name: "Multiple Manifests", Transforms: []Transformer{ + &CreateApplicationVersion{ + Version: 10, + Application: appName, + Manifests: map[string]string{ + "env": "testenvmanifest", + "env2": "testenvmanifest2", + }, + SourceCommitId: "0000000000000000000000000000000000000000", + SourceAuthor: "testmail@example.com", + SourceMessage: "test", + DisplayVersion: "10", + }, + &CreateApplicationVersion{ + Version: 11, + Application: appName, + Manifests: map[string]string{ + "env": "testenvmanifest", + "env2": "testenvmanifest2", + }, + SourceCommitId: "0000000000000000000000000000000000000000", + SourceAuthor: "testmail@example.com", + SourceMessage: "test", + DisplayVersion: "10", + }, &DeleteEnvFromApp{ - Application: firstRelease.App, + Application: appName, Environment: "env", }, }, @@ -2026,35 +2259,29 @@ func TestDeleteEnvFromAppWithDB(t *testing.T) { if err != nil { return err } - for _, release := range tc.PrevReleases { - repo.State().DBHandler.DBInsertRelease(ctx, transaction, release, 0) - } _, state, _, err := repo.ApplyTransformersInternal(ctx, transaction, tc.Transforms...) if err != nil { return fmt.Errorf("error: %v", err) } - releases, err2 := state.DBHandler.DBSelectReleasesByApp(ctx, transaction, firstRelease.App, false, true) + releases, err2 := state.DBHandler.DBSelectReleasesByApp(ctx, transaction, appName, false, true) if err2 != nil { return fmt.Errorf("error retrieving release: %v", err2) } for _, release := range releases { - if diff := cmp.Diff(firstRelease.EslVersion+1, release.EslVersion); diff != "" { - return fmt.Errorf("error mismatch ReleaseNumber - want, +got:\n%s", diff) - } for env, manifest := range tc.ExpectedManifests { if diff := cmp.Diff(manifest, release.Manifests.Manifests[env]); diff != "" { return fmt.Errorf("error mismatch Manifests - want, +got:\n%s", diff) } } } - environment, err2 := state.DBHandler.DBSelectEnvironment(ctx, transaction, tc.Transforms[0].(*DeleteEnvFromApp).Environment) + environment, err2 := state.DBHandler.DBSelectEnvironment(ctx, transaction, tc.Transforms[len(tc.Transforms)-1].(*DeleteEnvFromApp).Environment) if err2 != nil { return err2 } if environment != nil { for _, envApp := range environment.Applications { - if envApp == firstRelease.App { - return fmt.Errorf("Expected app %s to be deleted from environment %s", firstRelease.App, environment.Name) + if envApp == appName { + return fmt.Errorf("Expected app %s to be deleted from environment %s", appName, environment.Name) } } } diff --git a/services/cd-service/pkg/repository/transformer_test.go b/services/cd-service/pkg/repository/transformer_test.go index 7392ee6f5..385142846 100644 --- a/services/cd-service/pkg/repository/transformer_test.go +++ b/services/cd-service/pkg/repository/transformer_test.go @@ -7096,6 +7096,9 @@ func SetupRepositoryTestWithDBOptions(t *testing.T, writeEslOnly bool) Repositor if err != nil { t.Fatal(err) } + repo.State().DBHandler.InsertAppFun = func(ctx context.Context, transaction *sql.Tx, appName string, previousEslVersion db.EslVersion, stateChange db.AppStateChange, metaData db.DBAppMetaData) error { + return repo.State().DBInsertApplicationWithOverview(ctx, transaction, appName, previousEslVersion, stateChange, metaData) + } return repo } func SetupRepositoryTestWithoutDB(t *testing.T, repositoryConfig *RepositoryConfig) Repository { diff --git a/services/cd-service/pkg/service/batch_test.go b/services/cd-service/pkg/service/batch_test.go index 59db0efc7..a48897745 100644 --- a/services/cd-service/pkg/service/batch_test.go +++ b/services/cd-service/pkg/service/batch_test.go @@ -678,6 +678,12 @@ func setupRepositoryTestWithDB(t *testing.T, dbConfig *db.DBConfig) (repository. if err != nil { t.Fatal(err) } + + if dbConfig != nil { + repo.State().DBHandler.InsertAppFun = func(ctx context.Context, transaction *sql.Tx, appName string, previousEslVersion db.EslVersion, stateChange db.AppStateChange, metaData db.DBAppMetaData) error { + return repo.State().DBInsertApplicationWithOverview(ctx, transaction, appName, previousEslVersion, stateChange, metaData) + } + } return repo, nil } diff --git a/services/cd-service/pkg/service/overview.go b/services/cd-service/pkg/service/overview.go index 167587f56..3ae118dc8 100644 --- a/services/cd-service/pkg/service/overview.go +++ b/services/cd-service/pkg/service/overview.go @@ -21,7 +21,6 @@ import ( "database/sql" "errors" "fmt" - "github.com/freiheit-com/kuberpult/pkg/mapper" "sync" "sync/atomic" @@ -32,7 +31,6 @@ import ( git "github.com/libgit2/git2go/v34" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/timestamppb" api "github.com/freiheit-com/kuberpult/pkg/api/v1" "github.com/freiheit-com/kuberpult/pkg/db" @@ -129,61 +127,9 @@ func (o *OverviewServiceServer) getOverview( } result.ManifestRepoUrl = o.RepositoryConfig.URL result.Branch = o.RepositoryConfig.Branch - if envs, err := s.GetAllEnvironmentConfigs(ctx, transaction); err != nil { - return nil, grpc.InternalError(ctx, err) - } else { - result.EnvironmentGroups = mapper.MapEnvironmentsToGroups(envs) - for envName, config := range envs { - var groupName = mapper.DeriveGroupName(config, envName) - var envInGroup = getEnvironmentInGroup(result.EnvironmentGroups, groupName, envName) - //exhaustruct:ignore - argocd := &api.EnvironmentConfig_ArgoCD{} - if config.ArgoCd != nil { - argocd = mapper.TransformArgocd(*config.ArgoCd) - } - env := api.Environment{ - DistanceToUpstream: 0, - Priority: api.Priority_PROD, - Name: envName, - Config: &api.EnvironmentConfig{ - Upstream: mapper.TransformUpstream(config.Upstream), - Argocd: argocd, - EnvironmentGroup: &groupName, - }, - Locks: map[string]*api.Lock{}, - Applications: map[string]*api.Environment_Application{}, - } - envInGroup.Config = env.Config - if locks, err := s.GetEnvironmentLocks(ctx, transaction, envName); err != nil { - return nil, err - } else { - for lockId, lock := range locks { - env.Locks[lockId] = &api.Lock{ - Message: lock.Message, - LockId: lockId, - CreatedAt: timestamppb.New(lock.CreatedAt), - CreatedBy: &api.Actor{ - Name: lock.CreatedBy.Name, - Email: lock.CreatedBy.Email, - }, - } - } - envInGroup.Locks = env.Locks - } - - if apps, err := s.GetEnvironmentApplications(ctx, transaction, envName); err != nil { - return nil, err - } else { - for _, appName := range apps { - app, err2 := s.UpdateOneAppEnvInOverview(ctx, transaction, appName, envName, &config, map[string]*int64{}) - if err2 != nil { - return nil, err2 - } - env.Applications[appName] = app - } - } - envInGroup.Applications = env.Applications - } + err := s.UpdateEnvironmentsInOverview(ctx, transaction, &result) + if err != nil { + return nil, err } if apps, err := s.GetApplications(ctx, transaction); err != nil { return nil, err @@ -200,19 +146,6 @@ func (o *OverviewServiceServer) getOverview( return &result, nil } -func getEnvironmentInGroup(groups []*api.EnvironmentGroup, groupNameToReturn string, envNameToReturn string) *api.Environment { - for _, currentGroup := range groups { - if currentGroup.EnvironmentGroupName == groupNameToReturn { - for _, currentEnv := range currentGroup.Environments { - if currentEnv.Name == envNameToReturn { - return currentEnv - } - } - } - } - return nil -} - func (o *OverviewServiceServer) StreamOverview(in *api.GetOverviewRequest, stream api.OverviewService_StreamOverviewServer) error { ch, unsubscribe := o.subscribe() diff --git a/services/cd-service/pkg/service/overview_test.go b/services/cd-service/pkg/service/overview_test.go index c36c23c10..4aa499474 100644 --- a/services/cd-service/pkg/service/overview_test.go +++ b/services/cd-service/pkg/service/overview_test.go @@ -30,8 +30,8 @@ import ( "github.com/freiheit-com/kuberpult/pkg/db" "github.com/freiheit-com/kuberpult/services/cd-service/pkg/repository" "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/grpc" + "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -443,7 +443,9 @@ func TestOverviewService(t *testing.T) { Upstream: &api.EnvironmentConfig_Upstream{ Latest: &upstreamLatest, }, - Argocd: &api.EnvironmentConfig_ArgoCD{}, + Argocd: &api.EnvironmentConfig_ArgoCD{ + Destination: &api.EnvironmentConfig_ArgoCD_Destination{}, + }, EnvironmentGroup: &dev, }, Applications: map[string]*api.Environment_Application{ @@ -475,6 +477,16 @@ func TestOverviewService(t *testing.T) { PrNumber: "678", CreatedAt: ×tamppb.Timestamp{Seconds: 1, Nanos: 1}, }, + { + Version: 2, + SourceCommitId: "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", + SourceAuthor: "example ", + SourceMessage: "changed something (#678)", + PrNumber: "678", + IsMinor: true, + IsPrepublish: true, + CreatedAt: ×tamppb.Timestamp{Seconds: 1, Nanos: 1}, + }, }, Team: "team-123", }, @@ -569,8 +581,8 @@ func TestOverviewService(t *testing.T) { if test.Name != "test" { t.Errorf("test applications name is not test but %q", test.Name) } - if len(test.Releases) != 1 { - t.Errorf("expected one release, got %#v", test.Releases) + if len(test.Releases) != 2 { + t.Errorf("expected two releases, got %#v", test.Releases) } if test.Releases[0].Version != 1 { t.Errorf("expected test release version to be 1, but got %d", test.Releases[0].Version) @@ -635,12 +647,8 @@ func TestOverviewService(t *testing.T) { if err != nil { return err } - cachedResponse.EnvironmentGroups[0].Environments[0].Applications["test"].DeploymentMetaData.DeployTime = "1" - cachedResponse.Applications["test"].Releases[0].CreatedAt.Seconds = 1 - cachedResponse.Applications["test"].Releases[0].CreatedAt.Nanos = 1 cachedResponse.GitRevision = "0" - opts := cmpopts.IgnoreUnexported(api.GetOverviewResponse{}, api.EnvironmentGroup{}, api.Environment{}, api.Application{}, api.Release{}, timestamppb.Timestamp{}, api.EnvironmentConfig{}, api.EnvironmentConfig_Upstream{}, api.Environment_Application{}, api.Environment_Application_DeploymentMetaData{}, api.EnvironmentConfig_ArgoCD{}) - if diff := cmp.Diff(tc.ExpectedCachedOverview, cachedResponse, opts); diff != "" { + if diff := cmp.Diff(tc.ExpectedCachedOverview, cachedResponse, protocmp.Transform(), protocmp.IgnoreFields(&api.Release{}, "created_at"), protocmp.IgnoreFields(&api.Environment_Application_DeploymentMetaData{}, "deploy_time")); diff != "" { t.Errorf("latest overview cache mismatch (-want +got):\n%s", diff) } return nil