diff --git a/splitio/admin/admin.go b/splitio/admin/admin.go index 47c9f87c..b08f1eaa 100644 --- a/splitio/admin/admin.go +++ b/splitio/admin/admin.go @@ -41,6 +41,7 @@ type Options struct { FullConfig interface{} FlagSpecVersion string LargeSegmentVersion string + Hash string } type AdminServer struct { @@ -96,7 +97,7 @@ func NewServer(options *Options) (*AdminServer, error) { observabilityController.Register(admin) if options.Snapshotter != nil { - snapshotController := controllers.NewSnapshotController(options.Logger, options.Snapshotter, options.FlagSpecVersion) + snapshotController := controllers.NewSnapshotController(options.Logger, options.Snapshotter, options.Hash) snapshotController.Register(admin) } diff --git a/splitio/admin/controllers/snapshot.go b/splitio/admin/controllers/snapshot.go index 657907b3..b5d451a8 100644 --- a/splitio/admin/controllers/snapshot.go +++ b/splitio/admin/controllers/snapshot.go @@ -14,14 +14,14 @@ import ( // SnapshotController bundles endpoints associated to snapshot management type SnapshotController struct { - logger logging.LoggerInterface - db storage.Snapshotter - version string + logger logging.LoggerInterface + db storage.Snapshotter + hash string } // NewSnapshotController constructs a new snapshot controller -func NewSnapshotController(logger logging.LoggerInterface, db storage.Snapshotter, version string) *SnapshotController { - return &SnapshotController{logger: logger, db: db, version: version} +func NewSnapshotController(logger logging.LoggerInterface, db storage.Snapshotter, hash string) *SnapshotController { + return &SnapshotController{logger: logger, db: db, hash: hash} } // Register mounts the endpoints int he provided router @@ -39,7 +39,7 @@ func (c *SnapshotController) downloadSnapshot(ctx *gin.Context) { return } - s, err := snapshot.New(snapshot.Metadata{Version: 1, Storage: snapshot.StorageBoltDB, SpecVersion: c.version}, b) + s, err := snapshot.New(snapshot.Metadata{Version: 1, Storage: snapshot.StorageBoltDB, Hash: c.hash}, b) if err != nil { c.logger.Error("error building snapshot: ", err) ctx.JSON(http.StatusInternalServerError, gin.H{"error": "error building snapshot"}) diff --git a/splitio/admin/controllers/snapshot_test.go b/splitio/admin/controllers/snapshot_test.go index 77394a7e..fc5a9e0b 100644 --- a/splitio/admin/controllers/snapshot_test.go +++ b/splitio/admin/controllers/snapshot_test.go @@ -29,7 +29,7 @@ func TestDownloadProxySnapshot(t *testing.T) { dbInstance, err := persistent.NewBoltWrapper(tmpDataFile, nil) assert.Nil(t, err) - ctrl := NewSnapshotController(logging.NewLogger(nil), dbInstance, "1.3") + ctrl := NewSnapshotController(logging.NewLogger(nil), dbInstance, "123456") resp := httptest.NewRecorder() ctx, router := gin.CreateTestContext(resp) @@ -46,7 +46,7 @@ func TestDownloadProxySnapshot(t *testing.T) { assert.Equal(t, uint64(1), snapRes.Meta().Version) assert.Equal(t, uint64(1), snapRes.Meta().Storage) - assert.Equal(t, "1.3", snapRes.Meta().SpecVersion) + assert.Equal(t, "123456", snapRes.Meta().Hash) dat, err := snap.Data() assert.Nil(t, err) diff --git a/splitio/commitversion.go b/splitio/commitversion.go index 96bdc507..f7990321 100644 --- a/splitio/commitversion.go +++ b/splitio/commitversion.go @@ -5,4 +5,4 @@ This file is created automatically, please do not edit */ // CommitVersion is the version of the last commit previous to release -const CommitVersion = "88290d5" +const CommitVersion = "829fcf8" diff --git a/splitio/common/snapshot/snapshot.go b/splitio/common/snapshot/snapshot.go index 20e4e15a..235bfb52 100644 --- a/splitio/common/snapshot/snapshot.go +++ b/splitio/common/snapshot/snapshot.go @@ -39,9 +39,9 @@ var ErrMetadataRead = errors.New("snapshot metadata cannot be decoded") // Metadata represents the Snapshot metadata object type Metadata struct { - Version uint64 - Storage uint64 - SpecVersion string + Version uint64 + Storage uint64 + Hash string } // Snapshot represents a snapshot struct with metadata and data diff --git a/splitio/proxy/initialization.go b/splitio/proxy/initialization.go index f4628bd2..4fbd890e 100644 --- a/splitio/proxy/initialization.go +++ b/splitio/proxy/initialization.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/url" + "strconv" "strings" "time" @@ -57,8 +58,9 @@ func Start(logger logging.LoggerInterface, cfg *pconf.Main) error { return fmt.Errorf("error writing temporary snapshot file: %w", err) } - if snap.Meta().SpecVersion != cfg.FlagSpecVersion { - return common.NewInitError(fmt.Errorf("snapshot spec version %s does not match config spec version %s", snap.Meta().SpecVersion, cfg.FlagSpecVersion), common.ExitErrorDB) + currentHash := util.HashAPIKey(cfg.Apikey + cfg.FlagSpecVersion + strings.Join(cfg.FlagSetsFilter, "::")) + if snap.Meta().Hash != strconv.Itoa(int(currentHash)) { + return common.NewInitError(errors.New("snapshot cfg (apikey, version, flagsets) does not match the provided one"), common.ExitErrorDB) } logger.Debug("Database created from snapshot at", dbpath) @@ -221,6 +223,7 @@ func Start(logger logging.LoggerInterface, cfg *pconf.Main) error { // --------------------------- ADMIN DASHBOARD ------------------------------ cfgForAdmin := *cfg + hash := util.HashAPIKey(cfgForAdmin.Apikey + cfg.FlagSpecVersion + strings.Join(cfg.FlagSetsFilter, "::")) cfgForAdmin.Apikey = logging.ObfuscateAPIKey(cfgForAdmin.Apikey) adminTLSConfig, err := util.TLSConfigForServer(&cfg.Admin.TLS) @@ -244,6 +247,7 @@ func Start(logger logging.LoggerInterface, cfg *pconf.Main) error { FullConfig: cfgForAdmin, TLS: adminTLSConfig, FlagSpecVersion: cfg.FlagSpecVersion, + Hash: strconv.Itoa(int(hash)), }) if err != nil { return common.NewInitError(fmt.Errorf("error starting admin server: %w", err), common.ExitAdminError)