From 076297b9e56873b3ea09b64a2e24005d1aaef97f Mon Sep 17 00:00:00 2001 From: adohe Date: Thu, 21 Dec 2023 22:18:27 +0800 Subject: [PATCH] refactor: use project&stack types in core v1 pkg --- pkg/apis/core/v1/types.go | 25 + pkg/apis/project/project.go | 185 --- pkg/apis/project/project_test.go | 1157 ----------------- pkg/apis/project/types.go | 117 -- pkg/apis/project/types_test.go | 164 --- pkg/apis/stack/stack.go | 152 --- pkg/apis/stack/types.go | 68 - pkg/cmd/apply/options.go | 4 +- pkg/cmd/apply/options_test.go | 47 +- pkg/cmd/build/builders/appconfig_builder.go | 6 +- .../build/builders/appconfig_builder_test.go | 16 +- pkg/cmd/build/builders/builder.go | 5 +- pkg/cmd/build/builders/kcl/kcl_builder.go | 7 +- .../build/builders/kcl/kcl_builder_test.go | 8 +- pkg/cmd/build/options.go | 11 +- pkg/cmd/build/options_test.go | 29 +- pkg/cmd/build/util.go | 19 +- pkg/cmd/build/util_test.go | 52 +- pkg/cmd/deps/deps_test.go | 2 +- pkg/cmd/deps/options.go | 17 +- .../testdata/appops/projectA/project.yaml | 1 + .../testdata/appops/projectB/project.yaml | 1 + .../testdata/appops/projectC/project.yaml | 1 + pkg/cmd/destroy/options.go | 14 +- pkg/cmd/destroy/options_test.go | 19 +- pkg/cmd/preview/options.go | 10 +- pkg/cmd/preview/options_test.go | 27 +- pkg/engine/backend/util.go | 3 +- pkg/engine/backend/util_test.go | 11 +- pkg/engine/operation/apply_test.go | 20 +- pkg/engine/operation/destory_test.go | 18 +- pkg/engine/operation/models/change.go | 13 +- pkg/engine/operation/models/change_test.go | 65 +- .../operation/models/operation_context.go | 17 +- pkg/engine/operation/preview_test.go | 18 +- pkg/engine/runtime/runtime.go | 10 +- .../runtime/terraform/terraform_runtime.go | 6 +- .../terraform/terraform_runtime_test.go | 10 +- .../accessories/database/alicloud_rds_test.go | 51 +- .../accessories/database/aws_rds_test.go | 39 +- .../database/database_generator.go | 15 +- .../database/database_generator_test.go | 63 +- .../database/local_database_test.go | 63 +- .../app_configurations_generator.go | 16 +- .../app_configurations_generator_test.go | 16 +- .../monitoring/monitoring_generator.go | 16 +- .../monitoring/monitoring_generator_test.go | 20 +- .../generators/trait/ops_rule_generator.go | 15 +- .../trait/ops_rule_generator_test.go | 21 +- .../generators/workload/job_generator.go | 15 +- .../generators/workload/job_generator_test.go | 31 +- .../workload/secret/secret_generator.go | 18 +- .../workload/secret/secret_generator_test.go | 8 +- .../generators/workload/service_generator.go | 15 +- .../workload/service_generator_test.go | 27 +- .../generators/workload/workload_generator.go | 15 +- .../workload/workload_generator_test.go | 37 +- .../patchers/monitoring/monitoring_patcher.go | 12 +- .../monitoring/monitoring_patcher_test.go | 24 +- pkg/project/paths.go | 238 ++++ pkg/project/paths_test.go | 255 ++++ .../testdata/appops/empty-app/base/base.k | 0 .../empty-app/dev/ci-test/settings.yaml | 0 .../testdata/appops/empty-app/dev/kcl.yaml | 0 .../testdata/appops/empty-app/dev/main.k | 0 .../testdata/appops/empty-app/dev/stack.yaml | 0 .../testdata/appops/empty-app/project.yaml | 0 .../testdata/appops/http-echo/README.md | 0 .../testdata/appops/http-echo/base/base.k | 0 .../http-echo/dev/ci-test/settings.yaml | 0 .../testdata/appops/http-echo/dev/kcl.yaml | 0 .../testdata/appops/http-echo/dev/main.k | 0 .../testdata/appops/http-echo/dev/stack.yaml | 0 .../testdata/appops/http-echo/project.yaml | 0 .../testdata/appops/nginx-example/README.md | 0 .../testdata/appops/nginx-example/base/base.k | 0 .../nginx-example/dev/ci-test/settings.yaml | 0 .../appops/nginx-example/dev/kcl.yaml | 0 .../testdata/appops/nginx-example/dev/main.k | 0 .../appops/nginx-example/dev/stack.yaml | 0 .../nginx-example/prod/ci-test/settings.yaml | 0 .../appops/nginx-example/prod/kcl.yaml | 0 .../testdata/appops/nginx-example/prod/main.k | 0 .../appops/nginx-example/prod/stack.yaml | 0 .../appops/nginx-example/project.yaml | 0 pkg/{apis => }/project/testdata/kcl.mod | 0 pkg/scaffold/templates.go | 3 +- 87 files changed, 941 insertions(+), 2447 deletions(-) delete mode 100644 pkg/apis/project/project.go delete mode 100644 pkg/apis/project/project_test.go delete mode 100644 pkg/apis/project/types.go delete mode 100644 pkg/apis/project/types_test.go delete mode 100644 pkg/apis/stack/stack.go delete mode 100644 pkg/apis/stack/types.go create mode 100644 pkg/project/paths.go create mode 100644 pkg/project/paths_test.go rename pkg/{apis => }/project/testdata/appops/empty-app/base/base.k (100%) rename pkg/{apis => }/project/testdata/appops/empty-app/dev/ci-test/settings.yaml (100%) rename pkg/{apis => }/project/testdata/appops/empty-app/dev/kcl.yaml (100%) rename pkg/{apis => }/project/testdata/appops/empty-app/dev/main.k (100%) rename pkg/{apis => }/project/testdata/appops/empty-app/dev/stack.yaml (100%) rename pkg/{apis => }/project/testdata/appops/empty-app/project.yaml (100%) rename pkg/{apis => }/project/testdata/appops/http-echo/README.md (100%) rename pkg/{apis => }/project/testdata/appops/http-echo/base/base.k (100%) rename pkg/{apis => }/project/testdata/appops/http-echo/dev/ci-test/settings.yaml (100%) rename pkg/{apis => }/project/testdata/appops/http-echo/dev/kcl.yaml (100%) rename pkg/{apis => }/project/testdata/appops/http-echo/dev/main.k (100%) rename pkg/{apis => }/project/testdata/appops/http-echo/dev/stack.yaml (100%) rename pkg/{apis => }/project/testdata/appops/http-echo/project.yaml (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/README.md (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/base/base.k (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/dev/ci-test/settings.yaml (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/dev/kcl.yaml (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/dev/main.k (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/dev/stack.yaml (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/prod/ci-test/settings.yaml (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/prod/kcl.yaml (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/prod/main.k (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/prod/stack.yaml (100%) rename pkg/{apis => }/project/testdata/appops/nginx-example/project.yaml (100%) rename pkg/{apis => }/project/testdata/kcl.mod (100%) diff --git a/pkg/apis/core/v1/types.go b/pkg/apis/core/v1/types.go index 6b4baa6d..7af93c6c 100644 --- a/pkg/apis/core/v1/types.go +++ b/pkg/apis/core/v1/types.go @@ -5,6 +5,13 @@ type ( MonitorType string ) +const ( + KCLBuilder BuilderType = "KCL" + AppConfigurationBuilder BuilderType = "AppConfiguration" + PodMonitorType MonitorType = "Pod" + ServiceMonitorType MonitorType = "Service" +) + // Project is a definition of Kusion Project resource. // // A project is composed of one or more applications and is linked to a Git repository, @@ -18,8 +25,17 @@ type Project struct { // Labels is the list of labels that are assigned to this project. Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + // Path is a directory path within the Git repository. + Path string `json:"path,omitempty" yaml:"path,omitempty"` + // Generator controls how to generate the Intent. Generator *GeneratorConfig `json:"generator,omitempty" yaml:"generator,omitempty"` + + // Prometheus configs + Prometheus *PrometheusConfig `json:"prometheus,omitempty" yaml:"prometheus,omitempty"` + + // The set of stacks that are known about this project. + Stacks []*Stack `json:"stacks,omitempty" yaml:"stacks,omitempty"` } // GeneratorConfig holds the intent generation configurations defined in Project resource. @@ -30,6 +46,12 @@ type GeneratorConfig struct { Configs map[string]interface{} `json:"configs,omitempty" yaml:"configs,omitempty"` } +// PrometheusConfig represent Prometheus configs saved in project.yaml +type PrometheusConfig struct { + OperatorMode bool `yaml:"operatorMode,omitempty" json:"operatorMode,omitempty"` + MonitorType MonitorType `yaml:"monitorType,omitempty" json:"monitorType,omitempty"` +} + // Stack is a definition of Kusion Stack resource. // // Stack provides a mechanism to isolate multiple deploys of same application, @@ -43,4 +65,7 @@ type Stack struct { Description *string `json:"description,omitempty" yaml:"description,omitempty"` // Labels is the list of labels that are assigned to this stack. Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + + // Path is a directory path within the Git repository. + Path string `json:"path,omitempty" yaml:"path,omitempty"` } diff --git a/pkg/apis/project/project.go b/pkg/apis/project/project.go deleted file mode 100644 index a2100d31..00000000 --- a/pkg/apis/project/project.go +++ /dev/null @@ -1,185 +0,0 @@ -package project - -import ( - "fmt" - "io/fs" - "os" - "path/filepath" - - "github.com/pulumi/pulumi/sdk/v3/go/common/util/fsutil" - "k8s.io/apimachinery/pkg/util/sets" - - "kusionstack.io/kusion/pkg/apis/stack" - "kusionstack.io/kusion/pkg/log" - "kusionstack.io/kusion/pkg/util/yaml" -) - -// IsProject determine whether the given path is Project directory -func IsProject(path string) bool { - f, err := os.Stat(path) - f2, err2 := os.Stat(filepath.Join(path, ProjectFile)) - - if (err == nil && f.IsDir()) && (err2 == nil && f2.Mode().IsRegular()) { - return true - } - - return false -} - -// IsProjectFile determine whether the given path is Project file -func IsProjectFile(path string) bool { - f, err := os.Stat(path) - return err == nil && !f.IsDir() && f.Mode().IsRegular() && filepath.Base(path) == ProjectFile -} - -// FindProjectPath locates the closest project from the current working directory, or an error if not found. -func FindProjectPath() (string, error) { - dir, err := os.Getwd() - if err != nil { - return "", err - } - - path, err := FindProjectPathFrom(dir) - if err != nil { - return "", err - } - - return path, nil -} - -// FindProjectPathFrom locates the closest project from the given path, searching "upwards" in the directory -// hierarchy. If no project is found, an empty path is returned. -func FindProjectPathFrom(path string) (string, error) { - file, err := fsutil.WalkUp(path, IsProjectFile, func(s string) bool { - return true - }) - if err != nil { - return "", err - } - - return filepath.Dir(file), nil -} - -// ParseConfiguration parse the project configuration by the given directory -func ParseConfiguration(path string) (*Configuration, error) { - if !IsProject(path) { - return nil, ErrNotProjectDirectory - } - - var config Configuration - - err := yaml.ParseYamlFromFile(filepath.Join(path, ProjectFile), &config) - if err != nil { - return nil, err - } - - return &config, nil -} - -// FindAllProjects find all projects from the current working directory -func FindAllProjects() ([]*Project, error) { - dir, err := os.Getwd() - if err != nil { - return nil, err - } - - projects, err := FindAllProjectsFrom(dir) - if err != nil { - return nil, err - } - - return projects, nil -} - -// FindAllProjectsFrom find all project from the given path -func FindAllProjectsFrom(path string) ([]*Project, error) { - projects := []*Project{} - s := sets.NewString() - err := filepath.WalkDir(path, func(p string, _ fs.DirEntry, _ error) error { - if IsProject(p) && !s.Has(p) { - // Parse project configuration - config, err := ParseConfiguration(p) - if err != nil { - log.Error(err) - return fmt.Errorf("parse project.yaml failed. %w", err) - } - - // Find all stacks - stacks, err := stack.FindAllStacksFrom(p) - if err != nil { - log.Error(err) - return fmt.Errorf("parse stacks failed. %w", err) - } - - // Get absolute path - absPath, err := filepath.Abs(p) - if err != nil { - log.Error(err) - return fmt.Errorf("project path failed. %w", err) - } - - projects = append(projects, NewProject(config, absPath, stacks)) - } - return nil - }) - - return projects, err -} - -// GetProject get project from the current working directory -func GetProject() (*Project, error) { - dir, err := os.Getwd() - if err != nil { - return nil, err - } - - project, err := GetProjectFrom(dir) - if err != nil { - return nil, err - } - - return project, nil -} - -// GetProjectFrom get project from the given path -func GetProjectFrom(path string) (*Project, error) { - if !IsProject(path) { - return nil, ErrNotProjectDirectory - } - - projects, err := FindAllProjectsFrom(path) - if err != nil { - return nil, err - } - - if len(projects) != 1 { - return nil, ErrProjectNotUnique - } - - return projects[0], nil -} - -// DetectProjectAndStack try to get stack and project from given path -func DetectProjectAndStack(stackDir string) (p *Project, s *stack.Stack, err error) { - stackDir, err = filepath.Abs(stackDir) - if err != nil { - return nil, nil, err - } - - s, err = stack.GetStackFrom(stackDir) - if err != nil { - return nil, nil, err - } - - projectDir, err := FindProjectPathFrom(stackDir) - if err != nil { - return nil, nil, err - } - - p, err = GetProjectFrom(projectDir) - if err != nil { - return nil, nil, err - } - - return p, s, nil -} diff --git a/pkg/apis/project/project_test.go b/pkg/apis/project/project_test.go deleted file mode 100644 index ec2f98d3..00000000 --- a/pkg/apis/project/project_test.go +++ /dev/null @@ -1,1157 +0,0 @@ -package project - -import ( - "errors" - "os" - "path/filepath" - "reflect" - "testing" - - "github.com/bytedance/mockey" - "github.com/pterm/pterm" - - "kusionstack.io/kusion/pkg/apis/stack" - "kusionstack.io/kusion/pkg/util/json" -) - -// merge project tests and stack tests together to reuse test data -var ( - // Inject into the TestMain - TestCurrentDir string - TestProjectPathA string - TestStackPathAA string - TestProjectPathB string - TestStackPathBA string - TestStackPathBB string - ErrFake = errors.New("fake error") -) - -const ( - TestProjectA string = "http-echo" - TestProjectB string = "nginx-example" - TestStackA string = "dev" - TestStackB string = "prod" -) - -func TestMain(m *testing.M) { - TestCurrentDir, _ = os.Getwd() - TestProjectPathA = filepath.Join("testdata", "appops", TestProjectA) - TestStackPathAA = filepath.Join("testdata", "appops", TestProjectA, TestStackA) - TestProjectPathB = filepath.Join("testdata", "appops", TestProjectB) - TestStackPathBA = filepath.Join("testdata", "appops", TestProjectB, TestStackA) - TestStackPathBB = filepath.Join("testdata", "appops", TestProjectB, TestStackB) - - os.Exit(m.Run()) -} - -func TestFindProjectPath(t *testing.T) { - _ = os.Chdir(TestStackPathAA) - defer os.Chdir(TestCurrentDir) - - tests := []struct { - name string - want string - wantErr bool - }{ - { - name: "success", - want: filepath.Join(TestCurrentDir, TestProjectPathA), - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := FindProjectPath() - if (err != nil) != tt.wantErr { - t.Errorf("FindProjectPath() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("FindProjectPath() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestFindProjectPathFrom(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want string - wantErr bool - }{ - { - name: "success", - args: args{ - path: "./testdata/appops/http-echo/dev/ci-test", - }, - want: "testdata/appops/http-echo", - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := FindProjectPathFrom(tt.args.path) - if (err != nil) != tt.wantErr { - t.Errorf("FindProjectPathFrom() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("FindProjectPathFrom() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestIsProject(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want bool - }{ - { - name: "is-project", - args: args{ - path: "./testdata/appops/http-echo/dev/ci-test", - }, - want: false, - }, - { - name: "is-not-project", - args: args{ - path: "./testdata/appops/http-echo", - }, - want: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := IsProject(tt.args.path); got != tt.want { - t.Errorf("IsProject() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestParseConfiguration(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want *Configuration - wantErr bool - }{ - { - name: "success", - args: args{ - path: "./testdata/appops/http-echo/", - }, - want: &Configuration{ - Name: TestProjectA, - Tenant: "", - }, - wantErr: false, - }, - { - name: "fail", - args: args{ - path: "./testdata/appops/http-echo/dev", - }, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ParseConfiguration(tt.args.path) - if (err != nil) != tt.wantErr { - t.Errorf("ParseConfiguration() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ParseConfiguration() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestFindAllProjects(t *testing.T) { - _ = os.Chdir(TestProjectPathA) - defer os.Chdir(TestCurrentDir) - - tests := []struct { - name string - want []*Project - wantErr bool - }{ - { - name: "given-project-path", - want: []*Project{ - { - Configuration: Configuration{ - Name: TestProjectA, - }, - Path: filepath.Join(TestCurrentDir, TestProjectPathA), - Stacks: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - }, - }, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := FindAllProjects() - if (err != nil) != tt.wantErr { - t.Errorf("FindAllProjects() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("FindAllProjects() = %v, want %v", json.MustMarshal2PrettyString(got), json.MustMarshal2PrettyString(tt.want)) - } - }) - } -} - -func TestFindAllProjectsFrom(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want []*Project - wantErr bool - }{ - { - name: "given-project-path", - args: args{ - path: "./testdata/appops/http-echo", - }, - want: []*Project{ - { - Configuration: Configuration{ - Name: TestProjectA, - }, - Path: filepath.Join(TestCurrentDir, TestProjectPathA), - Stacks: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - }, - }, - }, - wantErr: false, - }, - { - name: "give-project-path-with-two-stacks", - args: args{ - path: "./testdata/appops/nginx-example", - }, - want: []*Project{ - { - Configuration: Configuration{ - Name: TestProjectB, - }, - Path: filepath.Join(TestCurrentDir, TestProjectPathB), - Stacks: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathBA), - }, - { - Configuration: stack.Configuration{ - Name: TestStackB, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathBB), - }, - }, - }, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := FindAllProjectsFrom(tt.args.path) - if (err != nil) != tt.wantErr { - t.Errorf("FindAllProjectsFrom() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("FindAllProjectsFrom() = %v, want %v", json.MustMarshal2PrettyString(got), json.MustMarshal2PrettyString(tt.want)) - } - }) - } -} - -func TestGetProject(t *testing.T) { - _ = os.Chdir(TestProjectPathA) - defer os.Chdir(TestCurrentDir) - - tests := []struct { - name string - want *Project - wantErr bool - preRun func() - postRun func() - }{ - { - name: "success", - want: &Project{ - Configuration: Configuration{ - Name: TestProjectA, - }, - Path: filepath.Join(TestCurrentDir, TestProjectPathA), - Stacks: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - }, - }, - wantErr: false, - preRun: func() {}, - postRun: func() {}, - }, - { - name: "fail-for-GetProjectFrom", - want: nil, - wantErr: true, - preRun: func() { - mockGetProjectFrom(ErrFake) - }, - postRun: func() {}, - }, - } - for _, tt := range tests { - mockey.PatchConvey(tt.name, t, func() { - tt.preRun() - got, err := GetProject() - tt.postRun() - if (err != nil) != tt.wantErr { - t.Errorf("GetProject() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetProject() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestGetProjectFrom(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want *Project - wantErr bool - }{ - { - name: "success", - args: args{ - path: filepath.Join(TestCurrentDir, TestProjectPathA), - }, - want: &Project{ - Configuration: Configuration{ - Name: TestProjectA, - }, - Path: filepath.Join(TestCurrentDir, TestProjectPathA), - Stacks: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - }, - }, - wantErr: false, - }, - { - name: "failed-because-no-project-path", - args: args{ - path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - want: nil, - wantErr: true, - }, - { - name: "failed-because-not-existed-path", - args: args{ - path: "./testdata-not-exist", - }, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := GetProjectFrom(tt.args.path) - if (err != nil) != tt.wantErr { - t.Errorf("GetProjectFrom() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetProjectFrom() = %v, want %v", json.MustMarshal2PrettyString(got), json.MustMarshal2PrettyString(tt.want)) - } - }) - } -} - -func TestIsProjectFile(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want bool - }{ - { - name: "is-project-file", - args: args{ - path: filepath.Join(TestProjectPathA, ProjectFile), - }, - want: true, - }, - { - name: "is-not-project-file", - args: args{ - path: TestProjectPathA, - }, - want: false, - }, - { - name: "is-not-project-file-2", - args: args{ - path: filepath.Join(TestStackPathAA, stack.File), - }, - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := IsProjectFile(tt.args.path); got != tt.want { - t.Errorf("IsProjectFile() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestDetectProjectAndStack(t *testing.T) { - FakeProject := &Project{ - Configuration: Configuration{ - Name: TestProjectA, - }, - Path: filepath.Join(TestCurrentDir, TestProjectPathA), - Stacks: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - }, - } - FakeStack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - } - - type args struct { - stackDir string - } - tests := []struct { - name string - args args - project *Project - stack *stack.Stack - wantErr bool - preRun func() - postRun func() - }{ - { - name: "success", - args: args{ - stackDir: "./testdata/appops/http-echo/dev/", - }, - project: FakeProject, - stack: FakeStack, - wantErr: false, - preRun: func() {}, - postRun: func() {}, - }, - { - name: "fail-for-abs", - args: args{ - stackDir: "./testdata/appops/http-echo/dev/", - }, - project: nil, - stack: nil, - wantErr: true, - preRun: func() { - mockAbs("", ErrFake) - }, - postRun: func() {}, - }, - { - name: "fail-for-GetStackFrom", - args: args{ - stackDir: "./testdata/appops/http-echo/dev/", - }, - project: nil, - stack: nil, - wantErr: true, - preRun: func() { - mockGetStackFrom(ErrFake) - }, - postRun: func() {}, - }, - { - name: "fail-for-FindProjectPathFrom", - args: args{ - stackDir: "./testdata/appops/http-echo/dev/", - }, - project: nil, - stack: nil, - wantErr: true, - preRun: func() { - mockFindProjectPathFrom("", ErrFake) - }, - postRun: func() {}, - }, - { - name: "fail-for-GetProjectFrom", - args: args{ - stackDir: "./testdata/appops/http-echo/dev/", - }, - project: nil, - stack: nil, - wantErr: true, - preRun: func() { - mockGetProjectFrom(ErrFake) - }, - postRun: func() {}, - }, - } - for _, tt := range tests { - mockey.PatchConvey(tt.name, t, func() { - tt.preRun() - got, gosuccess, err := DetectProjectAndStack(tt.args.stackDir) - tt.postRun() - if (err != nil) != tt.wantErr { - t.Errorf("DetectProjectAndStack() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.project) { - t.Errorf("DetectProjectAndStack() got = %v, want %v", got, tt.project) - } - if !reflect.DeepEqual(gosuccess, tt.stack) { - t.Errorf("DetectProjectAndStack() gosuccess = %v, want %v", gosuccess, tt.stack) - } - }) - } -} - -func TestFindStackPath(t *testing.T) { - _ = os.Chdir(filepath.Join(TestStackPathAA, "ci-test")) - defer os.Chdir(TestCurrentDir) - - tests := []struct { - name string - want string - wantErr bool - }{ - { - name: "success", - want: filepath.Join(TestCurrentDir, TestStackPathAA), - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := stack.FindStackPath() - if (err != nil) != tt.wantErr { - t.Errorf("FindStackPath() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("FindStackPath() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestFindStackPathFrom(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want string - wantErr bool - }{ - { - name: "success", - args: args{ - path: "./testdata/appops/http-echo/dev/ci-test", - }, - want: "testdata/appops/http-echo/dev", - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := stack.FindStackPathFrom(tt.args.path) - if (err != nil) != tt.wantErr { - t.Errorf("FindStackPathFrom() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("FindStackPathFrom() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestIsStack(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want bool - }{ - { - name: "is-stack", - args: args{ - path: "./testdata/appops/http-echo/dev/ci-test", - }, - want: false, - }, - { - name: "is-not-stack", - args: args{ - path: "./testdata/appops/http-echo/dev", - }, - want: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := stack.IsStack(tt.args.path); got != tt.want { - t.Errorf("IsStack() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestParseStackConfiguration(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want *stack.Configuration - wantErr bool - }{ - { - name: "success", - args: args{ - path: "./testdata/appops/http-echo/dev", - }, - want: &stack.Configuration{ - Name: TestStackA, - }, - wantErr: false, - }, - { - name: "fail", - args: args{ - path: "./testdata/appops/http-echo", - }, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := stack.ParseStackConfiguration(tt.args.path) - if (err != nil) != tt.wantErr { - t.Errorf("ParseStackConfiguration() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ParseStackConfiguration() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestFindAllStacks(t *testing.T) { - _ = os.Chdir(TestProjectPathA) - defer os.Chdir(TestCurrentDir) - - tests := []struct { - name string - want []*stack.Stack - wantErr bool - }{ - { - name: "given-project-path", - want: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := stack.FindAllStacks() - if (err != nil) != tt.wantErr { - t.Errorf("FindAllStacks() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("FindAllStacks() = %v, want %v", json.MustMarshal2PrettyString(got), json.MustMarshal2PrettyString(tt.want)) - } - }) - } -} - -func TestFindAllStacksFrom(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want []*stack.Stack - wantErr bool - }{ - { - name: "given-project-path", - args: args{ - path: "./testdata/appops/http-echo", - }, - want: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - }, - wantErr: false, - }, - { - name: "give-project-path-with-two-stacks", - args: args{ - path: "./testdata/appops/nginx-example", - }, - want: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathBA), - }, - { - Configuration: stack.Configuration{ - Name: TestStackB, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathBB), - }, - }, - wantErr: false, - }, - { - name: "given-stack-path", - args: args{ - path: "./testdata/appops/http-echo/dev/", - }, - want: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - }, - wantErr: false, - }, - { - name: "given-no-stack-path", - args: args{ - path: "./testdata/appops/http-echo/gray/", - }, - want: []*stack.Stack{}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := stack.FindAllStacksFrom(tt.args.path) - if (err != nil) != tt.wantErr { - t.Errorf("FindAllStacksFrom() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("FindAllStacksFrom() = %v, want %v", json.MustMarshal2PrettyString(got), json.MustMarshal2PrettyString(tt.want)) - } - }) - } -} - -func TestGetStack(t *testing.T) { - _ = os.Chdir(TestStackPathAA) - defer os.Chdir(TestCurrentDir) - - tests := []struct { - name string - want *stack.Stack - wantErr bool - preRun func() - postRun func() - }{ - { - name: "success", - want: &stack.Stack{ - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - wantErr: false, - preRun: func() {}, - postRun: func() {}, - }, - { - name: "fail-for-GetStackFrom", - want: nil, - wantErr: true, - preRun: func() { - mockGetStackFrom(ErrFake) - }, - postRun: func() {}, - }, - } - for _, tt := range tests { - mockey.PatchConvey(tt.name, t, func() { - tt.preRun() - got, err := stack.GetStack() - tt.postRun() - if (err != nil) != tt.wantErr { - t.Errorf("GetStack() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetStack() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestGetStackFrom(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want *stack.Stack - wantErr bool - }{ - { - name: "success", - args: args{ - path: "./testdata/appops/http-echo/dev/", - }, - want: &stack.Stack{ - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: filepath.Join(TestCurrentDir, TestStackPathAA), - }, - wantErr: false, - }, - { - name: "failed-because-no-stack-path", - args: args{ - path: TestProjectPathA, - }, - want: nil, - wantErr: true, - }, - { - name: "failed-because-not-existed-path", - args: args{ - path: "./testdata-not-exist", - }, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := stack.GetStackFrom(tt.args.path) - if (err != nil) != tt.wantErr { - t.Errorf("GetStackFrom() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetStackFrom() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestIsStackFile(t *testing.T) { - type args struct { - path string - } - tests := []struct { - name string - args args - want bool - }{ - { - name: "is-stack-file", - args: args{ - path: filepath.Join(TestStackPathAA, stack.File), - }, - want: true, - }, - { - name: "is-not-stack-file", - args: args{ - path: TestStackPathAA, - }, - want: false, - }, - { - name: "is-not-stack-file-2", - args: args{ - path: filepath.Join(TestStackPathAA, "main.k"), - }, - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := stack.IsStackFile(tt.args.path); got != tt.want { - t.Errorf("IsStackFile() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestNewStack(t *testing.T) { - type args struct { - config *stack.Configuration - path string - } - tests := []struct { - name string - args args - want *stack.Stack - }{ - { - name: "success", - args: args{ - config: &stack.Configuration{ - Name: TestStackA, - }, - path: TestStackPathAA, - }, - want: &stack.Stack{ - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: TestStackPathAA, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := stack.NewStack(tt.args.config, tt.args.path); !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewStack() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestStack_GetName(t *testing.T) { - type fields struct { - Configuration stack.Configuration - Path string - } - tests := []struct { - name string - fields fields - want string - }{ - { - name: "success", - fields: fields{ - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: TestStackPathAA, - }, - want: TestStackA, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - s := &stack.Stack{ - Configuration: tt.fields.Configuration, - Path: tt.fields.Path, - } - if got := s.GetName(); got != tt.want { - t.Errorf("Stack.GetName() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestStack_GetPath(t *testing.T) { - type fields struct { - Configuration stack.Configuration - Path string - } - tests := []struct { - name string - fields fields - want string - }{ - { - name: "success", - fields: fields{ - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: TestStackPathAA, - }, - want: TestStackPathAA, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - s := &stack.Stack{ - Configuration: tt.fields.Configuration, - Path: tt.fields.Path, - } - if got := s.GetPath(); got != tt.want { - t.Errorf("Stack.GetPath() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestStack_TableReport(t *testing.T) { - type fields struct { - Configuration stack.Configuration - Path string - } - tests := []struct { - name string - fields fields - want string - }{ - { - name: "success", - fields: fields{ - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: TestStackPathAA, - }, - want: `┌────────────────────────────────────────────┐ -| Type | Name | -| Stack Name | dev | -| Stack Path | testdata/appops/http-echo/dev | -└────────────────────────────────────────────┘`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - s := &stack.Stack{ - Configuration: tt.fields.Configuration, - Path: tt.fields.Path, - } - got := pterm.RemoveColorFromString(s.TableReport()) - if got != tt.want { - t.Errorf("Stack.TableReport() = %v, want %v", got, tt.want) - } - }) - } -} - -func mockAbs(mockAbs string, mockErr error) { - mockey.Mock(filepath.Abs).To(func(_ string) (string, error) { - return mockAbs, mockErr - }).Build() -} - -func mockGetStackFrom(mockErr error) { - mockey.Mock(stack.GetStackFrom).To(func(_ string) (*stack.Stack, error) { - if mockErr == nil { - return &stack.Stack{}, nil - } - return nil, mockErr - }).Build() -} - -func mockGetProjectFrom(mockErr error) { - mockey.Mock(GetProjectFrom).To(func(_ string) (*Project, error) { - if mockErr == nil { - return &Project{}, nil - } - return nil, mockErr - }).Build() -} - -func mockFindProjectPathFrom(mockProjectDir string, mockErr error) { - mockey.Mock(FindProjectPathFrom).To(func(_ string) (string, error) { - if mockErr == nil { - return mockProjectDir, nil - } - return "", mockErr - }).Build() -} diff --git a/pkg/apis/project/types.go b/pkg/apis/project/types.go deleted file mode 100644 index f1eadbf1..00000000 --- a/pkg/apis/project/types.go +++ /dev/null @@ -1,117 +0,0 @@ -package project - -import ( - "errors" - "strings" - - "github.com/pterm/pterm" - - "kusionstack.io/kusion/pkg/apis/stack" - "kusionstack.io/kusion/pkg/log" -) - -var ( - ErrNotProjectDirectory = errors.New("path must be a project directory") - ErrProjectNotUnique = errors.New("the project obtained is not unique") -) - -const ( - ProjectFile = "project.yaml" - KclFile = "kcl.yaml" - KCLBuilder BuilderType = "KCL" - AppConfigurationBuilder BuilderType = "AppConfiguration" - PodMonitorType MonitorType = "Pod" - ServiceMonitorType MonitorType = "Service" -) - -type ( - BuilderType string - MonitorType string -) - -// GeneratorConfig represent Generator configs saved in project.yaml -type GeneratorConfig struct { - Type BuilderType `json:"type"` - Configs map[string]interface{} `json:"configs,omitempty"` -} - -// PrometheusConfig represent Prometheus configs saved in project.yaml -type PrometheusConfig struct { - OperatorMode bool `yaml:"operatorMode,omitempty" json:"operatorMode,omitempty"` - MonitorType MonitorType `yaml:"monitorType,omitempty" json:"monitorType,omitempty"` -} - -// Configuration is the project configuration -type Configuration struct { - // Project name - Name string `json:"name" yaml:"name"` - - // Tenant name - Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"` - - // SpecGenerator configs - Generator *GeneratorConfig `json:"generator,omitempty" yaml:"generator,omitempty"` - - // Prometheus configs - Prometheus *PrometheusConfig `json:"prometheus,omitempty" yaml:"prometheus,omitempty"` -} - -type Project struct { - Configuration `json:",inline" yaml:",inline"` - Path string `json:"path,omitempty" yaml:"path,omitempty"` // Absolute path to the project directory - Stacks []*stack.Stack `json:"stacks,omitempty" yaml:"stacks,omitempty"` // Stacks -} - -// NewProject creates a new project -func NewProject(config *Configuration, path string, stacks []*stack.Stack) *Project { - return &Project{ - Configuration: *config, - Path: path, - Stacks: stacks, - } -} - -// GetName returns the name of the project -func (p *Project) GetName() string { - return p.Name -} - -// GetPath returns the path of the project -func (p *Project) GetPath() string { - return p.Path -} - -// TableReport returns the report string of table format -func (p *Project) TableReport() string { - // Fill table header - tableHeader := []string{"Type", "Name"} - tableData := pterm.TableData{tableHeader} - - // Fill table content - tableData = append(tableData, []string{"Project Name", p.GetName()}) - if p.GetPath() != "" { - tableData = append(tableData, []string{"Project Path", p.GetPath()}) - } - - if p.Tenant != "" { - tableData = append(tableData, []string{"Tenant", p.Tenant}) - } - - stacksList := []string{} - for _, s := range p.Stacks { - stacksList = append(stacksList, s.GetName()) - } - - tableData = append(tableData, []string{"Stacks", strings.Join(stacksList, ",")}) - - // Render table - report, err := pterm.DefaultTable.WithHasHeader(). - WithBoxed(true). - WithData(tableData). - Srender() - if err != nil { - log.Warn(err) - } - - return report -} diff --git a/pkg/apis/project/types_test.go b/pkg/apis/project/types_test.go deleted file mode 100644 index e3e72903..00000000 --- a/pkg/apis/project/types_test.go +++ /dev/null @@ -1,164 +0,0 @@ -package project - -import ( - "reflect" - "testing" - - "github.com/pterm/pterm" - - "kusionstack.io/kusion/pkg/apis/stack" -) - -func TestNewProject(t *testing.T) { - type args struct { - config *Configuration - path string - stacks []*stack.Stack - } - tests := []struct { - name string - args args - want *Project - }{ - { - name: "success", - args: args{ - config: &Configuration{}, - path: "test", - stacks: []*stack.Stack{}, - }, - want: &Project{ - Configuration: Configuration{}, - Path: "test", - Stacks: []*stack.Stack{}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := NewProject(tt.args.config, tt.args.path, tt.args.stacks); !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewProject() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestProject_GetName(t *testing.T) { - type fields struct { - Configuration Configuration - Path string - Stacks []*stack.Stack - } - tests := []struct { - name string - fields fields - want string - }{ - { - name: "success", - fields: fields{ - Configuration: Configuration{ - Name: "test", - }, - }, - want: "test", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Project{ - Configuration: tt.fields.Configuration, - Path: tt.fields.Path, - Stacks: tt.fields.Stacks, - } - if got := p.GetName(); got != tt.want { - t.Errorf("Project.GetName() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestProject_GetPath(t *testing.T) { - type fields struct { - Configuration Configuration - Path string - Stacks []*stack.Stack - } - tests := []struct { - name string - fields fields - want string - }{ - { - name: "success", - fields: fields{ - Path: "test", - }, - want: "test", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Project{ - Configuration: tt.fields.Configuration, - Path: tt.fields.Path, - Stacks: tt.fields.Stacks, - } - if got := p.GetPath(); got != tt.want { - t.Errorf("Project.GetPath() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestProject_TableReport(t *testing.T) { - type fields struct { - Configuration Configuration - Path string - Stacks []*stack.Stack - } - tests := []struct { - name string - fields fields - want string - }{ - { - name: "success", - fields: fields{ - Configuration: Configuration{ - Name: TestProjectA, - Tenant: "main", - }, - Path: TestProjectPathA, - Stacks: []*stack.Stack{ - { - Configuration: stack.Configuration{ - Name: TestStackA, - }, - Path: TestStackPathAA, - }, - }, - }, - want: `┌──────────────────────────────────────────┐ -| Type | Name | -| Project Name | http-echo | -| Project Path | testdata/appops/http-echo | -| Tenant | main | -| Stacks | dev | -└──────────────────────────────────────────┘`, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Project{ - Configuration: tt.fields.Configuration, - Path: tt.fields.Path, - Stacks: tt.fields.Stacks, - } - got := pterm.RemoveColorFromString(p.TableReport()) - if got != tt.want { - t.Errorf("Project.TableReport() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/apis/stack/stack.go b/pkg/apis/stack/stack.go deleted file mode 100644 index e5186681..00000000 --- a/pkg/apis/stack/stack.go +++ /dev/null @@ -1,152 +0,0 @@ -package stack - -import ( - "io/fs" - "os" - "path/filepath" - - "github.com/pulumi/pulumi/sdk/v3/go/common/util/fsutil" - "k8s.io/apimachinery/pkg/util/sets" - - "kusionstack.io/kusion/pkg/log" - "kusionstack.io/kusion/pkg/util/yaml" -) - -// IsStack determine whether the given path is Stack directory -func IsStack(path string) bool { - f, err := os.Stat(path) - f2, err2 := os.Stat(filepath.Join(path, File)) - - if (err == nil && f.IsDir()) && (err2 == nil && f2.Mode().IsRegular()) { - return true - } - - return false -} - -// IsStackFile determine whether the given path is Stack file -func IsStackFile(path string) bool { - f, err := os.Stat(path) - return err == nil && !f.IsDir() && f.Mode().IsRegular() && filepath.Base(path) == File -} - -// FindStackPath locates the closest stack from the current working directory, or an error if not found. -func FindStackPath() (string, error) { - dir, err := os.Getwd() - if err != nil { - return "", err - } - - path, err := FindStackPathFrom(dir) - if err != nil { - return "", err - } - - return path, nil -} - -// FindStackPathFrom locates the closest stack from the given path, searching "upwards" in the directory -// hierarchy. If no stack is found, an empty path is returned. -func FindStackPathFrom(path string) (string, error) { - file, err := fsutil.WalkUp(path, IsStackFile, func(s string) bool { - return true - }) - if err != nil { - return "", err - } - - return filepath.Dir(file), nil -} - -// ParseStackConfiguration parse the stack configuration by the given directory -func ParseStackConfiguration(path string) (*Configuration, error) { - if !IsStack(path) { - return nil, ErrNotStackDirectory - } - - var stack Configuration - - err := yaml.ParseYamlFromFile(filepath.Join(path, File), &stack) - if err != nil { - return nil, err - } - - return &stack, nil -} - -// FindAllStacks find all stacks from the current working directory -func FindAllStacks() ([]*Stack, error) { - dir, err := os.Getwd() - if err != nil { - return nil, err - } - - stacks, err := FindAllStacksFrom(dir) - if err != nil { - return nil, err - } - - return stacks, nil -} - -// FindAllStacksFrom find all stacks from the given path -func FindAllStacksFrom(path string) ([]*Stack, error) { - stacks := []*Stack{} - s := sets.NewString() - _ = filepath.WalkDir(path, func(p string, _ fs.DirEntry, _ error) (err error) { - if IsStack(p) && !s.Has(p) { - // Parse stack configuration - config, err := ParseStackConfiguration(p) - if err != nil { - log.Error(err) - return nil - } - - // Get absolute path - absPath, err := filepath.Abs(p) - if err != nil { - log.Error(err) - return nil - } - - stacks = append(stacks, NewStack(config, absPath)) - } - - return nil - }) - - return stacks, nil -} - -// GetStack get stack from the current working directory -func GetStack() (*Stack, error) { - dir, err := os.Getwd() - if err != nil { - return nil, err - } - - stack, err := GetStackFrom(dir) - if err != nil { - return nil, err - } - - return stack, nil -} - -// GetStackFrom get stack from the given path -func GetStackFrom(path string) (*Stack, error) { - if !IsStack(path) { - return nil, ErrNotStackDirectory - } - - stacks, err := FindAllStacksFrom(path) - if err != nil { - return nil, err - } - - if len(stacks) != 1 { - return nil, ErrStackNotUnique - } - - return stacks[0], nil -} diff --git a/pkg/apis/stack/types.go b/pkg/apis/stack/types.go deleted file mode 100644 index ade62b9d..00000000 --- a/pkg/apis/stack/types.go +++ /dev/null @@ -1,68 +0,0 @@ -package stack - -import ( - "errors" - - "github.com/pterm/pterm" - - "kusionstack.io/kusion/pkg/log" -) - -const File = "stack.yaml" - -var ( - ErrNotStackDirectory = errors.New("path must be a stack directory") - ErrStackNotUnique = errors.New("the stack obtained is not unique") -) - -// Configuration is the stack configuration -type Configuration struct { - Name string `json:"name" yaml:"name"` // Stack name -} - -type Stack struct { - Configuration `json:",inline" yaml:",inline"` - Path string `json:"path,omitempty" yaml:"path,omitempty"` // Absolute path to the stack directory -} - -// NewStack creates a new stack -func NewStack(config *Configuration, path string) *Stack { - return &Stack{ - Configuration: *config, - Path: path, - } -} - -// GetName returns the name of the stack -func (s *Stack) GetName() string { - return s.Name -} - -// GetPath returns the path of the stack -func (s *Stack) GetPath() string { - return s.Path -} - -// TableReport returns the report string of table format -func (s *Stack) TableReport() string { - // Fill table header - tableHeader := []string{"Type", "Name"} - tableData := pterm.TableData{tableHeader} - - // Fill table content - tableData = append(tableData, []string{"Stack Name", s.GetName()}) - if s.GetPath() != "" { - tableData = append(tableData, []string{"Stack Path", s.GetPath()}) - } - - // Render table - report, err := pterm.DefaultTable.WithHasHeader(). - WithBoxed(true). - WithData(tableData). - Srender() - if err != nil { - log.Warn(err) - } - - return report -} diff --git a/pkg/cmd/apply/options.go b/pkg/cmd/apply/options.go index 1ef1a5c7..fb615af6 100644 --- a/pkg/cmd/apply/options.go +++ b/pkg/cmd/apply/options.go @@ -11,7 +11,6 @@ import ( "github.com/pterm/pterm" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" "kusionstack.io/kusion/pkg/apis/status" "kusionstack.io/kusion/pkg/cmd/build" cmdintent "kusionstack.io/kusion/pkg/cmd/build/builders" @@ -22,6 +21,7 @@ import ( opsmodels "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/states" "kusionstack.io/kusion/pkg/log" + "kusionstack.io/kusion/pkg/project" "kusionstack.io/kusion/pkg/util/pretty" ) @@ -286,7 +286,7 @@ func Apply( cluster := o.Arguments["cluster"] _, st := ac.Apply(&operation.ApplyRequest{ Request: opsmodels.Request{ - Tenant: changes.Project().Tenant, + Tenant: "", Project: changes.Project(), Stack: changes.Stack(), Cluster: cluster, diff --git a/pkg/cmd/apply/options_test.go b/pkg/cmd/apply/options_test.go index 9d0da6c6..044e3e31 100644 --- a/pkg/cmd/apply/options_test.go +++ b/pkg/cmd/apply/options_test.go @@ -12,9 +12,8 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" "kusionstack.io/kusion/pkg/cmd/build" "kusionstack.io/kusion/pkg/cmd/build/builders" @@ -24,14 +23,15 @@ import ( "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/engine/runtime/kubernetes" "kusionstack.io/kusion/pkg/engine/states/local" + "kusionstack.io/kusion/pkg/project" ) func TestApplyOptions_Run(t *testing.T) { mockey.PatchConvey("Detail is true", t, func() { - mockeyPatchDetectProjectAndStack() - mockeyPatchBuildIntent() - mockeyPatchNewKubernetesRuntime() - mockeyPatchOperationPreview() + mockPatchDetectProjectAndStack() + mockPatchBuildIntent() + mockPatchNewKubernetesRuntime() + mockPatchOperationPreview() o := NewApplyOptions() o.Detail = true @@ -42,10 +42,10 @@ func TestApplyOptions_Run(t *testing.T) { }) mockey.PatchConvey("DryRun is true", t, func() { - mockeyPatchDetectProjectAndStack() - mockeyPatchBuildIntent() - mockeyPatchNewKubernetesRuntime() - mockeyPatchOperationPreview() + mockPatchDetectProjectAndStack() + mockPatchBuildIntent() + mockPatchNewKubernetesRuntime() + mockPatchOperationPreview() mockOperationApply(opsmodels.Success) o := NewApplyOptions() @@ -57,38 +57,33 @@ func TestApplyOptions_Run(t *testing.T) { } var ( - p = &project.Project{ - Configuration: project.Configuration{ - Name: "testdata", - Tenant: "admin", - }, + p = &apiv1.Project{ + Name: "testdata", } - s = &stack.Stack{ - Configuration: stack.Configuration{ - Name: "dev", - }, + s = &apiv1.Stack{ + Name: "dev", } ) -func mockeyPatchDetectProjectAndStack() *mockey.Mocker { - return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*project.Project, *stack.Stack, error) { +func mockPatchDetectProjectAndStack() *mockey.Mocker { + return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) { p.Path = stackDir s.Path = stackDir return p, s, nil }).Build() } -func mockeyPatchBuildIntent() *mockey.Mocker { +func mockPatchBuildIntent() *mockey.Mocker { return mockey.Mock(build.Intent).To(func( o *builders.Options, - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, ) (*intent.Intent, error) { return &intent.Intent{Resources: []intent.Resource{sa1, sa2, sa3}}, nil }).Build() } -func mockeyPatchNewKubernetesRuntime() *mockey.Mocker { +func mockPatchNewKubernetesRuntime() *mockey.Mocker { return mockey.Mock(kubernetes.NewKubernetesRuntime).To(func() (runtime.Runtime, error) { return &fakerRuntime{}, nil }).Build() @@ -130,7 +125,7 @@ func (f *fakerRuntime) Watch(ctx context.Context, request *runtime.WatchRequest) return nil } -func mockeyPatchOperationPreview() *mockey.Mocker { +func mockPatchOperationPreview() *mockey.Mocker { return mockey.Mock((*operation.PreviewOperation).Preview).To(func( *operation.PreviewOperation, *operation.PreviewRequest, diff --git a/pkg/cmd/build/builders/appconfig_builder.go b/pkg/cmd/build/builders/appconfig_builder.go index b7d3dda9..d35137df 100644 --- a/pkg/cmd/build/builders/appconfig_builder.go +++ b/pkg/cmd/build/builders/appconfig_builder.go @@ -3,8 +3,6 @@ package builders import ( "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/generators" "kusionstack.io/kusion/pkg/modules/inputs" @@ -17,8 +15,8 @@ type AppsConfigBuilder struct { func (acg *AppsConfigBuilder) Build( _ *Options, - project *project.Project, - stack *stack.Stack, + project *v1.Project, + stack *v1.Stack, ) (*intent.Intent, error) { i := &intent.Intent{ Resources: []intent.Resource{}, diff --git a/pkg/cmd/build/builders/appconfig_builder_test.go b/pkg/cmd/build/builders/appconfig_builder_test.go index 257db5a4..b3e8d9b7 100644 --- a/pkg/cmd/build/builders/appconfig_builder_test.go +++ b/pkg/cmd/build/builders/appconfig_builder_test.go @@ -6,8 +6,6 @@ import ( "github.com/stretchr/testify/assert" "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" appmodel "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/workload" "kusionstack.io/kusion/pkg/modules/inputs/workload/network" @@ -86,17 +84,13 @@ func buildMockWorkspace() *v1.Workspace { } } -func buildMockProjectAndStack() (*project.Project, *stack.Stack) { - p := &project.Project{ - Configuration: project.Configuration{ - Name: "test-project", - }, +func buildMockProjectAndStack() (*v1.Project, *v1.Stack) { + p := &v1.Project{ + Name: "test-project", } - s := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "test-stack", - }, + s := &v1.Stack{ + Name: "test-project", } return p, s diff --git a/pkg/cmd/build/builders/builder.go b/pkg/cmd/build/builders/builder.go index 6570164c..0fa5abff 100644 --- a/pkg/cmd/build/builders/builder.go +++ b/pkg/cmd/build/builders/builder.go @@ -1,16 +1,15 @@ package builders import ( + v1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" ) // Builder represents a method to build an Intent. Typically, it is implemented by the AppConfigureBuilder, // but we have designed it as an interface to allow for more general usage. Any struct that implements this interface // is considered a Builder and can be integrated into the Kusion workflow. type Builder interface { - Build(o *Options, project *project.Project, stack *stack.Stack) (*intent.Intent, error) + Build(o *Options, project *v1.Project, stack *v1.Stack) (*intent.Intent, error) } type Options struct { diff --git a/pkg/cmd/build/builders/kcl/kcl_builder.go b/pkg/cmd/build/builders/kcl/kcl_builder.go index 69f466cd..22b8cd63 100644 --- a/pkg/cmd/build/builders/kcl/kcl_builder.go +++ b/pkg/cmd/build/builders/kcl/kcl_builder.go @@ -16,9 +16,8 @@ import ( "kcl-lang.io/kpm/pkg/api" "kcl-lang.io/kpm/pkg/opt" + v1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/cmd/build/builders" "kusionstack.io/kusion/pkg/cmd/build/builders/crd" "kusionstack.io/kusion/pkg/cmd/build/builders/kcl/rest" @@ -52,7 +51,7 @@ func EnableRPC() bool { return !enableRest } -func (g *Builder) Build(o *builders.Options, _ *project.Project, stack *stack.Stack) (*intent.Intent, error) { +func (g *Builder) Build(o *builders.Options, _ *v1.Project, stack *v1.Stack) (*intent.Intent, error) { compileResult, err := Run(o, stack) if err != nil { return nil, err @@ -66,7 +65,7 @@ func (g *Builder) Build(o *builders.Options, _ *project.Project, stack *stack.St return i, nil } -func Run(o *builders.Options, stack *stack.Stack) (*CompileResult, error) { +func Run(o *builders.Options, stack *v1.Stack) (*CompileResult, error) { optList, err := BuildKCLOptions(o) if err != nil { return nil, err diff --git a/pkg/cmd/build/builders/kcl/kcl_builder_test.go b/pkg/cmd/build/builders/kcl/kcl_builder_test.go index aa1be25d..fbd57610 100644 --- a/pkg/cmd/build/builders/kcl/kcl_builder_test.go +++ b/pkg/cmd/build/builders/kcl/kcl_builder_test.go @@ -11,8 +11,8 @@ import ( kcl "kcl-lang.io/kcl-go" "kcl-lang.io/kcl-go/pkg/spec/gpyrpc" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/cmd/build/builders" "kusionstack.io/kusion/pkg/cmd/build/builders/kcl/rest" ) @@ -31,10 +31,8 @@ func TestInit(t *testing.T) { } func TestGenerateIntent(t *testing.T) { - fakeStack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "fake-stack", - }, + fakeStack := &v1.Stack{ + Name: "fake-stack", Path: filepath.Join(".", "testdata"), } diff --git a/pkg/cmd/build/options.go b/pkg/cmd/build/options.go index bc3ce5e1..76ed4d05 100644 --- a/pkg/cmd/build/options.go +++ b/pkg/cmd/build/options.go @@ -9,9 +9,12 @@ import ( yamlv2 "gopkg.in/yaml.v2" "kcl-lang.io/kpm/pkg/api" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/cmd/build/builders" + "kusionstack.io/kusion/pkg/project" +) + +const ( + KclFile = "kcl.yaml" ) type Options struct { @@ -42,7 +45,7 @@ func NewBuildOptions() *Options { func (o *Options) Complete(args []string) error { o.Filenames = args - return o.PreSet(stack.IsStack) + return o.PreSet(project.IsStack) } func (o *Options) Validate() error { @@ -124,7 +127,7 @@ func (o *Options) PreSet(preCheck func(cur string) bool) error { } if len(o.Settings) == 0 { - o.Settings = []string{project.KclFile} + o.Settings = []string{KclFile} } return nil } diff --git a/pkg/cmd/build/options_test.go b/pkg/cmd/build/options_test.go index 2e6721be..fe581b9f 100644 --- a/pkg/cmd/build/options_test.go +++ b/pkg/cmd/build/options_test.go @@ -9,11 +9,11 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/cmd/build/builders" "kusionstack.io/kusion/pkg/engine" + "kusionstack.io/kusion/pkg/project" ) var ( @@ -21,16 +21,11 @@ var ( kind = "ServiceAccount" namespace = "test-ns" - p = &project.Project{ - Configuration: project.Configuration{ - Name: "testdata", - Tenant: "admin", - }, + p = &apiv1.Project{ + Name: "testdata", } - s = &stack.Stack{ - Configuration: stack.Configuration{ - Name: "dev", - }, + s = &apiv1.Stack{ + Name: "dev", } sa1 = newSA("sa1") @@ -140,7 +135,7 @@ func newSA(name string) intent.Resource { } func mockDetectProjectAndStack() *mockey.Mocker { - return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*project.Project, *stack.Stack, error) { + return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) { p.Path = stackDir s.Path = stackDir return p, s, nil @@ -148,7 +143,7 @@ func mockDetectProjectAndStack() *mockey.Mocker { } func mockDetectProjectAndStackFail() *mockey.Mocker { - return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*project.Project, *stack.Stack, error) { + return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) { p.Path = stackDir s.Path = stackDir return p, s, errTest @@ -158,8 +153,8 @@ func mockDetectProjectAndStackFail() *mockey.Mocker { func mockGenerateIntent() *mockey.Mocker { return mockey.Mock(IntentWithSpinner).To(func( o *builders.Options, - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, ) (*intent.Intent, error) { return &intent.Intent{Resources: []intent.Resource{sa1, sa2, sa3}}, nil }).Build() @@ -168,8 +163,8 @@ func mockGenerateIntent() *mockey.Mocker { func mockGenerateIntentFail() *mockey.Mocker { return mockey.Mock(IntentWithSpinner).To(func( o *builders.Options, - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, ) (*intent.Intent, error) { return &intent.Intent{Resources: []intent.Resource{sa1, sa2, sa3}}, errTest }).Build() diff --git a/pkg/cmd/build/util.go b/pkg/cmd/build/util.go index fd184ac1..0e2d4d12 100644 --- a/pkg/cmd/build/util.go +++ b/pkg/cmd/build/util.go @@ -12,9 +12,8 @@ import ( "gopkg.in/yaml.v2" yamlv3 "gopkg.in/yaml.v3" + v1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/cmd/build/builders" "kusionstack.io/kusion/pkg/cmd/build/builders/kcl" "kusionstack.io/kusion/pkg/log" @@ -23,7 +22,7 @@ import ( workspace "kusionstack.io/kusion/pkg/workspace" ) -func IntentWithSpinner(o *builders.Options, project *project.Project, stack *stack.Stack) (*intent.Intent, error) { +func IntentWithSpinner(o *builders.Options, project *v1.Project, stack *v1.Stack) (*intent.Intent, error) { var sp *pterm.SpinnerPrinter if o.NoStyle { fmt.Printf("Generating Intent in the Stack %s...\n", stack.Name) @@ -56,29 +55,29 @@ func IntentWithSpinner(o *builders.Options, project *project.Project, stack *sta return i, nil } -func Intent(o *builders.Options, p *project.Project, s *stack.Stack) (*intent.Intent, error) { +func Intent(o *builders.Options, p *v1.Project, s *v1.Stack) (*intent.Intent, error) { // Choose the generator var builder builders.Builder pg := p.Generator // default AppsConfigBuilder - var bt project.BuilderType + var bt v1.BuilderType if pg == nil { - bt = project.AppConfigurationBuilder + bt = v1.AppConfigurationBuilder } else { bt = pg.Type } // we can add more generators here switch bt { - case project.KCLBuilder: + case v1.KCLBuilder: builder = &kcl.Builder{} - case project.AppConfigurationBuilder: + case v1.AppConfigurationBuilder: appConfigs, err := buildAppConfigs(o, s) if err != nil { return nil, err } - ws, err := workspace.GetWorkspaceByDefaultOperator(s.GetName()) + ws, err := workspace.GetWorkspaceByDefaultOperator(s.Name) if err != nil { return nil, err } @@ -97,7 +96,7 @@ func Intent(o *builders.Options, p *project.Project, s *stack.Stack) (*intent.In return i, nil } -func buildAppConfigs(o *builders.Options, stack *stack.Stack) (map[string]inputs.AppConfiguration, error) { +func buildAppConfigs(o *builders.Options, stack *v1.Stack) (map[string]inputs.AppConfiguration, error) { o.Arguments[kcl.IncludeSchemaTypePath] = "true" compileResult, err := kcl.Run(o, stack) if err != nil { diff --git a/pkg/cmd/build/util_test.go b/pkg/cmd/build/util_test.go index e54ca9ea..694b8e89 100644 --- a/pkg/cmd/build/util_test.go +++ b/pkg/cmd/build/util_test.go @@ -12,8 +12,6 @@ import ( "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/cmd/build/builders" "kusionstack.io/kusion/pkg/cmd/build/builders/kcl" appconfigmodel "kusionstack.io/kusion/pkg/modules/inputs" @@ -207,8 +205,8 @@ func TestBuildIntent(t *testing.T) { type args struct { o *builders.Options - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack mockers []*mockey.MockBuilder } tests := []struct { @@ -220,16 +218,14 @@ func TestBuildIntent(t *testing.T) { { name: "nil builder", args: struct { o *builders.Options - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack mockers []*mockey.MockBuilder }{ o: &builders.Options{Arguments: map[string]string{}}, - project: &project.Project{ - Configuration: project.Configuration{ - Name: "default", - }, - }, stack: &stack.Stack{}, + project: &v1.Project{ + Name: "default", + }, stack: &v1.Stack{}, mockers: []*mockey.MockBuilder{ mockey.Mock(kcl.Run).Return(&kcl.CompileResult{Documents: []kclgo.KCLResult{apcMap}}, nil), mockey.Mock(workspace.GetWorkspaceByDefaultOperator).Return(ws, nil), @@ -240,19 +236,17 @@ func TestBuildIntent(t *testing.T) { { name: "kcl builder", args: struct { o *builders.Options - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack mockers []*mockey.MockBuilder }{ o: &builders.Options{}, - project: &project.Project{ - Configuration: project.Configuration{ - Generator: &project.GeneratorConfig{ - Type: project.KCLBuilder, - }, + project: &v1.Project{ + Generator: &v1.GeneratorConfig{ + Type: v1.KCLBuilder, }, }, - stack: &stack.Stack{}, + stack: &v1.Stack{}, mockers: []*mockey.MockBuilder{ mockey.Mock((*kcl.Builder).Build).Return(nil, nil), }, @@ -262,23 +256,19 @@ func TestBuildIntent(t *testing.T) { { name: "app builder", args: struct { o *builders.Options - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack mockers []*mockey.MockBuilder }{ o: &builders.Options{Arguments: map[string]string{}}, - project: &project.Project{ - Configuration: project.Configuration{ - Name: "default", - Generator: &project.GeneratorConfig{ - Type: project.AppConfigurationBuilder, - }, + project: &v1.Project{ + Name: "default", + Generator: &v1.GeneratorConfig{ + Type: v1.AppConfigurationBuilder, }, }, - stack: &stack.Stack{ - Configuration: stack.Configuration{ - Name: "default", - }, + stack: &v1.Stack{ + Name: "default", }, mockers: []*mockey.MockBuilder{ mockey.Mock(kcl.Run).Return(&kcl.CompileResult{Documents: []kclgo.KCLResult{apcMap}}, nil), diff --git a/pkg/cmd/deps/deps_test.go b/pkg/cmd/deps/deps_test.go index d89fe36c..88ed45e2 100644 --- a/pkg/cmd/deps/deps_test.go +++ b/pkg/cmd/deps/deps_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" - "kusionstack.io/kusion/pkg/apis/project" + "kusionstack.io/kusion/pkg/project" ) var workDir string diff --git a/pkg/cmd/deps/options.go b/pkg/cmd/deps/options.go index 7a51a8aa..0c272df4 100644 --- a/pkg/cmd/deps/options.go +++ b/pkg/cmd/deps/options.go @@ -10,7 +10,12 @@ import ( kcl "kcl-lang.io/kcl-go" "kcl-lang.io/kcl-go/pkg/tools/list" - "kusionstack.io/kusion/pkg/apis/project" + v1 "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/project" +) + +const ( + KclFile = "kcl.yaml" ) type Options struct { @@ -140,7 +145,7 @@ func (o *Options) Run() (err error) { } // 3. Find all the projects under the workdir - var projects []*project.Project + var projects []*v1.Project if projects, err = project.FindAllProjectsFrom(workDir); err != nil { return } @@ -179,7 +184,7 @@ func (o *Options) Run() (err error) { // Do not call this function with high frequency and please ensure at least 10 seconds interval when calling. func findDownStreams( workDir string, - projects []*project.Project, + projects []*v1.Project, focusPaths, shouldIgnore stringSet, projectOnly bool, ) (downStreams stringSet, err error) { @@ -191,10 +196,10 @@ func findDownStreams( // To list downstream stacks/projects, wee need to go through all the entrance files under each project/stack, // then filter out the ones that are downstream of the focus files for _, p := range projects { - projectRel, _ := filepath.Rel(workDir, p.GetPath()) + projectRel, _ := filepath.Rel(workDir, p.Path) for _, stack := range p.Stacks { // 1.1 Get the relative path of project/stack - stackRel, _ := filepath.Rel(workDir, stack.GetPath()) + stackRel, _ := filepath.Rel(workDir, stack.Path) var stackProjectPath string if projectOnly { stackProjectPath = projectRel @@ -222,7 +227,7 @@ func findDownStreams( continue } // 1.3 Collect and index all the entrance files of the stack by loading the settings file - settingsPath := filepath.Join(stack.GetPath(), project.KclFile) + settingsPath := filepath.Join(stack.Path, KclFile) opt := kcl.WithSettings(settingsPath) if opt.Err != nil { // The stack settings is invalid diff --git a/pkg/cmd/deps/testdata/appops/projectA/project.yaml b/pkg/cmd/deps/testdata/appops/projectA/project.yaml index e69de29b..6a564b1a 100644 --- a/pkg/cmd/deps/testdata/appops/projectA/project.yaml +++ b/pkg/cmd/deps/testdata/appops/projectA/project.yaml @@ -0,0 +1 @@ +name: projectA \ No newline at end of file diff --git a/pkg/cmd/deps/testdata/appops/projectB/project.yaml b/pkg/cmd/deps/testdata/appops/projectB/project.yaml index e69de29b..0cee7e44 100644 --- a/pkg/cmd/deps/testdata/appops/projectB/project.yaml +++ b/pkg/cmd/deps/testdata/appops/projectB/project.yaml @@ -0,0 +1 @@ +name: projectB \ No newline at end of file diff --git a/pkg/cmd/deps/testdata/appops/projectC/project.yaml b/pkg/cmd/deps/testdata/appops/projectC/project.yaml index e69de29b..8a85c95e 100644 --- a/pkg/cmd/deps/testdata/appops/projectC/project.yaml +++ b/pkg/cmd/deps/testdata/appops/projectC/project.yaml @@ -0,0 +1 @@ +name: projectC \ No newline at end of file diff --git a/pkg/cmd/destroy/options.go b/pkg/cmd/destroy/options.go index b03e5c93..c808def7 100644 --- a/pkg/cmd/destroy/options.go +++ b/pkg/cmd/destroy/options.go @@ -9,9 +9,8 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/pterm/pterm" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" "kusionstack.io/kusion/pkg/cmd/build" "kusionstack.io/kusion/pkg/engine/backend" @@ -19,6 +18,7 @@ import ( opsmodels "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/states" "kusionstack.io/kusion/pkg/log" + "kusionstack.io/kusion/pkg/project" jsonutil "kusionstack.io/kusion/pkg/util/json" "kusionstack.io/kusion/pkg/util/signals" ) @@ -71,7 +71,7 @@ func (o *Options) Run() error { // only destroy resources we managed // todo add the `cluster` field in query query := &states.StateQuery{ - Tenant: project.Tenant, + Tenant: "", Stack: stack.Name, Project: project.Name, } @@ -134,8 +134,8 @@ func (o *Options) Run() error { } func (o *Options) preview( - planResources *intent.Intent, project *project.Project, - stack *stack.Stack, stateStorage states.StateStorage, + planResources *intent.Intent, project *apiv1.Project, + stack *apiv1.Stack, stateStorage states.StateStorage, ) (*opsmodels.Changes, error) { log.Info("Start compute preview changes ...") @@ -152,7 +152,7 @@ func (o *Options) preview( rsp, s := pc.Preview(&operation.PreviewRequest{ Request: opsmodels.Request{ - Tenant: project.Tenant, + Tenant: "", Project: project, Operator: o.Operator, Stack: stack, @@ -244,7 +244,7 @@ func (o *Options) destroy(planResources *intent.Intent, changes *opsmodels.Chang st := do.Destroy(&operation.DestroyRequest{ Request: opsmodels.Request{ - Tenant: changes.Project().Tenant, + Tenant: "", Project: changes.Project(), Operator: o.Operator, Stack: changes.Stack(), diff --git a/pkg/cmd/destroy/options_test.go b/pkg/cmd/destroy/options_test.go index 863c0af0..6d0b2766 100644 --- a/pkg/cmd/destroy/options_test.go +++ b/pkg/cmd/destroy/options_test.go @@ -11,9 +11,8 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" "kusionstack.io/kusion/pkg/engine" "kusionstack.io/kusion/pkg/engine/operation" @@ -22,6 +21,7 @@ import ( "kusionstack.io/kusion/pkg/engine/runtime/kubernetes" "kusionstack.io/kusion/pkg/engine/states" "kusionstack.io/kusion/pkg/engine/states/local" + "kusionstack.io/kusion/pkg/project" ) func TestDestroyOptions_Run(t *testing.T) { @@ -64,21 +64,16 @@ func TestDestroyOptions_Run(t *testing.T) { } var ( - p = &project.Project{ - Configuration: project.Configuration{ - Name: "testdata", - Tenant: "admin", - }, + p = &apiv1.Project{ + Name: "testdata", } - s = &stack.Stack{ - Configuration: stack.Configuration{ - Name: "dev", - }, + s = &apiv1.Stack{ + Name: "dev", } ) func mockDetectProjectAndStack() { - mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*project.Project, *stack.Stack, error) { + mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) { p.Path = stackDir s.Path = stackDir return p, s, nil diff --git a/pkg/cmd/preview/options.go b/pkg/cmd/preview/options.go index 66318996..2939648c 100644 --- a/pkg/cmd/preview/options.go +++ b/pkg/cmd/preview/options.go @@ -10,9 +10,8 @@ import ( "github.com/pkg/errors" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" "kusionstack.io/kusion/pkg/cmd/build" "kusionstack.io/kusion/pkg/cmd/build/builders" @@ -21,6 +20,7 @@ import ( opsmodels "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/states" "kusionstack.io/kusion/pkg/log" + "kusionstack.io/kusion/pkg/project" "kusionstack.io/kusion/pkg/util/pretty" ) @@ -229,8 +229,8 @@ func Preview( o *Options, storage states.StateStorage, planResources *intent.Intent, - project *project.Project, - stack *stack.Stack, + project *v1.Project, + stack *v1.Stack, ) (*opsmodels.Changes, error) { log.Info("Start compute preview changes ...") @@ -251,7 +251,7 @@ func Preview( cluster := o.Arguments["cluster"] rsp, s := pc.Preview(&operation.PreviewRequest{ Request: opsmodels.Request{ - Tenant: project.Tenant, + Tenant: "", Project: project, Stack: stack, Operator: o.Operator, diff --git a/pkg/cmd/preview/options_test.go b/pkg/cmd/preview/options_test.go index a09fde7e..0522ef53 100644 --- a/pkg/cmd/preview/options_test.go +++ b/pkg/cmd/preview/options_test.go @@ -10,9 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" "kusionstack.io/kusion/pkg/cmd/build" "kusionstack.io/kusion/pkg/cmd/build/builders" @@ -22,6 +21,7 @@ import ( "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/engine/runtime/kubernetes" "kusionstack.io/kusion/pkg/engine/states/local" + "kusionstack.io/kusion/pkg/project" ) var ( @@ -29,16 +29,11 @@ var ( kind = "ServiceAccount" namespace = "test-ns" - p = &project.Project{ - Configuration: project.Configuration{ - Name: "testdata", - Tenant: "admin", - }, + p = &apiv1.Project{ + Name: "testdata", } - s = &stack.Stack{ - Configuration: stack.Configuration{ - Name: "dev", - }, + s = &apiv1.Stack{ + Name: "dev", } sa1 = newSA("sa1") @@ -229,7 +224,7 @@ func newSA(name string) intent.Resource { } func mockDetectProjectAndStack() *mockey.Mocker { - return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*project.Project, *stack.Stack, error) { + return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) { p.Path = stackDir s.Path = stackDir return p, s, nil @@ -239,8 +234,8 @@ func mockDetectProjectAndStack() *mockey.Mocker { func mockBuildIntent() *mockey.Mocker { return mockey.Mock(build.Intent).To(func( o *builders.Options, - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, ) (*intent.Intent, error) { return &intent.Intent{Resources: []intent.Resource{sa1, sa2, sa3}}, nil }).Build() @@ -249,8 +244,8 @@ func mockBuildIntent() *mockey.Mocker { func mockPatchBuildIntentWithSpinner() *mockey.Mocker { return mockey.Mock(build.IntentWithSpinner).To(func( o *builders.Options, - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, ) (*intent.Intent, error) { return &intent.Intent{Resources: []intent.Resource{sa1, sa2, sa3}}, nil }).Build() diff --git a/pkg/engine/backend/util.go b/pkg/engine/backend/util.go index e7893112..5ebee417 100644 --- a/pkg/engine/backend/util.go +++ b/pkg/engine/backend/util.go @@ -4,13 +4,12 @@ import ( "fmt" "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/engine/states" "kusionstack.io/kusion/pkg/workspace" ) // NewStateStorage news a StateStorage by configs of workspace, cli backend options, and environment variables. -func NewStateStorage(stack *stack.Stack, opts *BackendOptions) (states.StateStorage, error) { +func NewStateStorage(stack *v1.Stack, opts *BackendOptions) (states.StateStorage, error) { var backendConfigs *v1.BackendConfigs wsOperator, err := workspace.NewValidDefaultOperator() if err != nil { diff --git a/pkg/engine/backend/util_test.go b/pkg/engine/backend/util_test.go index 13817e98..e6bdf289 100644 --- a/pkg/engine/backend/util_test.go +++ b/pkg/engine/backend/util_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/assert" "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/util/kfile" ) @@ -19,11 +18,9 @@ func testDataFolder() string { return path.Join(pwd, "testdata") } -func mockStack(name string) *stack.Stack { - return &stack.Stack{ - Configuration: stack.Configuration{ - Name: name, - }, +func mockStack(name string) *v1.Stack { + return &v1.Stack{ + Name: name, Path: fmt.Sprintf("/test_project/%s", name), } } @@ -32,7 +29,7 @@ func Test_NewStateStorage(t *testing.T) { testcases := []struct { name string success bool - stack *stack.Stack + stack *v1.Stack opts *BackendOptions setEnvFunc, unsetEnvFunc func() }{ diff --git a/pkg/engine/operation/apply_test.go b/pkg/engine/operation/apply_test.go index 5d2f5529..ee215896 100644 --- a/pkg/engine/operation/apply_test.go +++ b/pkg/engine/operation/apply_test.go @@ -10,9 +10,8 @@ import ( _ "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/assert" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" "kusionstack.io/kusion/pkg/engine/operation/graph" opsmodels "kusionstack.io/kusion/pkg/engine/operation/models" @@ -68,7 +67,7 @@ func TestOperation_Apply(t *testing.T) { StateResourceIndex map[string]*intent.Resource Order *opsmodels.ChangeOrder RuntimeMap map[intent.Type]runtime.Runtime - Stack *stack.Stack + Stack *apiv1.Stack MsgCh chan opsmodels.Message resultState *states.State lock *sync.Mutex @@ -110,17 +109,14 @@ func TestOperation_Apply(t *testing.T) { }, } - s := &stack.Stack{ - Configuration: stack.Configuration{Name: "fakeStack"}, - Path: "fakePath", + s := &apiv1.Stack{ + Name: "fakeStack", + Path: "fakePath", } - p := &project.Project{ - Configuration: project.Configuration{ - Name: "fakeProject", - Tenant: "fakeTenant", - }, + p := &apiv1.Project{ + Name: "fakeProject", Path: "fakePath", - Stacks: []*stack.Stack{s}, + Stacks: []*apiv1.Stack{s}, } tests := []struct { diff --git a/pkg/engine/operation/destory_test.go b/pkg/engine/operation/destory_test.go index 7773f548..864b4608 100644 --- a/pkg/engine/operation/destory_test.go +++ b/pkg/engine/operation/destory_test.go @@ -10,9 +10,8 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" "kusionstack.io/kusion/pkg/engine/operation/graph" opsmodels "kusionstack.io/kusion/pkg/engine/operation/models" @@ -28,17 +27,14 @@ func TestOperation_Destroy(t *testing.T) { operator = "foo_user" ) - s := &stack.Stack{ - Configuration: stack.Configuration{Name: "fake-name"}, - Path: "fake-path", + s := &apiv1.Stack{ + Name: "fake-name", + Path: "fake-path", } - p := &project.Project{ - Configuration: project.Configuration{ - Name: "fake-name", - Tenant: "fake-tenant", - }, + p := &apiv1.Project{ + Name: "fake-name", Path: "fake-path", - Stacks: []*stack.Stack{s}, + Stacks: []*apiv1.Stack{s}, } resourceState := intent.Resource{ diff --git a/pkg/engine/operation/models/change.go b/pkg/engine/operation/models/change.go index 6db1e6b5..88f1cf46 100644 --- a/pkg/engine/operation/models/change.go +++ b/pkg/engine/operation/models/change.go @@ -9,9 +9,8 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/pterm/pterm" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/log" "kusionstack.io/kusion/pkg/util/diff" "kusionstack.io/kusion/pkg/util/pretty" @@ -85,8 +84,8 @@ var ( type Changes struct { *ChangeOrder `json:",inline" yaml:",inline"` - project *project.Project // the project of current changes - stack *stack.Stack // the stack of current changes + project *v1.Project // the project of current changes + stack *v1.Stack // the stack of current changes } type ChangeOrder struct { @@ -94,7 +93,7 @@ type ChangeOrder struct { ChangeSteps map[string]*ChangeStep `json:"changeSteps,omitempty" yaml:"changeSteps,omitempty"` } -func NewChanges(p *project.Project, s *stack.Stack, order *ChangeOrder) *Changes { +func NewChanges(p *v1.Project, s *v1.Stack, order *ChangeOrder) *Changes { return &Changes{ ChangeOrder: order, project: p, @@ -129,11 +128,11 @@ func (o *ChangeOrder) Values(filters ...ChangeStepFilterFunc) []*ChangeStep { return result } -func (p *Changes) Stack() *stack.Stack { +func (p *Changes) Stack() *v1.Stack { return p.stack } -func (p *Changes) Project() *project.Project { +func (p *Changes) Project() *v1.Project { return p.project } diff --git a/pkg/engine/operation/models/change_test.go b/pkg/engine/operation/models/change_test.go index 703b412a..80d8259c 100644 --- a/pkg/engine/operation/models/change_test.go +++ b/pkg/engine/operation/models/change_test.go @@ -7,9 +7,8 @@ import ( "github.com/stretchr/testify/assert" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/util/pretty" ) @@ -150,8 +149,8 @@ func TestChangeStep_Diff(t *testing.T) { func TestChanges_Get(t *testing.T) { type fields struct { order *ChangeOrder - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack } type args struct { key string @@ -194,8 +193,8 @@ func TestChanges_Get(t *testing.T) { func TestChanges_Values(t *testing.T) { type fields struct { order *ChangeOrder - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack } type args struct { filters []ChangeStepFilterFunc @@ -276,30 +275,26 @@ func TestChanges_Values(t *testing.T) { func TestChanges_Stack(t *testing.T) { type fields struct { order *ChangeOrder - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack } tests := []struct { name string fields fields - want *stack.Stack + want *v1.Stack }{ { name: "t1", fields: fields{ order: &ChangeOrder{StepKeys: []string{}, ChangeSteps: map[string]*ChangeStep{}}, - project: &project.Project{}, - stack: &stack.Stack{ - Configuration: stack.Configuration{ - Name: "test-name", - }, + project: &v1.Project{}, + stack: &v1.Stack{ + Name: "test-name", Path: "test-path", }, }, - want: &stack.Stack{ - Configuration: stack.Configuration{ - Name: "test-name", - }, + want: &v1.Stack{ + Name: "test-name", Path: "test-path", }, }, @@ -321,30 +316,24 @@ func TestChanges_Stack(t *testing.T) { func TestChanges_Project(t *testing.T) { type fields struct { order *ChangeOrder - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack } tests := []struct { name string fields fields - want *project.Project + want *v1.Project }{ { name: "t1", fields: fields{ - project: &project.Project{ - Configuration: project.Configuration{ - Name: "test-name", - Tenant: "test-tenant", - }, + project: &v1.Project{ + Name: "test-name", Path: "test-path", }, }, - want: &project.Project{ - Configuration: project.Configuration{ - Name: "test-name", - Tenant: "test-tenant", - }, + want: &v1.Project{ + Name: "test-name", Path: "test-path", }, }, @@ -362,8 +351,8 @@ func TestChanges_Project(t *testing.T) { func TestChanges_Diffs(t *testing.T) { type fields struct { order *ChangeOrder - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack } tests := []struct { name string @@ -404,8 +393,8 @@ func TestChanges_Diffs(t *testing.T) { func TestChanges_Preview(t *testing.T) { type fields struct { order *ChangeOrder - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack } tests := []struct { name string @@ -420,10 +409,8 @@ func TestChanges_Preview(t *testing.T) { "test-key": TestChangeStepOpCreate, }, }, - stack: &stack.Stack{ - Configuration: stack.Configuration{ - Name: "test-name", - }, + stack: &v1.Stack{ + Name: "test-name", }, }, }, diff --git a/pkg/engine/operation/models/operation_context.go b/pkg/engine/operation/models/operation_context.go index cac2e3ad..3b65791d 100644 --- a/pkg/engine/operation/models/operation_context.go +++ b/pkg/engine/operation/models/operation_context.go @@ -6,9 +6,8 @@ import ( "github.com/jinzhu/copier" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/engine/states" "kusionstack.io/kusion/pkg/log" @@ -43,7 +42,7 @@ type Operation struct { RuntimeMap map[intent.Type]runtime.Runtime // Stack contains info about where this command is invoked - Stack *stack.Stack + Stack *v1.Stack // MsgCh is used to send operation status like Success, Failed or Skip to Kusion CTl, // and this message will be displayed in the terminal @@ -63,12 +62,12 @@ type Message struct { } type Request struct { - Tenant string `json:"tenant"` - Project *project.Project `json:"project"` - Stack *stack.Stack `json:"stack"` - Cluster string `json:"cluster"` - Operator string `json:"operator"` - Intent *intent.Intent `json:"intent"` + Tenant string `json:"tenant"` + Project *v1.Project `json:"project"` + Stack *v1.Stack `json:"stack"` + Cluster string `json:"cluster"` + Operator string `json:"operator"` + Intent *intent.Intent `json:"intent"` } type OpResult string diff --git a/pkg/engine/operation/preview_test.go b/pkg/engine/operation/preview_test.go index 6eaf19f8..667490ac 100644 --- a/pkg/engine/operation/preview_test.go +++ b/pkg/engine/operation/preview_test.go @@ -9,9 +9,8 @@ import ( "github.com/bytedance/mockey" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" opsmodels "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/runtime" @@ -102,17 +101,14 @@ func TestOperation_Preview(t *testing.T) { type args struct { request *PreviewRequest } - s := &stack.Stack{ - Configuration: stack.Configuration{Name: "fake-name"}, - Path: "fake-path", + s := &apiv1.Stack{ + Name: "fake-name", + Path: "fake-path", } - p := &project.Project{ - Configuration: project.Configuration{ - Name: "fake-name", - Tenant: "fake-tenant", - }, + p := &apiv1.Project{ + Name: "fake-name", Path: "fake-path", - Stacks: []*stack.Stack{s}, + Stacks: []*apiv1.Stack{s}, } tests := []struct { name string diff --git a/pkg/engine/runtime/runtime.go b/pkg/engine/runtime/runtime.go index 2a4664cd..b90e7b36 100644 --- a/pkg/engine/runtime/runtime.go +++ b/pkg/engine/runtime/runtime.go @@ -5,8 +5,8 @@ import ( "k8s.io/apimachinery/pkg/watch" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/apis/status" ) @@ -50,7 +50,7 @@ type ApplyRequest struct { PlanResource *intent.Resource // Stack contains info about where this command is invoked - Stack *stack.Stack + Stack *apiv1.Stack // DryRun means this a dry-run request and will not make any changes in actual infra DryRun bool @@ -72,7 +72,7 @@ type ReadRequest struct { PlanResource *intent.Resource // Stack contains info about where this command is invoked - Stack *stack.Stack + Stack *apiv1.Stack } type ReadResponse struct { @@ -88,7 +88,7 @@ type ImportRequest struct { PlanResource *intent.Resource // Stack contains info about where this command is invoked - Stack *stack.Stack + Stack *apiv1.Stack } type ImportResponse struct { @@ -104,7 +104,7 @@ type DeleteRequest struct { Resource *intent.Resource // Stack contains info about where this command is invoked - Stack *stack.Stack + Stack *apiv1.Stack } type DeleteResponse struct { diff --git a/pkg/engine/runtime/terraform/terraform_runtime.go b/pkg/engine/runtime/terraform/terraform_runtime.go index dfd27be8..ac81391d 100644 --- a/pkg/engine/runtime/terraform/terraform_runtime.go +++ b/pkg/engine/runtime/terraform/terraform_runtime.go @@ -38,7 +38,7 @@ func (t *TerraformRuntime) Apply(ctx context.Context, request *runtime.ApplyRequ defer t.mu.Unlock() plan := request.PlanResource - stackPath := request.Stack.GetPath() + stackPath := request.Stack.Path tfCacheDir := filepath.Join(stackPath, "."+plan.ResourceKey()) t.WorkSpace.SetStackDir(stackPath) t.WorkSpace.SetCacheDir(tfCacheDir) @@ -136,7 +136,7 @@ func (t *TerraformRuntime) Read(ctx context.Context, request *runtime.ReadReques t.mu.Lock() defer t.mu.Unlock() - stackPath := request.Stack.GetPath() + stackPath := request.Stack.Path tfCacheDir := filepath.Join(stackPath, "."+planResource.ResourceKey()) t.WorkSpace.SetStackDir(stackPath) t.WorkSpace.SetCacheDir(tfCacheDir) @@ -197,7 +197,7 @@ func (t *TerraformRuntime) Import(ctx context.Context, request *runtime.ImportRe // Delete terraform resource and remove workspace func (t *TerraformRuntime) Delete(ctx context.Context, request *runtime.DeleteRequest) (res *runtime.DeleteResponse) { - stackPath := request.Stack.GetPath() + stackPath := request.Stack.Path tfCacheDir := filepath.Join(stackPath, "."+request.Resource.ResourceKey()) t.mu.Lock() defer t.mu.Unlock() diff --git a/pkg/engine/runtime/terraform/terraform_runtime_test.go b/pkg/engine/runtime/terraform/terraform_runtime_test.go index c6f81a20..7ac9f2b0 100644 --- a/pkg/engine/runtime/terraform/terraform_runtime_test.go +++ b/pkg/engine/runtime/terraform/terraform_runtime_test.go @@ -13,8 +13,8 @@ import ( "github.com/spf13/afero" "github.com/stretchr/testify/assert" + "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/engine/runtime/terraform/tfops" ) @@ -40,11 +40,11 @@ var fakeSR = &tfops.StateRepresentation{ func TestTerraformRuntime(t *testing.T) { cwd, _ := os.Getwd() - stack := &stack.Stack{ - Configuration: stack.Configuration{Name: "fakeStack"}, - Path: filepath.Join(cwd, "fakePath"), + stack := &v1.Stack{ + Name: "fakeStack", + Path: filepath.Join(cwd, "fakePath"), } - defer os.RemoveAll(stack.GetPath()) + defer os.RemoveAll(stack.Path) tfRuntime := TerraformRuntime{ WorkSpace: *tfops.NewWorkSpace(afero.Afero{Fs: afero.NewOsFs()}), mu: &sync.Mutex{}, diff --git a/pkg/modules/generators/accessories/database/alicloud_rds_test.go b/pkg/modules/generators/accessories/database/alicloud_rds_test.go index 1915698a..105ca2c4 100644 --- a/pkg/modules/generators/accessories/database/alicloud_rds_test.go +++ b/pkg/modules/generators/accessories/database/alicloud_rds_test.go @@ -7,24 +7,19 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/accessories/database" "kusionstack.io/kusion/pkg/modules/inputs/workload" ) func TestGenerateAlicloudResources(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -82,15 +77,11 @@ func TestGenerateAlicloudDBInstance(t *testing.T) { alicloudProvider := &inputs.Provider{} alicloudProvider.SetString(defaultAlicloudProvider) - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -158,15 +149,11 @@ func TestGenerateAlicloudDBConnection(t *testing.T) { alicloudProvider := &inputs.Provider{} alicloudProvider.SetString(defaultAlicloudProvider) - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -219,15 +206,11 @@ func TestGenerateAlicloudRDSAccount(t *testing.T) { alicloudProvider := &inputs.Provider{} alicloudProvider.SetString(defaultAlicloudProvider) - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} diff --git a/pkg/modules/generators/accessories/database/aws_rds_test.go b/pkg/modules/generators/accessories/database/aws_rds_test.go index ca9a5fce..efebe064 100644 --- a/pkg/modules/generators/accessories/database/aws_rds_test.go +++ b/pkg/modules/generators/accessories/database/aws_rds_test.go @@ -7,24 +7,19 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/accessories/database" "kusionstack.io/kusion/pkg/modules/inputs/workload" ) func TestGenerateAWSResources(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -76,15 +71,11 @@ func TestGenerateAWSSecurityGroup(t *testing.T) { awsProvider.SetString(defaultAWSProvider) awsProviderRegion = "us-east-1" - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -147,15 +138,11 @@ func TestGenerateAWSDBInstance(t *testing.T) { awsProvider.SetString(defaultAWSProvider) awsProviderRegion = "us-east-1" - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} diff --git a/pkg/modules/generators/accessories/database/database_generator.go b/pkg/modules/generators/accessories/database/database_generator.go index ac4f423f..9e127a75 100644 --- a/pkg/modules/generators/accessories/database/database_generator.go +++ b/pkg/modules/generators/accessories/database/database_generator.go @@ -9,9 +9,8 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/accessories/database" @@ -28,16 +27,16 @@ const ( ) type databaseGenerator struct { - project *project.Project - stack *stack.Stack + project *apiv1.Project + stack *apiv1.Stack appName string workload *workload.Workload database *database.Database } func NewDatabaseGenerator( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, workload *workload.Workload, database *database.Database, @@ -56,8 +55,8 @@ func NewDatabaseGenerator( } func NewDatabaseGeneratorFunc( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, workload *workload.Workload, database *database.Database, diff --git a/pkg/modules/generators/accessories/database/database_generator_test.go b/pkg/modules/generators/accessories/database/database_generator_test.go index 3a58bab3..abb5422d 100644 --- a/pkg/modules/generators/accessories/database/database_generator_test.go +++ b/pkg/modules/generators/accessories/database/database_generator_test.go @@ -8,9 +8,8 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/accessories/database" "kusionstack.io/kusion/pkg/modules/inputs/workload" @@ -18,15 +17,11 @@ import ( ) func TestNewDatabaseGenerator(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -38,15 +33,11 @@ func TestNewDatabaseGenerator(t *testing.T) { } func TestGenerate(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -166,15 +157,11 @@ func TestGenerate(t *testing.T) { } func TestInjectSecret(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{ @@ -246,15 +233,11 @@ func TestInjectSecret(t *testing.T) { } func TestGenerateTFRandomPassword(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -292,15 +275,11 @@ func TestGenerateTFRandomPassword(t *testing.T) { } func TestGenerateDBSeret(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} diff --git a/pkg/modules/generators/accessories/database/local_database_test.go b/pkg/modules/generators/accessories/database/local_database_test.go index 14402472..35b29a69 100644 --- a/pkg/modules/generators/accessories/database/local_database_test.go +++ b/pkg/modules/generators/accessories/database/local_database_test.go @@ -7,23 +7,18 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules/inputs/accessories/database" "kusionstack.io/kusion/pkg/modules/inputs/workload" ) func TestGenerateLocalResources(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -69,15 +64,11 @@ func TestGenerateLocalResources(t *testing.T) { } func TestGenerateLocalSecret(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -105,15 +96,11 @@ func TestGenerateLocalSecret(t *testing.T) { } func TestGenerateLocalPVC(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -139,15 +126,11 @@ func TestGenerateLocalPVC(t *testing.T) { } func TestGenerateLocalDeployment(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} @@ -173,15 +156,11 @@ func TestGenerateLocalDeployment(t *testing.T) { } func TestGenerateLocalService(t *testing.T) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, + project := &apiv1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + stack := &apiv1.Stack{ + Name: "teststack", } appName := "testapp" workload := &workload.Workload{} diff --git a/pkg/modules/generators/app_configurations_generator.go b/pkg/modules/generators/app_configurations_generator.go index 01ae09c6..4e372bcd 100644 --- a/pkg/modules/generators/app_configurations_generator.go +++ b/pkg/modules/generators/app_configurations_generator.go @@ -6,8 +6,6 @@ import ( "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" accessories "kusionstack.io/kusion/pkg/modules/generators/accessories/database" "kusionstack.io/kusion/pkg/modules/generators/monitoring" @@ -20,16 +18,16 @@ import ( ) type appConfigurationGenerator struct { - project *project.Project - stack *stack.Stack + project *v1.Project + stack *v1.Stack appName string app *inputs.AppConfiguration ws *v1.Workspace } func NewAppConfigurationGenerator( - project *project.Project, - stack *stack.Stack, + project *v1.Project, + stack *v1.Stack, appName string, app *inputs.AppConfiguration, ws *v1.Workspace, @@ -50,7 +48,7 @@ func NewAppConfigurationGenerator( return nil, errors.New("workspace must not be empty") // AppConfiguration asks for non-empty workspace } if err := workspace.ValidateWorkspace(ws); err != nil { - return nil, fmt.Errorf("invalid config of workspace %s, %w", stack.GetName(), err) + return nil, fmt.Errorf("invalid config of workspace %s, %w", stack.Name, err) } return &appConfigurationGenerator{ @@ -63,8 +61,8 @@ func NewAppConfigurationGenerator( } func NewAppConfigurationGeneratorFunc( - project *project.Project, - stack *stack.Stack, + project *v1.Project, + stack *v1.Stack, appName string, app *inputs.AppConfiguration, ws *v1.Workspace, diff --git a/pkg/modules/generators/app_configurations_generator_test.go b/pkg/modules/generators/app_configurations_generator_test.go index 749e936a..1dadc976 100644 --- a/pkg/modules/generators/app_configurations_generator_test.go +++ b/pkg/modules/generators/app_configurations_generator_test.go @@ -7,8 +7,6 @@ import ( "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" appmodel "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/workload" "kusionstack.io/kusion/pkg/modules/inputs/workload/network" @@ -131,17 +129,13 @@ func buildMockWorkspace() *v1.Workspace { } } -func buildMockProjectAndStack() (*project.Project, *stack.Stack) { - project := &project.Project{ - Configuration: project.Configuration{ - Name: "testproject", - }, +func buildMockProjectAndStack() (*v1.Project, *v1.Stack) { + project := &v1.Project{ + Name: "testproject", } - stack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "test", - }, + stack := &v1.Stack{ + Name: "test", } return project, stack diff --git a/pkg/modules/generators/monitoring/monitoring_generator.go b/pkg/modules/generators/monitoring/monitoring_generator.go index 44ad399e..f0bae84b 100644 --- a/pkg/modules/generators/monitoring/monitoring_generator.go +++ b/pkg/modules/generators/monitoring/monitoring_generator.go @@ -6,20 +6,20 @@ import ( prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/inputs/monitoring" ) type monitoringGenerator struct { - project *project.Project + project *apiv1.Project monitor *monitoring.Monitor appName string } func NewMonitoringGenerator( - project *project.Project, + project *apiv1.Project, monitor *monitoring.Monitor, appName string, ) (modules.Generator, error) { @@ -38,7 +38,7 @@ func NewMonitoringGenerator( } func NewMonitoringGeneratorFunc( - project *project.Project, + project *apiv1.Project, monitor *monitoring.Monitor, appName string, ) modules.NewGeneratorFunc { @@ -67,8 +67,8 @@ func (g *monitoringGenerator) Generate(spec *intent.Intent) error { "kusion_monitoring_appname": g.appName, } - if g.project.Configuration.Prometheus != nil && g.project.Configuration.Prometheus.OperatorMode && g.monitor != nil { - if g.project.Configuration.Prometheus.MonitorType == project.ServiceMonitorType { + if g.project.Prometheus != nil && g.project.Prometheus.OperatorMode && g.monitor != nil { + if g.project.Prometheus.MonitorType == apiv1.ServiceMonitorType { serviceEndpoint := prometheusv1.Endpoint{ Interval: g.monitor.Interval, ScrapeTimeout: g.monitor.Timeout, @@ -99,7 +99,7 @@ func (g *monitoringGenerator) Generate(spec *intent.Intent) error { if err != nil { return err } - } else if g.project.Configuration.Prometheus.MonitorType == project.PodMonitorType { + } else if g.project.Prometheus.MonitorType == apiv1.PodMonitorType { podMetricsEndpoint := prometheusv1.PodMetricsEndpoint{ Interval: g.monitor.Interval, ScrapeTimeout: g.monitor.Timeout, @@ -133,7 +133,7 @@ func (g *monitoringGenerator) Generate(spec *intent.Intent) error { return err } } else { - return fmt.Errorf("MonitorType should either be service or pod %s", g.project.Configuration.Prometheus.MonitorType) + return fmt.Errorf("MonitorType should either be service or pod %s", g.project.Prometheus.MonitorType) } } diff --git a/pkg/modules/generators/monitoring/monitoring_generator_test.go b/pkg/modules/generators/monitoring/monitoring_generator_test.go index 2bc2c5ce..02977a59 100644 --- a/pkg/modules/generators/monitoring/monitoring_generator_test.go +++ b/pkg/modules/generators/monitoring/monitoring_generator_test.go @@ -8,13 +8,13 @@ import ( prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/require" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" "kusionstack.io/kusion/pkg/modules/inputs/monitoring" ) type Fields struct { - project *project.Project + project *apiv1.Project monitor *monitoring.Monitor appName string } @@ -35,11 +35,11 @@ func BuildMonitoringTestCase( projectName, appName string, interval, timeout prometheusv1.Duration, path, port, scheme string, - monitorType project.MonitorType, + monitorType apiv1.MonitorType, operatorMode bool, ) *TestCase { var endpointType string - var monitorKind project.MonitorType + var monitorKind apiv1.MonitorType if monitorType == "Service" { monitorKind = "ServiceMonitor" endpointType = "endpoints" @@ -92,13 +92,11 @@ func BuildMonitoringTestCase( testCase := &TestCase{ name: fmt.Sprintf("%s-%s", projectName, appName), fields: Fields{ - project: &project.Project{ - Configuration: project.Configuration{ - Name: projectName, - Prometheus: &project.PrometheusConfig{ - OperatorMode: operatorMode, - MonitorType: monitorType, - }, + project: &apiv1.Project{ + Name: projectName, + Prometheus: &apiv1.PrometheusConfig{ + OperatorMode: operatorMode, + MonitorType: monitorType, }, Path: "/test-project", }, diff --git a/pkg/modules/generators/trait/ops_rule_generator.go b/pkg/modules/generators/trait/ops_rule_generator.go index 0939ef90..f51b7027 100644 --- a/pkg/modules/generators/trait/ops_rule_generator.go +++ b/pkg/modules/generators/trait/ops_rule_generator.go @@ -5,24 +5,23 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "kusionstack.io/kube-api/apps/v1alpha1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" appmodule "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/workload" ) type opsRuleGenerator struct { - project *project.Project - stack *stack.Stack + project *apiv1.Project + stack *apiv1.Stack appName string app *appmodule.AppConfiguration } func NewOpsRuleGenerator( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, app *appmodule.AppConfiguration, ) (modules.Generator, error) { @@ -35,8 +34,8 @@ func NewOpsRuleGenerator( } func NewOpsRuleGeneratorFunc( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, app *appmodule.AppConfiguration, ) modules.NewGeneratorFunc { diff --git a/pkg/modules/generators/trait/ops_rule_generator_test.go b/pkg/modules/generators/trait/ops_rule_generator_test.go index 476b0cfe..78aba56d 100644 --- a/pkg/modules/generators/trait/ops_rule_generator_test.go +++ b/pkg/modules/generators/trait/ops_rule_generator_test.go @@ -5,9 +5,8 @@ import ( "github.com/stretchr/testify/require" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" appmodule "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/trait" "kusionstack.io/kusion/pkg/modules/inputs/workload" @@ -15,21 +14,19 @@ import ( func Test_opsRuleGenerator_Generate(t *testing.T) { type fields struct { - project *project.Project - stack *stack.Stack + project *apiv1.Project + stack *apiv1.Stack appName string app *appmodule.AppConfiguration } type args struct { spec *intent.Intent } - project := &project.Project{ - Configuration: project.Configuration{ - Name: "default", - }, + project := &apiv1.Project{ + Name: "default", } - stack := &stack.Stack{ - Configuration: stack.Configuration{Name: "dev"}, + stack := &apiv1.Stack{ + Name: "dev", } appName := "foo" tests := []struct { @@ -143,8 +140,8 @@ func Test_opsRuleGenerator_Generate(t *testing.T) { func TestNewOpsRuleGeneratorFunc(t *testing.T) { type args struct { - project *project.Project - stack *stack.Stack + project *apiv1.Project + stack *apiv1.Stack appName string app *appmodule.AppConfiguration } diff --git a/pkg/modules/generators/workload/job_generator.go b/pkg/modules/generators/workload/job_generator.go index 359bf478..b29a00f5 100644 --- a/pkg/modules/generators/workload/job_generator.go +++ b/pkg/modules/generators/workload/job_generator.go @@ -5,23 +5,22 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/inputs/workload" ) type jobGenerator struct { - project *project.Project - stack *stack.Stack + project *apiv1.Project + stack *apiv1.Stack appName string job *workload.Job } func NewJobGenerator( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, job *workload.Job, ) (modules.Generator, error) { @@ -34,8 +33,8 @@ func NewJobGenerator( } func NewJobGeneratorFunc( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, job *workload.Job, ) modules.NewGeneratorFunc { diff --git a/pkg/modules/generators/workload/job_generator_test.go b/pkg/modules/generators/workload/job_generator_test.go index d42a2f41..de347154 100644 --- a/pkg/modules/generators/workload/job_generator_test.go +++ b/pkg/modules/generators/workload/job_generator_test.go @@ -6,20 +6,17 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/inputs/workload" ) func TestNewJobGenerator(t *testing.T) { - expectedProject := &project.Project{ - Configuration: project.Configuration{ - Name: "test", - }, + expectedProject := &apiv1.Project{ + Name: "test", } - expectedStack := &stack.Stack{} + expectedStack := &apiv1.Stack{} expectedAppName := "test" expectedJob := &workload.Job{} actual, err := NewJobGenerator(expectedProject, expectedStack, expectedAppName, expectedJob) @@ -33,12 +30,10 @@ func TestNewJobGenerator(t *testing.T) { } func TestNewJobGeneratorFunc(t *testing.T) { - expectedProject := &project.Project{ - Configuration: project.Configuration{ - Name: "test", - }, + expectedProject := &apiv1.Project{ + Name: "test", } - expectedStack := &stack.Stack{} + expectedStack := &apiv1.Stack{} expectedAppName := "test" expectedJob := &workload.Job{} generatorFunc := NewJobGeneratorFunc(expectedProject, expectedStack, expectedAppName, expectedJob) @@ -55,19 +50,17 @@ func TestNewJobGeneratorFunc(t *testing.T) { func TestJobGenerator_Generate(t *testing.T) { testCases := []struct { name string - expectedProject *project.Project - expectedStack *stack.Stack + expectedProject *apiv1.Project + expectedStack *apiv1.Stack expectedAppName string expectedJob *workload.Job }{ { name: "test generate", - expectedProject: &project.Project{ - Configuration: project.Configuration{ - Name: "test", - }, + expectedProject: &apiv1.Project{ + Name: "test", }, - expectedStack: &stack.Stack{}, + expectedStack: &apiv1.Stack{}, expectedAppName: "test", expectedJob: &workload.Job{}, }, diff --git a/pkg/modules/generators/workload/secret/secret_generator.go b/pkg/modules/generators/workload/secret/secret_generator.go index 585dd545..9a630cdf 100644 --- a/pkg/modules/generators/workload/secret/secret_generator.go +++ b/pkg/modules/generators/workload/secret/secret_generator.go @@ -7,19 +7,19 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/inputs/workload" ) type secretGenerator struct { - project *project.Project + project *apiv1.Project secrets map[string]workload.Secret } func NewSecretGenerator( - project *project.Project, + project *apiv1.Project, secrets map[string]workload.Secret, ) (modules.Generator, error) { if len(project.Name) == 0 { @@ -33,7 +33,7 @@ func NewSecretGenerator( } func NewSecretGeneratorFunc( - project *project.Project, + project *apiv1.Project, secrets map[string]workload.Secret, ) modules.NewGeneratorFunc { return func() (modules.Generator, error) { @@ -70,7 +70,7 @@ func (g *secretGenerator) Generate(spec *intent.Intent) error { // generateSecret generates target secret based on secret type. Most of these secret types are just semantic wrapper // of native Kubernetes secret types:https://kubernetes.io/docs/concepts/configuration/secret/#secret-types, and more // detailed usage info can be found in public documentation. -func generateSecret(project *project.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { +func generateSecret(project *apiv1.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { switch secretRef.Type { case "basic": return generateBasic(project, secretName, secretRef) @@ -87,7 +87,7 @@ func generateSecret(project *project.Project, secretName string, secretRef workl // generateBasic generates secret used for basic authentication. The basic secret type // is used for username / password pairs. -func generateBasic(project *project.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { +func generateBasic(project *apiv1.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { secret := &v1.Secret{ TypeMeta: metav1.TypeMeta{ APIVersion: v1.SchemeGroupVersion.String(), @@ -114,7 +114,7 @@ func generateBasic(project *project.Project, secretName string, secretRef worklo // generateToken generates secret used for password. Token secrets are useful for generating // a password or secure string used for passwords when the user is already known or not required. -func generateToken(project *project.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { +func generateToken(project *apiv1.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { secret := &v1.Secret{ TypeMeta: metav1.TypeMeta{ APIVersion: v1.SchemeGroupVersion.String(), @@ -138,7 +138,7 @@ func generateToken(project *project.Project, secretName string, secretRef worklo } // generateOpaque generates secret used for arbitrary user-defined data. -func generateOpaque(project *project.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { +func generateOpaque(project *apiv1.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { secret := &v1.Secret{ TypeMeta: metav1.TypeMeta{ APIVersion: v1.SchemeGroupVersion.String(), @@ -159,7 +159,7 @@ func generateOpaque(project *project.Project, secretName string, secretRef workl // generateCertificate generates secret used for storing a certificate and its associated key. // One common use for TLS Secrets is to configure encryption in transit for an Ingress, but // you can also use it with other resources or directly in your workload. -func generateCertificate(project *project.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { +func generateCertificate(project *apiv1.Project, secretName string, secretRef workload.Secret) (*v1.Secret, error) { secret := &v1.Secret{ TypeMeta: metav1.TypeMeta{ APIVersion: v1.SchemeGroupVersion.String(), diff --git a/pkg/modules/generators/workload/secret/secret_generator_test.go b/pkg/modules/generators/workload/secret/secret_generator_test.go index 7b7e04f3..6c1910ab 100644 --- a/pkg/modules/generators/workload/secret/secret_generator_test.go +++ b/pkg/modules/generators/workload/secret/secret_generator_test.go @@ -5,8 +5,8 @@ import ( "github.com/stretchr/testify/require" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" "kusionstack.io/kusion/pkg/modules/inputs/workload" ) @@ -70,10 +70,8 @@ func TestGenerateSecret(t *testing.T) { }, } - project := &project.Project{ - Configuration: project.Configuration{ - Name: "helloworld", - }, + project := &apiv1.Project{ + Name: "helloworld", } // run all the tests for name, test := range tests { diff --git a/pkg/modules/generators/workload/service_generator.go b/pkg/modules/generators/workload/service_generator.go index 6e01ce5e..1f8b1a6a 100644 --- a/pkg/modules/generators/workload/service_generator.go +++ b/pkg/modules/generators/workload/service_generator.go @@ -8,9 +8,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "kusionstack.io/kube-api/apps/v1alpha1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/inputs/workload" @@ -19,16 +18,16 @@ import ( // workloadServiceGenerator is a struct for generating service workload resources. type workloadServiceGenerator struct { - project *project.Project - stack *stack.Stack + project *apiv1.Project + stack *apiv1.Stack appName string service *workload.Service } // NewWorkloadServiceGenerator returns a new workloadServiceGenerator instance. func NewWorkloadServiceGenerator( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, service *workload.Service, ) (modules.Generator, error) { @@ -54,8 +53,8 @@ func NewWorkloadServiceGenerator( // NewWorkloadServiceGeneratorFunc returns a new NewGeneratorFunc that returns a workloadServiceGenerator instance. func NewWorkloadServiceGeneratorFunc( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, service *workload.Service, ) modules.NewGeneratorFunc { diff --git a/pkg/modules/generators/workload/service_generator_test.go b/pkg/modules/generators/workload/service_generator_test.go index 0b214b15..bea4dfad 100644 --- a/pkg/modules/generators/workload/service_generator_test.go +++ b/pkg/modules/generators/workload/service_generator_test.go @@ -6,9 +6,8 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules/inputs/workload" "kusionstack.io/kusion/pkg/modules/inputs/workload/container" "kusionstack.io/kusion/pkg/modules/inputs/workload/network" @@ -125,8 +124,8 @@ spec: status: {} ` type fields struct { - project *project.Project - stack *stack.Stack + project *apiv1.Project + stack *apiv1.Stack appName string service *workload.Service } @@ -144,14 +143,12 @@ status: {} { name: "CollaSet", fields: fields{ - project: &project.Project{ - Configuration: project.Configuration{ - Name: "default", - }, + project: &apiv1.Project{ + Name: "default", Path: "/test", }, - stack: &stack.Stack{ - Configuration: stack.Configuration{Name: "dev"}, + stack: &apiv1.Stack{ + Name: "dev", }, appName: "foo", service: &workload.Service{ @@ -189,14 +186,12 @@ status: {} { name: "Deployment", fields: fields{ - project: &project.Project{ - Configuration: project.Configuration{ - Name: "default", - }, + project: &apiv1.Project{ + Name: "default", Path: "/test", }, - stack: &stack.Stack{ - Configuration: stack.Configuration{Name: "dev"}, + stack: &apiv1.Stack{ + Name: "dev", }, appName: "foo", service: &workload.Service{ diff --git a/pkg/modules/generators/workload/workload_generator.go b/pkg/modules/generators/workload/workload_generator.go index 98d19b6d..95361c28 100644 --- a/pkg/modules/generators/workload/workload_generator.go +++ b/pkg/modules/generators/workload/workload_generator.go @@ -14,9 +14,8 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/inputs/workload" "kusionstack.io/kusion/pkg/modules/inputs/workload/container" @@ -26,15 +25,15 @@ import ( ) type workloadGenerator struct { - project *project.Project - stack *stack.Stack + project *apiv1.Project + stack *apiv1.Stack appName string workload *workload.Workload } func NewWorkloadGenerator( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, workload *workload.Workload, ) (modules.Generator, error) { @@ -51,8 +50,8 @@ func NewWorkloadGenerator( } func NewWorkloadGeneratorFunc( - project *project.Project, - stack *stack.Stack, + project *apiv1.Project, + stack *apiv1.Stack, appName string, workload *workload.Workload, ) modules.NewGeneratorFunc { diff --git a/pkg/modules/generators/workload/workload_generator_test.go b/pkg/modules/generators/workload/workload_generator_test.go index e6e232ac..6f565ad3 100644 --- a/pkg/modules/generators/workload/workload_generator_test.go +++ b/pkg/modules/generators/workload/workload_generator_test.go @@ -6,9 +6,8 @@ import ( "github.com/stretchr/testify/assert" "gopkg.in/yaml.v2" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/inputs/workload" "kusionstack.io/kusion/pkg/modules/inputs/workload/container" @@ -17,12 +16,10 @@ import ( func TestNewWorkloadGenerator(t *testing.T) { t.Run("NewWorkloadGenerator should return a valid generator", func(t *testing.T) { - expectedProject := &project.Project{ - Configuration: project.Configuration{ - Name: "test", - }, + expectedProject := &apiv1.Project{ + Name: "test", } - expectedStack := &stack.Stack{} + expectedStack := &apiv1.Stack{} expectedWorkload := &workload.Workload{} expectedAppName := "test" @@ -39,12 +36,10 @@ func TestNewWorkloadGenerator(t *testing.T) { func TestNewWorkloadGeneratorFunc(t *testing.T) { t.Run("NewWorkloadGeneratorFunc should return a valid generator function", func(t *testing.T) { - expectedProject := &project.Project{ - Configuration: project.Configuration{ - Name: "test", - }, + expectedProject := &apiv1.Project{ + Name: "test", } - expectedStack := &stack.Stack{} + expectedStack := &apiv1.Stack{} expectedWorkload := &workload.Workload{} expectedAppName := "test" @@ -101,19 +96,15 @@ func TestWorkloadGenerator_Generate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - expectedProject := &project.Project{ - Configuration: project.Configuration{ - Name: "test", - Prometheus: &project.PrometheusConfig{ - OperatorMode: false, - MonitorType: "Pod", - }, + expectedProject := &apiv1.Project{ + Name: "test", + Prometheus: &apiv1.PrometheusConfig{ + OperatorMode: false, + MonitorType: "Pod", }, } - expectedStack := &stack.Stack{ - Configuration: stack.Configuration{ - Name: "teststack", - }, + expectedStack := &apiv1.Stack{ + Name: "teststack", } expectedAppName := "test" diff --git a/pkg/modules/patchers/monitoring/monitoring_patcher.go b/pkg/modules/patchers/monitoring/monitoring_patcher.go index 232bd460..a8c5f0e4 100644 --- a/pkg/modules/patchers/monitoring/monitoring_patcher.go +++ b/pkg/modules/patchers/monitoring/monitoring_patcher.go @@ -5,8 +5,8 @@ import ( "kusionstack.io/kube-api/apps/v1alpha1" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" "kusionstack.io/kusion/pkg/modules" modelsapp "kusionstack.io/kusion/pkg/modules/inputs" ) @@ -14,11 +14,11 @@ import ( type monitoringPatcher struct { appName string app *modelsapp.AppConfiguration - project *project.Project + project *apiv1.Project } // NewMonitoringPatcher returns a Patcher. -func NewMonitoringPatcher(appName string, app *modelsapp.AppConfiguration, project *project.Project) (modules.Patcher, error) { +func NewMonitoringPatcher(appName string, app *modelsapp.AppConfiguration, project *apiv1.Project) (modules.Patcher, error) { return &monitoringPatcher{ appName: appName, app: app, @@ -27,7 +27,7 @@ func NewMonitoringPatcher(appName string, app *modelsapp.AppConfiguration, proje } // NewMonitoringPatcherFunc returns a NewPatcherFunc. -func NewMonitoringPatcherFunc(appName string, app *modelsapp.AppConfiguration, project *project.Project) modules.NewPatcherFunc { +func NewMonitoringPatcherFunc(appName string, app *modelsapp.AppConfiguration, project *apiv1.Project) modules.NewPatcherFunc { return func() (modules.Patcher, error) { return NewMonitoringPatcher(appName, app, project) } @@ -35,7 +35,7 @@ func NewMonitoringPatcherFunc(appName string, app *modelsapp.AppConfiguration, p // Patch implements Patcher interface. func (p *monitoringPatcher) Patch(resources map[string][]*intent.Resource) error { - if p.app.Monitoring == nil || p.project.Configuration.Prometheus == nil { + if p.app.Monitoring == nil || p.project.Prometheus == nil { return nil } @@ -53,7 +53,7 @@ func (p *monitoringPatcher) Patch(resources map[string][]*intent.Resource) error monitoringLabels := make(map[string]string) monitoringAnnotations := make(map[string]string) - if p.project.Configuration.Prometheus.OperatorMode { + if p.project.Prometheus.OperatorMode { monitoringLabels["kusion_monitoring_appname"] = p.appName } else { // If Prometheus doesn't run as an operator, kusion will generate the diff --git a/pkg/modules/patchers/monitoring/monitoring_patcher_test.go b/pkg/modules/patchers/monitoring/monitoring_patcher_test.go index 300b287c..be799dba 100644 --- a/pkg/modules/patchers/monitoring/monitoring_patcher_test.go +++ b/pkg/modules/patchers/monitoring/monitoring_patcher_test.go @@ -9,8 +9,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" "kusionstack.io/kusion/pkg/apis/intent" - "kusionstack.io/kusion/pkg/apis/project" "kusionstack.io/kusion/pkg/modules" modelsapp "kusionstack.io/kusion/pkg/modules/inputs" "kusionstack.io/kusion/pkg/modules/inputs/monitoring" @@ -26,7 +26,7 @@ func Test_monitoringPatcher_Patch(t *testing.T) { type fields struct { appName string app *modelsapp.AppConfiguration - project *project.Project + project *apiv1.Project } type args struct { resources map[string][]*intent.Resource @@ -44,11 +44,9 @@ func Test_monitoringPatcher_Patch(t *testing.T) { app: &modelsapp.AppConfiguration{ Monitoring: &monitoring.Monitor{}, }, - project: &project.Project{ - Configuration: project.Configuration{ - Prometheus: &project.PrometheusConfig{ - OperatorMode: true, - }, + project: &apiv1.Project{ + Prometheus: &apiv1.PrometheusConfig{ + OperatorMode: true, }, }, }, @@ -64,11 +62,9 @@ func Test_monitoringPatcher_Patch(t *testing.T) { app: &modelsapp.AppConfiguration{ Monitoring: &monitoring.Monitor{}, }, - project: &project.Project{ - Configuration: project.Configuration{ - Prometheus: &project.PrometheusConfig{ - OperatorMode: false, - }, + project: &apiv1.Project{ + Prometheus: &apiv1.PrometheusConfig{ + OperatorMode: false, }, }, }, @@ -130,7 +126,7 @@ func TestNewMonitoringPatcherFunc(t *testing.T) { type args struct { appName string app *modelsapp.AppConfiguration - project *project.Project + project *apiv1.Project } tests := []struct { name string @@ -142,7 +138,7 @@ func TestNewMonitoringPatcherFunc(t *testing.T) { args: args{ appName: "test", app: &modelsapp.AppConfiguration{}, - project: &project.Project{}, + project: &apiv1.Project{}, }, }, } diff --git a/pkg/project/paths.go b/pkg/project/paths.go new file mode 100644 index 00000000..6fc3e6b9 --- /dev/null +++ b/pkg/project/paths.go @@ -0,0 +1,238 @@ +package project + +import ( + "errors" + "fmt" + "io/fs" + "os" + "path/filepath" + + "github.com/pulumi/pulumi/sdk/v3/go/common/util/fsutil" + yamlv3 "gopkg.in/yaml.v3" + "k8s.io/apimachinery/pkg/util/sets" + + v1 "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/log" +) + +var ( + ErrNotProjectDirectory = errors.New("path must be a project directory") + ErrProjectNotUnique = errors.New("the project obtained is not unique") + ErrNotStackDirectory = errors.New("path must be a stack directory") + ErrStackNotUnique = errors.New("the stack obtained is not unique") +) + +const ( + ProjectFile = "project.yaml" + StackFile = "stack.yaml" +) + +// DetectProjectAndStack try to get stack and project from given path +func DetectProjectAndStack(stackDir string) (p *v1.Project, s *v1.Stack, err error) { + stackDir, err = filepath.Abs(stackDir) + if err != nil { + return nil, nil, err + } + + s, err = GetStackFrom(stackDir) + if err != nil { + return nil, nil, err + } + + projectDir, err := findProjectPathFrom(stackDir) + if err != nil { + return nil, nil, err + } + + p, err = getProjectFrom(projectDir) + if err != nil { + return nil, nil, err + } + + return p, s, nil +} + +// isProjectFile determine whether the given path is Project file +func isProjectFile(path string) bool { + f, err := os.Stat(path) + return err == nil && !f.IsDir() && f.Mode().IsRegular() && filepath.Base(path) == ProjectFile +} + +// isProject determine whether the given path is Project directory +func isProject(path string) bool { + f, err := os.Stat(path) + f2, err2 := os.Stat(filepath.Join(path, ProjectFile)) + + if (err == nil && f.IsDir()) && (err2 == nil && f2.Mode().IsRegular()) { + return true + } + + return false +} + +// getProjectFrom get project from the given path +func getProjectFrom(path string) (*v1.Project, error) { + if !isProject(path) { + return nil, ErrNotProjectDirectory + } + + projects, err := FindAllProjectsFrom(path) + if err != nil { + return nil, err + } + + if len(projects) != 1 { + return nil, ErrProjectNotUnique + } + + return projects[0], nil +} + +// findProjectPathFrom locates the closest project from the given path, searching "upwards" in the directory +// hierarchy. If no project is found, an empty path is returned. +func findProjectPathFrom(path string) (string, error) { + file, err := fsutil.WalkUp(path, isProjectFile, func(s string) bool { + return true + }) + if err != nil { + return "", err + } + + return filepath.Dir(file), nil +} + +// FindAllProjectsFrom find all project from the given path +func FindAllProjectsFrom(path string) ([]*v1.Project, error) { + var projects []*v1.Project + s := sets.NewString() + err := filepath.WalkDir(path, func(p string, _ fs.DirEntry, _ error) error { + if isProject(p) && !s.Has(p) { + // Parse project.yaml + project, err := parseProjectYamlFile(p) + if err != nil { + log.Error(err) + return fmt.Errorf("parse project.yaml failed. %w", err) + } + + // Find all stacks + stacks, err := FindAllStacksFrom(p) + if err != nil { + log.Error(err) + return fmt.Errorf("parse stacks failed. %w", err) + } + + // Get absolute path + absPath, err := filepath.Abs(p) + if err != nil { + log.Error(err) + return fmt.Errorf("project path failed. %w", err) + } + + project.Stacks = stacks + project.Path = absPath + projects = append(projects, project) + } + return nil + }) + + return projects, err +} + +// IsStack determine whether the given path is Stack directory +func IsStack(path string) bool { + f, err := os.Stat(path) + f2, err2 := os.Stat(filepath.Join(path, StackFile)) + + if (err == nil && f.IsDir()) && (err2 == nil && f2.Mode().IsRegular()) { + return true + } + + return false +} + +// GetStackFrom get stack from the given path +func GetStackFrom(path string) (*v1.Stack, error) { + if !IsStack(path) { + return nil, ErrNotStackDirectory + } + + stacks, err := FindAllStacksFrom(path) + if err != nil { + return nil, err + } + + if len(stacks) != 1 { + return nil, ErrStackNotUnique + } + + return stacks[0], nil +} + +// FindAllStacksFrom find all stacks from the given path +func FindAllStacksFrom(path string) ([]*v1.Stack, error) { + var stacks []*v1.Stack + s := sets.NewString() + _ = filepath.WalkDir(path, func(p string, _ fs.DirEntry, _ error) (err error) { + if IsStack(p) && !s.Has(p) { + // Parse stack.yaml + stack, err := parseStackYamlFile(p) + if err != nil { + log.Error(err) + return nil + } + + // Get absolute path + absPath, err := filepath.Abs(p) + if err != nil { + log.Error(err) + return nil + } + + stack.Path = absPath + stacks = append(stacks, stack) + } + + return nil + }) + + return stacks, nil +} + +// ParseProjectConfiguration parse the project configuration by the given directory +func parseProjectYamlFile(path string) (*v1.Project, error) { + var project v1.Project + + err := parseYamlFile(filepath.Join(path, ProjectFile), &project) + if err != nil { + return nil, err + } + + return &project, nil +} + +// parseStackConfiguration parse the stack configuration by the given directory +func parseStackYamlFile(path string) (*v1.Stack, error) { + var stack v1.Stack + + err := parseYamlFile(filepath.Join(path, StackFile), &stack) + if err != nil { + return nil, err + } + + return &stack, nil +} + +// Parse yaml data by file name +func parseYamlFile(filename string, target interface{}) error { + content, err := os.ReadFile(filename) + if err != nil { + return err + } + + err = yamlv3.Unmarshal(content, target) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/project/paths_test.go b/pkg/project/paths_test.go new file mode 100644 index 00000000..777f049f --- /dev/null +++ b/pkg/project/paths_test.go @@ -0,0 +1,255 @@ +package project + +import ( + "errors" + "os" + "path/filepath" + "reflect" + "testing" + + "github.com/bytedance/mockey" + + "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/util/json" +) + +// merge project tests and stack tests together to reuse test data +var ( + // Inject into the TestMain + TestCurrentDir string + TestProjectPathA string + TestStackPathAA string + TestProjectPathB string + TestStackPathBA string + TestStackPathBB string + ErrFake = errors.New("fake error") +) + +const ( + TestProjectA string = "http-echo" + TestProjectB string = "nginx-example" + TestStackA string = "dev" + TestStackB string = "prod" +) + +func TestMain(m *testing.M) { + TestCurrentDir, _ = os.Getwd() + TestProjectPathA = filepath.Join("testdata", "appops", TestProjectA) + TestStackPathAA = filepath.Join("testdata", "appops", TestProjectA, TestStackA) + TestProjectPathB = filepath.Join("testdata", "appops", TestProjectB) + TestStackPathBA = filepath.Join("testdata", "appops", TestProjectB, TestStackA) + TestStackPathBB = filepath.Join("testdata", "appops", TestProjectB, TestStackB) + + os.Exit(m.Run()) +} + +func TestFindAllProjectsFrom(t *testing.T) { + type args struct { + path string + } + tests := []struct { + name string + args args + want []*v1.Project + wantErr bool + }{ + { + name: "given-project-path", + args: args{ + path: "./testdata/appops/http-echo", + }, + want: []*v1.Project{ + { + Name: TestProjectA, + Path: filepath.Join(TestCurrentDir, TestProjectPathA), + Stacks: []*v1.Stack{ + { + Name: TestStackA, + Path: filepath.Join(TestCurrentDir, TestStackPathAA), + }, + }, + }, + }, + wantErr: false, + }, + { + name: "give-project-path-with-two-stacks", + args: args{ + path: "./testdata/appops/nginx-example", + }, + want: []*v1.Project{ + { + Name: TestProjectB, + Path: filepath.Join(TestCurrentDir, TestProjectPathB), + Stacks: []*v1.Stack{ + { + Name: TestStackA, + Path: filepath.Join(TestCurrentDir, TestStackPathBA), + }, + { + Name: TestStackB, + Path: filepath.Join(TestCurrentDir, TestStackPathBB), + }, + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := FindAllProjectsFrom(tt.args.path) + if (err != nil) != tt.wantErr { + t.Errorf("FindAllProjectsFrom() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("FindAllProjectsFrom() = %v, want %v", json.MustMarshal2PrettyString(got), json.MustMarshal2PrettyString(tt.want)) + } + }) + } +} + +func TestDetectProjectAndStack(t *testing.T) { + FakeProject := &v1.Project{ + Name: TestProjectA, + Path: filepath.Join(TestCurrentDir, TestProjectPathA), + Stacks: []*v1.Stack{ + { + Name: TestStackA, + Path: filepath.Join(TestCurrentDir, TestStackPathAA), + }, + }, + } + FakeStack := &v1.Stack{ + Name: TestStackA, + Path: filepath.Join(TestCurrentDir, TestStackPathAA), + } + + type args struct { + stackDir string + } + tests := []struct { + name string + args args + project *v1.Project + stack *v1.Stack + wantErr bool + preRun func() + postRun func() + }{ + { + name: "success", + args: args{ + stackDir: "./testdata/appops/http-echo/dev/", + }, + project: FakeProject, + stack: FakeStack, + wantErr: false, + preRun: func() {}, + postRun: func() {}, + }, + { + name: "fail-for-abs", + args: args{ + stackDir: "./testdata/appops/http-echo/dev/", + }, + project: nil, + stack: nil, + wantErr: true, + preRun: func() { + mockAbs("", ErrFake) + }, + postRun: func() {}, + }, + { + name: "fail-for-GetStackFrom", + args: args{ + stackDir: "./testdata/appops/http-echo/dev/", + }, + project: nil, + stack: nil, + wantErr: true, + preRun: func() { + mockGetStackFrom(ErrFake) + }, + postRun: func() {}, + }, + { + name: "fail-for-FindProjectPathFrom", + args: args{ + stackDir: "./testdata/appops/http-echo/dev/", + }, + project: nil, + stack: nil, + wantErr: true, + preRun: func() { + mockFindProjectPathFrom("", ErrFake) + }, + postRun: func() {}, + }, + { + name: "fail-for-GetProjectFrom", + args: args{ + stackDir: "./testdata/appops/http-echo/dev/", + }, + project: nil, + stack: nil, + wantErr: true, + preRun: func() { + mockGetProjectFrom(ErrFake) + }, + postRun: func() {}, + }, + } + for _, tt := range tests { + mockey.PatchConvey(tt.name, t, func() { + tt.preRun() + project, stack, err := DetectProjectAndStack(tt.args.stackDir) + tt.postRun() + if (err != nil) != tt.wantErr { + t.Errorf("DetectProjectAndStack() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(project, tt.project) { + t.Errorf("DetectProjectAndStack() got = %v, want %v", project, tt.project) + } + if !reflect.DeepEqual(stack, tt.stack) { + t.Errorf("DetectProjectAndStack() gosuccess = %v, want %v", stack, tt.stack) + } + }) + } +} + +func mockAbs(mockAbs string, mockErr error) { + mockey.Mock(filepath.Abs).To(func(_ string) (string, error) { + return mockAbs, mockErr + }).Build() +} + +func mockGetStackFrom(mockErr error) { + mockey.Mock(GetStackFrom).To(func(_ string) (*v1.Stack, error) { + if mockErr == nil { + return &v1.Stack{}, nil + } + return nil, mockErr + }).Build() +} + +func mockGetProjectFrom(mockErr error) { + mockey.Mock(getProjectFrom).To(func(_ string) (*v1.Project, error) { + if mockErr == nil { + return &v1.Project{}, nil + } + return nil, mockErr + }).Build() +} + +func mockFindProjectPathFrom(mockProjectDir string, mockErr error) { + mockey.Mock(findProjectPathFrom).To(func(_ string) (string, error) { + if mockErr == nil { + return mockProjectDir, nil + } + return "", mockErr + }).Build() +} diff --git a/pkg/apis/project/testdata/appops/empty-app/base/base.k b/pkg/project/testdata/appops/empty-app/base/base.k similarity index 100% rename from pkg/apis/project/testdata/appops/empty-app/base/base.k rename to pkg/project/testdata/appops/empty-app/base/base.k diff --git a/pkg/apis/project/testdata/appops/empty-app/dev/ci-test/settings.yaml b/pkg/project/testdata/appops/empty-app/dev/ci-test/settings.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/empty-app/dev/ci-test/settings.yaml rename to pkg/project/testdata/appops/empty-app/dev/ci-test/settings.yaml diff --git a/pkg/apis/project/testdata/appops/empty-app/dev/kcl.yaml b/pkg/project/testdata/appops/empty-app/dev/kcl.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/empty-app/dev/kcl.yaml rename to pkg/project/testdata/appops/empty-app/dev/kcl.yaml diff --git a/pkg/apis/project/testdata/appops/empty-app/dev/main.k b/pkg/project/testdata/appops/empty-app/dev/main.k similarity index 100% rename from pkg/apis/project/testdata/appops/empty-app/dev/main.k rename to pkg/project/testdata/appops/empty-app/dev/main.k diff --git a/pkg/apis/project/testdata/appops/empty-app/dev/stack.yaml b/pkg/project/testdata/appops/empty-app/dev/stack.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/empty-app/dev/stack.yaml rename to pkg/project/testdata/appops/empty-app/dev/stack.yaml diff --git a/pkg/apis/project/testdata/appops/empty-app/project.yaml b/pkg/project/testdata/appops/empty-app/project.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/empty-app/project.yaml rename to pkg/project/testdata/appops/empty-app/project.yaml diff --git a/pkg/apis/project/testdata/appops/http-echo/README.md b/pkg/project/testdata/appops/http-echo/README.md similarity index 100% rename from pkg/apis/project/testdata/appops/http-echo/README.md rename to pkg/project/testdata/appops/http-echo/README.md diff --git a/pkg/apis/project/testdata/appops/http-echo/base/base.k b/pkg/project/testdata/appops/http-echo/base/base.k similarity index 100% rename from pkg/apis/project/testdata/appops/http-echo/base/base.k rename to pkg/project/testdata/appops/http-echo/base/base.k diff --git a/pkg/apis/project/testdata/appops/http-echo/dev/ci-test/settings.yaml b/pkg/project/testdata/appops/http-echo/dev/ci-test/settings.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/http-echo/dev/ci-test/settings.yaml rename to pkg/project/testdata/appops/http-echo/dev/ci-test/settings.yaml diff --git a/pkg/apis/project/testdata/appops/http-echo/dev/kcl.yaml b/pkg/project/testdata/appops/http-echo/dev/kcl.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/http-echo/dev/kcl.yaml rename to pkg/project/testdata/appops/http-echo/dev/kcl.yaml diff --git a/pkg/apis/project/testdata/appops/http-echo/dev/main.k b/pkg/project/testdata/appops/http-echo/dev/main.k similarity index 100% rename from pkg/apis/project/testdata/appops/http-echo/dev/main.k rename to pkg/project/testdata/appops/http-echo/dev/main.k diff --git a/pkg/apis/project/testdata/appops/http-echo/dev/stack.yaml b/pkg/project/testdata/appops/http-echo/dev/stack.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/http-echo/dev/stack.yaml rename to pkg/project/testdata/appops/http-echo/dev/stack.yaml diff --git a/pkg/apis/project/testdata/appops/http-echo/project.yaml b/pkg/project/testdata/appops/http-echo/project.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/http-echo/project.yaml rename to pkg/project/testdata/appops/http-echo/project.yaml diff --git a/pkg/apis/project/testdata/appops/nginx-example/README.md b/pkg/project/testdata/appops/nginx-example/README.md similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/README.md rename to pkg/project/testdata/appops/nginx-example/README.md diff --git a/pkg/apis/project/testdata/appops/nginx-example/base/base.k b/pkg/project/testdata/appops/nginx-example/base/base.k similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/base/base.k rename to pkg/project/testdata/appops/nginx-example/base/base.k diff --git a/pkg/apis/project/testdata/appops/nginx-example/dev/ci-test/settings.yaml b/pkg/project/testdata/appops/nginx-example/dev/ci-test/settings.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/dev/ci-test/settings.yaml rename to pkg/project/testdata/appops/nginx-example/dev/ci-test/settings.yaml diff --git a/pkg/apis/project/testdata/appops/nginx-example/dev/kcl.yaml b/pkg/project/testdata/appops/nginx-example/dev/kcl.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/dev/kcl.yaml rename to pkg/project/testdata/appops/nginx-example/dev/kcl.yaml diff --git a/pkg/apis/project/testdata/appops/nginx-example/dev/main.k b/pkg/project/testdata/appops/nginx-example/dev/main.k similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/dev/main.k rename to pkg/project/testdata/appops/nginx-example/dev/main.k diff --git a/pkg/apis/project/testdata/appops/nginx-example/dev/stack.yaml b/pkg/project/testdata/appops/nginx-example/dev/stack.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/dev/stack.yaml rename to pkg/project/testdata/appops/nginx-example/dev/stack.yaml diff --git a/pkg/apis/project/testdata/appops/nginx-example/prod/ci-test/settings.yaml b/pkg/project/testdata/appops/nginx-example/prod/ci-test/settings.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/prod/ci-test/settings.yaml rename to pkg/project/testdata/appops/nginx-example/prod/ci-test/settings.yaml diff --git a/pkg/apis/project/testdata/appops/nginx-example/prod/kcl.yaml b/pkg/project/testdata/appops/nginx-example/prod/kcl.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/prod/kcl.yaml rename to pkg/project/testdata/appops/nginx-example/prod/kcl.yaml diff --git a/pkg/apis/project/testdata/appops/nginx-example/prod/main.k b/pkg/project/testdata/appops/nginx-example/prod/main.k similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/prod/main.k rename to pkg/project/testdata/appops/nginx-example/prod/main.k diff --git a/pkg/apis/project/testdata/appops/nginx-example/prod/stack.yaml b/pkg/project/testdata/appops/nginx-example/prod/stack.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/prod/stack.yaml rename to pkg/project/testdata/appops/nginx-example/prod/stack.yaml diff --git a/pkg/apis/project/testdata/appops/nginx-example/project.yaml b/pkg/project/testdata/appops/nginx-example/project.yaml similarity index 100% rename from pkg/apis/project/testdata/appops/nginx-example/project.yaml rename to pkg/project/testdata/appops/nginx-example/project.yaml diff --git a/pkg/apis/project/testdata/kcl.mod b/pkg/project/testdata/kcl.mod similarity index 100% rename from pkg/apis/project/testdata/kcl.mod rename to pkg/project/testdata/kcl.mod diff --git a/pkg/scaffold/templates.go b/pkg/scaffold/templates.go index ace7c86f..1bbdfe0e 100644 --- a/pkg/scaffold/templates.go +++ b/pkg/scaffold/templates.go @@ -17,7 +17,6 @@ import ( "github.com/spf13/afero" "github.com/texttheater/golang-levenshtein/levenshtein" - "kusionstack.io/kusion/pkg/apis/stack" "kusionstack.io/kusion/pkg/log" "kusionstack.io/kusion/pkg/util/kfile" ) @@ -414,7 +413,7 @@ func RenderFSTemplate(srcFS afero.Fs, srcDir string, destFS afero.Fs, destDir st dest := filepath.Join(destDir, d.Name()) if d.IsDir() { // Base dir or stack dir - fileInfo, err := srcFS.Stat(filepath.Join(src, stack.File)) + fileInfo, err := srcFS.Stat(filepath.Join(src, "stack.yaml")) if err == nil && fileInfo.Mode().IsRegular() { // Project config can be overridden configs := make(map[string]interface{}, len(tc.ProjectConfig))