From f7abe6c300be2ffb908c2d090798d2d44baca29f Mon Sep 17 00:00:00 2001 From: petruki <31597636+petruki@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:47:43 -0700 Subject: [PATCH] Added forceprune check to limit sync diff capabilities --- README.md | 8 ++++---- src/core/handler.go | 16 ++++++++++------ src/core/handler_test.go | 38 +++++++++++++++++++++++++++++++++++--- src/model/account.go | 5 +++++ 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index de8ed63..f45caab 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,11 @@ GitOps Domain Snapshot Orchestrator for Switcher API ![Switcher API: Cloud-based Feature Flag API](https://github.com/switcherapi/switcherapi-assets/blob/master/logo/switcherapi_grey.png) # About -**Switcher GitOps** is Domain Snapshot Orchestrator for Switcher API. It allows you to manage your feature flags and configurations in a GitOps manner. It is a simple and easy way to manage your feature flags and configurations in a versioned manner. +**Switcher GitOps** is used to orchestrate Domain Snapshots for Switcher API. It allows managing feature flags and configurations lifecycle. -# Features -- Manage Switchers with GitOps managed environment -- Auto Sync enables a fully integrated environment with Switcher API Management, Slack App and GitOps working simultaneously +- Manages Switchers with GitOps workflow (repository as a source of truth) +- Repository synchronization allows integrated tools such as Switcher API Management and Switcher Slack App to work in sync +- Flexible settings allow to define the best workflow for your ecosystem # Integrated tests diff --git a/src/core/handler.go b/src/core/handler.go index 9fb3fef..9388f62 100644 --- a/src/core/handler.go +++ b/src/core/handler.go @@ -74,10 +74,10 @@ func (c *CoreHandler) syncUp(account model.Account, repositoryData *model.Reposi // Update account status: Out of sync account.Domain.LastCommit = repositoryData.CommitHash account.Domain.LastDate = repositoryData.CommitDate - c.updateDomainStatus(account, model.StatusOutSync, "Syncing up...") + c.updateDomainStatus(account, model.StatusOutSync, model.MessageSyncingUp) // Check for changes - diff, snapshotApi, err := c.checkForChanges(account.Domain.ID, account.Environment, repositoryData.Content) + diff, snapshotApi, err := c.checkForChanges(account, repositoryData.Content) if err != nil { c.updateDomainStatus(account, model.StatusError, "Failed to check for changes - "+err.Error()) @@ -100,12 +100,12 @@ func (c *CoreHandler) syncUp(account model.Account, repositoryData *model.Reposi } // Update account status: Synced - c.updateDomainStatus(account, model.StatusSynced, "Synced successfully") + c.updateDomainStatus(account, model.StatusSynced, model.MessageSynced) } -func (c *CoreHandler) checkForChanges(domainId string, environment string, content string) (model.DiffResult, model.Snapshot, error) { +func (c *CoreHandler) checkForChanges(account model.Account, content string) (model.DiffResult, model.Snapshot, error) { // Get Snapshot from API - snapshotJsonFromApi, err := c.ApiService.FetchSnapshot(domainId, environment) + snapshotJsonFromApi, err := c.ApiService.FetchSnapshot(account.Domain.ID, account.Environment) if err != nil { return model.DiffResult{}, model.Snapshot{}, err @@ -122,7 +122,11 @@ func (c *CoreHandler) checkForChanges(domainId string, environment string, conte // Compare Snapshots and get diff diffNew := c.ComparatorService.CheckSnapshotDiff(fromRepo, fromApi, NEW) diffChanged := c.ComparatorService.CheckSnapshotDiff(fromApi, fromRepo, CHANGED) - diffDeleted := c.ComparatorService.CheckSnapshotDiff(fromApi, fromRepo, DELETED) + + var diffDeleted model.DiffResult + if account.Settings.ForcePrune { + diffDeleted = c.ComparatorService.CheckSnapshotDiff(fromApi, fromRepo, DELETED) + } return c.ComparatorService.MergeResults([]model.DiffResult{diffNew, diffChanged, diffDeleted}), snapshotApi.Snapshot, nil } diff --git a/src/core/handler_test.go b/src/core/handler_test.go index 722d801..b9c72ae 100644 --- a/src/core/handler_test.go +++ b/src/core/handler_test.go @@ -89,7 +89,40 @@ func TestStartAccountHandler(t *testing.T) { account := givenAccount() account.Domain.ID = "123-out-sync" + accountCreated, _ := coreHandler.AccountRepository.Create(&account) + + // Test + go coreHandler.StartAccountHandler(accountCreated.ID.Hex()) + + // Wait for goroutine to process + time.Sleep(1 * time.Second) + + // Assert + accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID) + assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status) + assert.Contains(t, accountFromDb.Domain.Message, model.MessageSynced) + assert.Equal(t, "123", accountFromDb.Domain.LastCommit) + assert.Equal(t, "1", accountFromDb.Domain.Version) + assert.NotEqual(t, "", accountFromDb.Domain.LastDate) + + tearDown() + }) + + t.Run("Should sync and prune successfully when repository is out of sync", func(t *testing.T) { + // Given + fakeGitService := NewFakeGitService() + fakeGitService.content = `{ + "domain": { + "group": [] + } + }` + fakeApiService := NewFakeApiService() + coreHandler = NewCoreHandler(coreHandler.AccountRepository, fakeGitService, fakeApiService, NewComparatorService()) + + account := givenAccount() + account.Domain.ID = "123-out-sync-prune" account.Domain.Version = "1" + account.Settings.ForcePrune = true accountCreated, _ := coreHandler.AccountRepository.Create(&account) // Test @@ -101,7 +134,7 @@ func TestStartAccountHandler(t *testing.T) { // Assert accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(accountCreated.Domain.ID) assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status) - assert.Contains(t, accountFromDb.Domain.Message, "Synced successfully") + assert.Contains(t, accountFromDb.Domain.Message, model.MessageSynced) assert.Equal(t, "123", accountFromDb.Domain.LastCommit) assert.Equal(t, "2", accountFromDb.Domain.Version) assert.NotEqual(t, "", accountFromDb.Domain.LastDate) @@ -119,7 +152,6 @@ func TestStartAccountHandler(t *testing.T) { account := givenAccount() account.Domain.ID = "123-newer-version" - account.Domain.Version = "0" accountCreated, _ := coreHandler.AccountRepository.Create(&account) // Test @@ -131,7 +163,7 @@ func TestStartAccountHandler(t *testing.T) { // Assert accountFromDb, _ := coreHandler.AccountRepository.FetchByAccountId(string(accountCreated.ID.Hex())) assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status) - assert.Contains(t, accountFromDb.Domain.Message, "Synced successfully") + assert.Contains(t, accountFromDb.Domain.Message, model.MessageSynced) assert.Equal(t, "111", accountFromDb.Domain.LastCommit) assert.Equal(t, "1", accountFromDb.Domain.Version) assert.NotEqual(t, "", accountFromDb.Domain.LastDate) diff --git a/src/model/account.go b/src/model/account.go index 7eaabdb..04e2099 100644 --- a/src/model/account.go +++ b/src/model/account.go @@ -13,6 +13,11 @@ const ( StatusError = "Error" ) +const ( + MessageSyncingUp = "Syncing up..." + MessageSynced = "Synced successfully" +) + const ( FilePath = "resources/" )