2
0
Эх сурвалжийг харах

add migration script for enable cluster preview envs

Mohammed Nafees 3 жил өмнө
parent
commit
1fa1f7c157

+ 42 - 0
cmd/migrate/enable_cluster_preview_envs/enable.go

@@ -0,0 +1,42 @@
+package enable_cluster_preview_envs
+
+import (
+	"github.com/porter-dev/porter/internal/models"
+	lr "github.com/porter-dev/porter/pkg/logger"
+	_gorm "gorm.io/gorm"
+)
+
+func EnableClusterPreviewEnvs(db *_gorm.DB, logger *lr.Logger) error {
+	logger.Info().Msg("starting to enable preview envs for existing clusters whose parent projects have preview envs enabled")
+
+	var clusters []*models.Cluster
+
+	if err := db.Find(&clusters).Error; err != nil {
+		logger.Error().Msgf("failed to get clusters: %v", err)
+		return err
+	}
+
+	for _, c := range clusters {
+		project := &models.Project{}
+
+		if err := db.Model(project).Where("id = ?", c.ProjectID).First(project).Error; err != nil {
+			logger.Error().Msgf("failed to get project for cluster with ID %d: %v", c.ID, err)
+			return err
+		}
+
+		if project.PreviewEnvsEnabled {
+			c.PreviewEnvsEnabled = true
+
+			if err := db.Save(c).Error; err != nil {
+				logger.Error().Msgf("failed to update cluster with ID %d: %v", c.ID, err)
+				return err
+			}
+
+			logger.Info().Msgf("enabled preview envs for cluster with ID %d", c.ID)
+		}
+	}
+
+	logger.Info().Msg("cluster preview envs migration completed")
+
+	return nil
+}

+ 73 - 0
cmd/migrate/enable_cluster_preview_envs/enable_test.go

@@ -0,0 +1,73 @@
+package enable_cluster_preview_envs
+
+import (
+	"testing"
+
+	lr "github.com/porter-dev/porter/pkg/logger"
+)
+
+func TestEnableForProjectEnabled(t *testing.T) {
+	logger := lr.NewConsole(true)
+
+	tester := &tester{
+		dbFileName: "./porter_cluster_preview_envs_enabled.db",
+	}
+
+	setupTestEnv(tester, t)
+
+	defer cleanup(tester, t)
+
+	initProjectPreviewEnabled(tester, t)
+	initCluster(tester, t)
+
+	err := EnableClusterPreviewEnvs(tester.DB, logger)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+		return
+	}
+
+	cluster, err := tester.repo.Cluster().ReadCluster(1, 1)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+		return
+	}
+
+	if !cluster.PreviewEnvsEnabled {
+		t.Fatalf("expected preview envs to be enabled, got disabled")
+	}
+}
+
+func TestEnableForProjectDisabled(t *testing.T) {
+	logger := lr.NewConsole(true)
+
+	tester := &tester{
+		dbFileName: "./porter_cluster_preview_envs_disabled.db",
+	}
+
+	setupTestEnv(tester, t)
+
+	defer cleanup(tester, t)
+
+	initProjectPreviewDisabled(tester, t)
+	initCluster(tester, t)
+
+	err := EnableClusterPreviewEnvs(tester.DB, logger)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+		return
+	}
+
+	cluster, err := tester.repo.Cluster().ReadCluster(1, 1)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+		return
+	}
+
+	if cluster.PreviewEnvsEnabled {
+		t.Fatalf("expected preview envs to be disabled, got enabled")
+	}
+}

+ 182 - 0
cmd/migrate/enable_cluster_preview_envs/helpers_test.go

@@ -0,0 +1,182 @@
+package enable_cluster_preview_envs
+
+import (
+	"os"
+	"testing"
+	"time"
+
+	"github.com/porter-dev/porter/api/server/shared/config/env"
+	"github.com/porter-dev/porter/internal/adapter"
+	"github.com/porter-dev/porter/internal/models"
+	ints "github.com/porter-dev/porter/internal/models/integrations"
+	"github.com/porter-dev/porter/internal/repository"
+	"github.com/porter-dev/porter/internal/repository/gorm"
+	_gorm "gorm.io/gorm"
+)
+
+type tester struct {
+	Key *[32]byte
+	DB  *_gorm.DB
+
+	repo       repository.Repository
+	dbFileName string
+	key        *[32]byte
+
+	initUsers    []*models.User
+	initProjects []*models.Project
+	initClusters []*models.Cluster
+	initKIs      []*ints.KubeIntegration
+}
+
+func setupTestEnv(tester *tester, t *testing.T) {
+	t.Helper()
+
+	db, err := adapter.New(&env.DBConf{
+		EncryptionKey: "__random_strong_encryption_key__",
+		SQLLite:       true,
+		SQLLitePath:   tester.dbFileName,
+	})
+
+	if err != nil {
+		t.Fatalf("%\n", err)
+	}
+
+	err = db.AutoMigrate(
+		&models.Project{},
+		&models.User{},
+		&models.Cluster{},
+		&ints.KubeIntegration{},
+		&ints.ClusterTokenCache{},
+	)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+	}
+
+	var key [32]byte
+
+	for i, b := range []byte("__random_strong_encryption_key__") {
+		key[i] = b
+	}
+
+	tester.key = &key
+	tester.Key = &key
+	tester.DB = db
+
+	tester.repo = gorm.NewRepository(db, &key, nil)
+}
+
+func cleanup(tester *tester, t *testing.T) {
+	t.Helper()
+
+	// remove the created file file
+	os.Remove(tester.dbFileName)
+}
+
+func initUser(tester *tester, t *testing.T) {
+	t.Helper()
+
+	user := &models.User{
+		Email:    "example@example.com",
+		Password: "hello1234",
+	}
+
+	user, err := tester.repo.User().CreateUser(user)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+	}
+
+	tester.initUsers = append(tester.initUsers, user)
+}
+
+func initCluster(tester *tester, t *testing.T) {
+	t.Helper()
+
+	if len(tester.initKIs) == 0 {
+		initKubeIntegration(tester, t)
+	}
+
+	cluster := &models.Cluster{
+		ProjectID:                tester.initProjects[0].ID,
+		Name:                     "cluster-test",
+		Server:                   "https://localhost",
+		KubeIntegrationID:        tester.initKIs[0].ID,
+		CertificateAuthorityData: []byte("-----BEGIN"),
+		TokenCache: ints.ClusterTokenCache{
+			TokenCache: ints.TokenCache{
+				Token:  []byte("token-1"),
+				Expiry: time.Now().Add(-1 * time.Hour),
+			},
+		},
+	}
+
+	cluster, err := tester.repo.Cluster().CreateCluster(cluster)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+	}
+
+	tester.initClusters = append(tester.initClusters, cluster)
+}
+
+func initProjectPreviewEnabled(tester *tester, t *testing.T) {
+	t.Helper()
+
+	proj := &models.Project{
+		Name:               "project-test",
+		PreviewEnvsEnabled: true,
+	}
+
+	proj, err := tester.repo.Project().CreateProject(proj)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+	}
+
+	tester.initProjects = append(tester.initProjects, proj)
+}
+
+func initProjectPreviewDisabled(tester *tester, t *testing.T) {
+	t.Helper()
+
+	proj := &models.Project{
+		Name: "project-test",
+	}
+
+	proj, err := tester.repo.Project().CreateProject(proj)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+	}
+
+	tester.initProjects = append(tester.initProjects, proj)
+}
+
+func initKubeIntegration(tester *tester, t *testing.T) {
+	t.Helper()
+
+	if len(tester.initUsers) == 0 {
+		initUser(tester, t)
+	}
+
+	ki := &ints.KubeIntegration{
+		Mechanism:             ints.KubeLocal,
+		ProjectID:             tester.initProjects[0].ID,
+		UserID:                tester.initUsers[0].ID,
+		Kubeconfig:            []byte("current-context: testing\n"),
+		ClientCertificateData: []byte("clientcertdata"),
+		ClientKeyData:         []byte("clientkeydata"),
+		Token:                 []byte("token"),
+		Username:              []byte("username"),
+		Password:              []byte("password"),
+	}
+
+	ki, err := tester.repo.KubeIntegration().CreateKubeIntegration(ki)
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+	}
+
+	tester.initKIs = append(tester.initKIs, ki)
+}

+ 28 - 0
cmd/migrate/main.go

@@ -4,6 +4,7 @@ import (
 	"log"
 
 	"github.com/porter-dev/porter/api/server/shared/config/envloader"
+	"github.com/porter-dev/porter/cmd/migrate/enable_cluster_preview_envs"
 	"github.com/porter-dev/porter/cmd/migrate/keyrotate"
 	"github.com/porter-dev/porter/cmd/migrate/populate_source_config_display_name"
 
@@ -70,6 +71,14 @@ func main() {
 		}
 	}
 
+	if shouldEnableClusterPreviewEnvs() {
+		err := enable_cluster_preview_envs.EnableClusterPreviewEnvs(db, logger)
+
+		if err != nil {
+			logger.Fatal().Err(err).Msg("failed to enable cluster preview envs")
+		}
+	}
+
 	if err := InstanceMigrate(db, envConf.DBConf); err != nil {
 		logger.Fatal().Err(err).Msg("vault migration failed")
 	}
@@ -111,3 +120,22 @@ func shouldPopulateSourceConfigDisplayName() bool {
 
 	return c.PopulateSourceConfigDisplayName
 }
+
+type EnableClusterPreviewEnvsConf struct {
+	// we add a dummy field to avoid empty struct issue with envdecode
+	DummyField string `env:"ASDF,default=asdf"`
+
+	// if true, will mark all clusters to have preview envs enabled whose parent project has it enabled
+	EnableClusterPreviewEnvs bool `env:"ENABLE_CLUSTER_PREVIEW_ENVS"`
+}
+
+func shouldEnableClusterPreviewEnvs() bool {
+	var c EnableClusterPreviewEnvsConf
+
+	if err := envdecode.StrictDecode(&c); err != nil {
+		log.Fatalf("Failed to decode migration conf: %s", err)
+		return false
+	}
+
+	return c.EnableClusterPreviewEnvs
+}