Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update state storage which is identified by project and workspace #1044

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Backend interface {
WorkspaceStorage() (workspace.Storage, error)

// StateStorage returns the state storage.
StateStorage(project, stack, workspace string) state.Storage
StateStorage(project, workspace string) state.Storage
}

// NewBackend creates the Backend with the configuration set in the Kusion configuration file, where the input
Expand Down
4 changes: 2 additions & 2 deletions pkg/backend/storages/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ func NewLocalStorage(config *v1.BackendLocalConfig) *LocalStorage {
return &LocalStorage{path: config.Path}
}

func (s *LocalStorage) StateStorage(project, stack, workspace string) state.Storage {
return statestorages.NewLocalStorage(statestorages.GenStateFilePath(s.path, project, stack, workspace))
func (s *LocalStorage) StateStorage(project, workspace string) state.Storage {
return statestorages.NewLocalStorage(statestorages.GenStateFilePath(s.path, project, workspace))
}

func (s *LocalStorage) WorkspaceStorage() (workspace.Storage, error) {
Expand Down
13 changes: 6 additions & 7 deletions pkg/backend/storages/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,27 @@ func TestNewLocalStorage(t *testing.T) {

func TestLocalStorage_StateStorage(t *testing.T) {
testcases := []struct {
name string
localStorage *LocalStorage
project, stack, workspace string
stateStorage state.Storage
name string
localStorage *LocalStorage
project, workspace string
stateStorage state.Storage
}{
{
name: "state storage from local backend",
localStorage: &LocalStorage{
path: "kusion",
},
project: "wordpress",
stack: "dev",
workspace: "dev",
stateStorage: statestorages.NewLocalStorage(
filepath.Join("kusion", "states", "wordpress", "dev", "dev", "state.yaml"),
filepath.Join("kusion", "states", "wordpress", "dev", "state.yaml"),
),
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
stateStorage := tc.localStorage.StateStorage(tc.project, tc.stack, tc.workspace)
stateStorage := tc.localStorage.StateStorage(tc.project, tc.workspace)
assert.Equal(t, tc.stateStorage, stateStorage)
})
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/backend/storages/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ func NewMysqlStorage(config *v1.BackendMysqlConfig) (*MysqlStorage, error) {
return &MysqlStorage{db: db}, nil
}

func (s *MysqlStorage) StateStorage(project, stack, workspace string) state.Storage {
return statestorages.NewMysqlStorage(s.db, project, stack, workspace)
func (s *MysqlStorage) StateStorage(project, workspace string) state.Storage {
return statestorages.NewMysqlStorage(s.db, project, workspace)
}

func (s *MysqlStorage) WorkspaceStorage() (workspace.Storage, error) {
Expand Down
12 changes: 5 additions & 7 deletions pkg/backend/storages/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,29 @@ func TestNewMysqlStorage(t *testing.T) {

func TestMysqlStorage_StateStorage(t *testing.T) {
testcases := []struct {
name string
mysqlStorage *MysqlStorage
project, stack, workspace string
stateStorage state.Storage
name string
mysqlStorage *MysqlStorage
project, workspace string
stateStorage state.Storage
}{
{
name: "state storage from mysql",
mysqlStorage: &MysqlStorage{
db: &gorm.DB{},
},
project: "wordpress",
stack: "dev",
workspace: "dev",
stateStorage: statestorages.NewMysqlStorage(
&gorm.DB{},
"wordpress",
"dev",
"dev",
),
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
stateStorage := tc.mysqlStorage.StateStorage(tc.project, tc.stack, tc.workspace)
stateStorage := tc.mysqlStorage.StateStorage(tc.project, tc.workspace)
assert.Equal(t, tc.stateStorage, stateStorage)
})
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/backend/storages/oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func NewOssStorage(config *v1.BackendOssConfig) (*OssStorage, error) {
return &OssStorage{bucket: bucket, prefix: config.Prefix}, nil
}

func (s *OssStorage) StateStorage(project, stack, workspace string) state.Storage {
return statestorages.NewOssStorage(s.bucket, statestorages.GenGenericOssStateFileKey(s.prefix, project, stack, workspace))
func (s *OssStorage) StateStorage(project, workspace string) state.Storage {
return statestorages.NewOssStorage(s.bucket, statestorages.GenGenericOssStateFileKey(s.prefix, project, workspace))
}

func (s *OssStorage) WorkspaceStorage() (workspace.Storage, error) {
Expand Down
13 changes: 6 additions & 7 deletions pkg/backend/storages/oss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ func TestNewOssStorage(t *testing.T) {

func TestOssStorage_StateStorage(t *testing.T) {
testcases := []struct {
name string
ossStorage *OssStorage
project, stack, workspace string
stateStorage state.Storage
name string
ossStorage *OssStorage
project, workspace string
stateStorage state.Storage
}{
{
name: "state storage from oss backend",
Expand All @@ -58,18 +58,17 @@ func TestOssStorage_StateStorage(t *testing.T) {
prefix: "kusion",
},
project: "wordpress",
stack: "dev",
workspace: "dev",
stateStorage: statestorages.NewOssStorage(
&oss.Bucket{},
"kusion/states/wordpress/dev/dev/state.yaml",
"kusion/states/wordpress/dev/state.yaml",
),
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
stateStorage := tc.ossStorage.StateStorage(tc.project, tc.stack, tc.workspace)
stateStorage := tc.ossStorage.StateStorage(tc.project, tc.workspace)
assert.Equal(t, tc.stateStorage, stateStorage)
})
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/backend/storages/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ func NewS3Storage(config *v1.BackendS3Config) (*S3Storage, error) {
}, nil
}

func (s *S3Storage) StateStorage(project, stack, workspace string) state.Storage {
return statestorages.NewS3Storage(s.s3, s.bucket, statestorages.GenGenericOssStateFileKey(s.prefix, project, stack, workspace))
func (s *S3Storage) StateStorage(project, workspace string) state.Storage {
return statestorages.NewS3Storage(s.s3, s.bucket, statestorages.GenGenericOssStateFileKey(s.prefix, project, workspace))
}

func (s *S3Storage) WorkspaceStorage() (workspace.Storage, error) {
Expand Down
13 changes: 6 additions & 7 deletions pkg/backend/storages/s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ func TestNewS3Storage(t *testing.T) {

func TestS3Storage_StateStorage(t *testing.T) {
testcases := []struct {
name string
s3Storage *S3Storage
project, stack, workspace string
stateStorage state.Storage
name string
s3Storage *S3Storage
project, workspace string
stateStorage state.Storage
}{
{
name: "state storage from s3 backend",
Expand All @@ -61,19 +61,18 @@ func TestS3Storage_StateStorage(t *testing.T) {
prefix: "kusion",
},
project: "wordpress",
stack: "dev",
workspace: "dev",
stateStorage: statestorages.NewS3Storage(
&s3.S3{},
"infra",
"kusion/states/wordpress/dev/dev/state.yaml",
"kusion/states/wordpress/dev/state.yaml",
),
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
stateStorage := tc.s3Storage.StateStorage(tc.project, tc.stack, tc.workspace)
stateStorage := tc.s3Storage.StateStorage(tc.project, tc.workspace)
assert.Equal(t, tc.stateStorage, stateStorage)
})
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (o *ApplyOptions) Run() error {
}

// compute changes for preview
storage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefStack.Name, o.RefWorkspace.Name)
storage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefWorkspace.Name)
changes, err := preview.Preview(o.PreviewOptions, storage, spec, o.RefProject, o.RefStack)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/destroy/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (o *DeleteOptions) Run() error {
signals.HandleInterrupt()

// only destroy resources we managed
storage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefStack.Name, o.RefWorkspace.Name)
storage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefWorkspace.Name)
priorState, err := storage.Get()
if err != nil || priorState == nil {
return fmt.Errorf("can not find DeprecatedState in this stack")
Expand Down
6 changes: 3 additions & 3 deletions pkg/cmd/destroy/destroy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func TestPreview(t *testing.T) {
mockOperationPreview()

o := NewDeleteOptions()
stateStorage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefStack.Name, o.RefWorkspace.Name)
stateStorage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefWorkspace.Name)
_, err := o.preview(&apiv1.Spec{Resources: []apiv1.Resource{sa1}}, proj, stack, stateStorage)
assert.Nil(t, err)
})
Expand Down Expand Up @@ -249,7 +249,7 @@ func TestDestroy(t *testing.T) {
}
changes := models.NewChanges(proj, stack, order)

stateStorage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefStack.Name, o.RefWorkspace.Name)
stateStorage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefWorkspace.Name)
err := o.destroy(planResources, changes, stateStorage)
assert.Nil(t, err)
})
Expand All @@ -271,7 +271,7 @@ func TestDestroy(t *testing.T) {
}
changes := models.NewChanges(proj, stack, order)

stateStorage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefStack.Name, o.RefWorkspace.Name)
stateStorage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefWorkspace.Name)
err := o.destroy(planResources, changes, stateStorage)
assert.NotNil(t, err)
})
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/preview/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (o *PreviewOptions) Run() error {
}

// compute changes for preview
storage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefStack.Name, o.RefWorkspace.Name)
storage := o.StorageBackend.StateStorage(o.RefProject.Name, o.RefWorkspace.Name)
changes, err := Preview(o, storage, spec, o.RefProject, o.RefStack)
if err != nil {
return err
Expand Down
20 changes: 7 additions & 13 deletions pkg/engine/state/storages/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,20 @@ import (

// MysqlStorage is an implementation of state.Storage which uses mysql as storage.
type MysqlStorage struct {
db *gorm.DB
project, stack, workspace string
db *gorm.DB
project, workspace string
}

func NewMysqlStorage(db *gorm.DB, project, stack, workspace string) *MysqlStorage {
func NewMysqlStorage(db *gorm.DB, project, workspace string) *MysqlStorage {
return &MysqlStorage{
db: db,
project: project,
stack: stack,
workspace: workspace,
}
}

func (s *MysqlStorage) Get() (*v1.DeprecatedState, error) {
stateDO, err := getStateFromMysql(s.db, s.project, s.stack, s.workspace)
stateDO, err := getStateFromMysql(s.db, s.project, s.workspace)
if err != nil {
return nil, err
}
Expand All @@ -36,7 +35,7 @@ func (s *MysqlStorage) Get() (*v1.DeprecatedState, error) {
}

func (s *MysqlStorage) Apply(state *v1.DeprecatedState) error {
exist, err := checkStateExistenceInMysql(s.db, s.project, s.stack, s.workspace)
exist, err := checkStateExistenceInMysql(s.db, s.project, s.workspace)
if err != nil {
return err
}
Expand All @@ -55,7 +54,6 @@ func (s *MysqlStorage) Apply(state *v1.DeprecatedState) error {
// StateMysqlDO is the data object stored in the mysql db.
type StateMysqlDO struct {
Project string
Stack string
Workspace string
Content string
}
Expand All @@ -64,10 +62,9 @@ func (s StateMysqlDO) TableName() string {
return stateTable
}

func getStateFromMysql(db *gorm.DB, project, stack, workspace string) (*StateMysqlDO, error) {
func getStateFromMysql(db *gorm.DB, project, workspace string) (*StateMysqlDO, error) {
q := &StateMysqlDO{
Project: project,
Stack: stack,
Workspace: workspace,
}
s := &StateMysqlDO{}
Expand All @@ -79,10 +76,9 @@ func getStateFromMysql(db *gorm.DB, project, stack, workspace string) (*StateMys
return s, result.Error
}

func checkStateExistenceInMysql(db *gorm.DB, project, stack, workspace string) (bool, error) {
func checkStateExistenceInMysql(db *gorm.DB, project, workspace string) (bool, error) {
q := &StateMysqlDO{
Project: project,
Stack: stack,
Workspace: workspace,
}
s := &StateMysqlDO{}
Expand All @@ -100,7 +96,6 @@ func createStateInMysql(db *gorm.DB, s *StateMysqlDO) error {
func updateStateInMysql(db *gorm.DB, s *StateMysqlDO) error {
q := &StateMysqlDO{
Project: s.Project,
Stack: s.Stack,
Workspace: s.Workspace,
}
return db.Where(q).Updates(s).Error
Expand All @@ -113,7 +108,6 @@ func convertToMysqlDO(state *v1.DeprecatedState) (*StateMysqlDO, error) {
}
return &StateMysqlDO{
Project: state.Project,
Stack: state.Stack,
Workspace: state.Workspace,
Content: string(content),
}, nil
Expand Down
1 change: 0 additions & 1 deletion pkg/engine/state/storages/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
func mockStateMysqlDO() *StateMysqlDO {
return &StateMysqlDO{
Project: "wordpress",
Stack: "dev",
Workspace: "dev",
Content: mockStateContent(),
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/engine/state/storages/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const (
)

// GenStateFilePath generates the state file path, which is used for LocalStorage.
func GenStateFilePath(dir, project, stack, workspace string) string {
return filepath.Join(dir, statesPrefix, project, stack, workspace, stateFile)
func GenStateFilePath(dir, project, workspace string) string {
return filepath.Join(dir, statesPrefix, project, workspace, stateFile)
}

// GenGenericOssStateFileKey generates generic oss state file key, which is use for OssStorage and S3Storage.
func GenGenericOssStateFileKey(prefix, project, stack, workspace string) string {
func GenGenericOssStateFileKey(prefix, project, workspace string) string {
prefix = strings.TrimPrefix(prefix, "/")
if prefix != "" {
prefix += "/"
}
return fmt.Sprintf("%s%s/%s/%s/%s/%s", prefix, statesPrefix, project, stack, workspace, stateFile)
return fmt.Sprintf("%s%s/%s/%s/%s", prefix, statesPrefix, project, workspace, stateFile)
}
Loading