From 00311671bac99135dea903a1a36c6ab762d23c44 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Fri, 28 Feb 2025 10:06:05 -0800 Subject: [PATCH 1/3] refactor: passes env down to deployment modules --- cli/cmd/cmds/module/template.go | 8 +-- foundry/api/blueprint.cue | 5 +- lib/project/blueprint/defaults/deployment.go | 6 +- .../deployment/deployer/deployer_test.go | 49 +++++++------ lib/project/deployment/generator/generator.go | 8 +-- .../deployment/generator/generator_test.go | 69 +++++++++++-------- lib/project/deployment/manifest_gen.go | 2 +- lib/project/deployment/mocks/manifest.go | 24 ++++--- lib/project/deployment/module.go | 4 +- .../deployment/providers/helm/generator.go | 2 +- .../providers/helm/generator_test.go | 2 +- .../deployment/providers/kcl/client/config.go | 1 + .../deployment/providers/kcl/generator.go | 4 +- .../providers/kcl/generator_test.go | 8 ++- lib/schema/blueprint/project/cue_types_gen.go | 13 ++-- lib/schema/blueprint/project/deployment.cue | 12 ++-- 16 files changed, 126 insertions(+), 91 deletions(-) diff --git a/cli/cmd/cmds/module/template.go b/cli/cmd/cmds/module/template.go index e87e8368..4a01d1d3 100644 --- a/cli/cmd/cmds/module/template.go +++ b/cli/cmd/cmds/module/template.go @@ -55,7 +55,7 @@ func (c *TemplateCmd) Run(ctx run.RunContext) error { manifests := make(map[string][]byte) gen := generator.NewGenerator(ctx.ManifestGeneratorStore, ctx.Logger) if c.Module != "" { - mod, ok := bundle.Bundle[c.Module] + mod, ok := bundle.Bundle.Modules[c.Module] if !ok { return fmt.Errorf("module %q not found", c.Module) } @@ -65,7 +65,7 @@ func (c *TemplateCmd) Run(ctx run.RunContext) error { mod.Path = path } - out, err := gen.Generate(mod) + out, err := gen.Generate(mod, bundle.Bundle.Env) if err != nil { return fmt.Errorf("failed to generate manifest: %w", err) } @@ -75,13 +75,13 @@ func (c *TemplateCmd) Run(ctx run.RunContext) error { } else { if c.SetPath != nil { for name, path := range c.SetPath { - mod, ok := bundle.Bundle[name] + mod, ok := bundle.Bundle.Modules[name] if !ok { return fmt.Errorf("module %q not found", name) } mod.Path = path - bundle.Bundle[name] = mod + bundle.Bundle.Modules[name] = mod } } diff --git a/foundry/api/blueprint.cue b/foundry/api/blueprint.cue index e81d6418..cf4db50e 100644 --- a/foundry/api/blueprint.cue +++ b/foundry/api/blueprint.cue @@ -18,8 +18,9 @@ project: { merge: {} tag: {} } - modules: { - main: { + bundle: { + env: "dev" + modules: main: { name: "app" version: "0.4.0" values: { diff --git a/lib/project/blueprint/defaults/deployment.go b/lib/project/blueprint/defaults/deployment.go index b8a09cea..c8b1aa53 100644 --- a/lib/project/blueprint/defaults/deployment.go +++ b/lib/project/blueprint/defaults/deployment.go @@ -13,7 +13,7 @@ func (d DeploymentModuleSetter) SetDefault(v cue.Value) (cue.Value, error) { projectName, _ := v.LookupPath(cue.ParsePath("project.name")).String() registry, _ := v.LookupPath(cue.ParsePath("global.deployment.registries.modules")).String() - modules := v.LookupPath(cue.ParsePath("project.deployment.modules")) + modules := v.LookupPath(cue.ParsePath("project.deployment.bundle.modules")) if !modules.Exists() || modules.Err() != nil { return v, nil } @@ -30,14 +30,14 @@ func (d DeploymentModuleSetter) SetDefault(v cue.Value) (cue.Value, error) { if projectName != "" { instance := module.LookupPath(cue.ParsePath("instance")) if !instance.Exists() { - v = v.FillPath(cue.ParsePath(fmt.Sprintf("project.deployment.modules.%s.instance", moduleName)), projectName) + v = v.FillPath(cue.ParsePath(fmt.Sprintf("project.deployment.bundle.modules.%s.instance", moduleName)), projectName) } } if registry != "" { r := module.LookupPath(cue.ParsePath("registry")) if !r.Exists() { - v = v.FillPath(cue.ParsePath(fmt.Sprintf("project.deployment.modules.%s.registry", moduleName)), registry) + v = v.FillPath(cue.ParsePath(fmt.Sprintf("project.deployment.bundle.modules.%s.registry", moduleName)), registry) } } } diff --git a/lib/project/deployment/deployer/deployer_test.go b/lib/project/deployment/deployer/deployer_test.go index 17fe7c1e..c7623714 100644 --- a/lib/project/deployment/deployer/deployer_test.go +++ b/lib/project/deployment/deployer/deployer_test.go @@ -38,7 +38,7 @@ func TestDeployerDeploy(t *testing.T) { Blueprint: sb.Blueprint{ Project: &sp.Project{ Deployment: &sp.Deployment{ - Modules: bundle, + Bundle: bundle, }, }, Global: &sg.Global{ @@ -85,14 +85,17 @@ func TestDeployerDeploy(t *testing.T) { project: newProject( "project", sp.ModuleBundle{ - "main": { - Instance: "instance", - Name: "module", - Namespace: "default", - Registry: "registry", - Type: "kcl", - Values: map[string]string{"key": "value"}, - Version: "v1.0.0", + Env: "test", + Modules: map[string]sp.Module{ + "main": { + Instance: "instance", + Name: "module", + Namespace: "default", + Registry: "registry", + Type: "kcl", + Values: map[string]string{"key": "value"}, + Version: "v1.0.0", + }, }, }, ), @@ -116,17 +119,19 @@ func TestDeployerDeploy(t *testing.T) { assert.Equal(t, "manifest", string(c)) mod := `{ - main: { - env: "" - instance: "instance" - name: "module" - namespace: "default" - registry: "registry" - type: "kcl" - values: { - key: "value" + env: "test" + modules: { + main: { + instance: "instance" + name: "module" + namespace: "default" + registry: "registry" + type: "kcl" + values: { + key: "value" + } + version: "v1.0.0" } - version: "v1.0.0" } }` c, err = afero.ReadFile(r.fs, mkPath("dev", "project", "mod.cue")) @@ -153,7 +158,8 @@ func TestDeployerDeploy(t *testing.T) { project: newProject( "project", sp.ModuleBundle{ - "main": { + Env: "test", + Modules: map[string]sp.Module{"main": { Instance: "instance", Name: "module", Namespace: "default", @@ -162,6 +168,7 @@ func TestDeployerDeploy(t *testing.T) { Values: map[string]string{"key": "value"}, Version: "v1.0.0", }, + }, }, ), files: map[string]string{ @@ -248,7 +255,7 @@ func TestDeployerDeploy(t *testing.T) { map[deployment.Provider]func(*slog.Logger) deployment.ManifestGenerator{ deployment.ProviderKCL: func(logger *slog.Logger) deployment.ManifestGenerator { return &dm.ManifestGeneratorMock{ - GenerateFunc: func(mod sp.Module) ([]byte, error) { + GenerateFunc: func(mod sp.Module, env string) ([]byte, error) { return []byte("manifest"), nil }, } diff --git a/lib/project/deployment/generator/generator.go b/lib/project/deployment/generator/generator.go index 6d3a6150..613e6980 100644 --- a/lib/project/deployment/generator/generator.go +++ b/lib/project/deployment/generator/generator.go @@ -40,9 +40,9 @@ func (d *Generator) GenerateBundle(b deployment.ModuleBundle, env cue.Value) (Ge } results := make(map[string][]byte) - for name, module := range nb.Bundle { + for name, module := range nb.Bundle.Modules { d.logger.Debug("Generating module", "name", name) - result, err := d.Generate(module) + result, err := d.Generate(module, b.Bundle.Env) if err != nil { return GeneratorResult{}, fmt.Errorf("failed to generate module %s: %w", name, err) } @@ -57,7 +57,7 @@ func (d *Generator) GenerateBundle(b deployment.ModuleBundle, env cue.Value) (Ge } // Generate generates manifests for a deployment module. -func (d *Generator) Generate(m sp.Module) ([]byte, error) { +func (d *Generator) Generate(m sp.Module, env string) ([]byte, error) { if err := deployment.Validate(m); err != nil { return nil, fmt.Errorf("failed to validate module: %w", err) } @@ -67,7 +67,7 @@ func (d *Generator) Generate(m sp.Module) ([]byte, error) { return nil, fmt.Errorf("failed to get generator for module: %w", err) } - manifests, err := mg.Generate(m) + manifests, err := mg.Generate(m, env) if err != nil { return nil, fmt.Errorf("failed to generate manifest for module: %w", err) } diff --git a/lib/project/deployment/generator/generator_test.go b/lib/project/deployment/generator/generator_test.go index 23a830e8..7b91960c 100644 --- a/lib/project/deployment/generator/generator_test.go +++ b/lib/project/deployment/generator/generator_test.go @@ -29,14 +29,17 @@ func TestGeneratorGenerateBundle(t *testing.T) { name: "full", bundle: deployment.ModuleBundle{ Bundle: sp.ModuleBundle{ - "test": sp.Module{ - Instance: "instance", - Name: "test", - Namespace: "default", - Registry: "registry", - Type: "kcl", - Values: ctx.CompileString(`foo: "bar"`), - Version: "1.0.0", + Env: "test", + Modules: map[string]sp.Module{ + "test": sp.Module{ + Instance: "instance", + Name: "test", + Namespace: "default", + Registry: "registry", + Type: "kcl", + Values: ctx.CompileString(`foo: "bar"`), + Version: "1.0.0", + }, }, }, }, @@ -47,17 +50,19 @@ func TestGeneratorGenerateBundle(t *testing.T) { require.NoError(t, err) m := `{ - test: { - env: "" - instance: "instance" - name: "test" - namespace: "default" - registry: "registry" - type: "kcl" - values: { - foo: "bar" + env: "test" + modules: { + test: { + instance: "instance" + name: "test" + namespace: "default" + registry: "registry" + type: "kcl" + values: { + foo: "bar" + } + version: "1.0.0" } - version: "1.0.0" } }` assert.Equal(t, m, string(result.Module)) @@ -68,14 +73,17 @@ func TestGeneratorGenerateBundle(t *testing.T) { name: "manifest error", bundle: deployment.ModuleBundle{ Bundle: sp.ModuleBundle{ - "test": sp.Module{ - Instance: "instance", - Name: "test", - Namespace: "default", - Registry: "registry", - Type: "kcl", - Values: ctx.CompileString(`foo: "bar"`), - Version: "1.0.0", + Env: "test", + Modules: map[string]sp.Module{ + "test": sp.Module{ + Instance: "instance", + Name: "test", + Namespace: "default", + Registry: "registry", + Type: "kcl", + Values: ctx.CompileString(`foo: "bar"`), + Version: "1.0.0", + }, }, }, }, @@ -90,7 +98,7 @@ func TestGeneratorGenerateBundle(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { mg := &mocks.ManifestGeneratorMock{ - GenerateFunc: func(mod sp.Module) ([]byte, error) { + GenerateFunc: func(mod sp.Module, env string) ([]byte, error) { if tt.err { return nil, fmt.Errorf("error") } @@ -125,6 +133,7 @@ func TestGeneratorGenerate(t *testing.T) { name string module sp.Module yaml string + env string err bool validate func(t *testing.T, result []byte, err error) }{ @@ -140,6 +149,7 @@ func TestGeneratorGenerate(t *testing.T) { Version: "1.0.0", }, yaml: "test", + env: "test", err: false, validate: func(t *testing.T, result []byte, err error) { require.NoError(t, err) @@ -156,6 +166,7 @@ func TestGeneratorGenerate(t *testing.T) { Version: "1.0.0", }, yaml: "test", + env: "test", err: true, validate: func(t *testing.T, result []byte, err error) { assert.Error(t, err) @@ -166,7 +177,7 @@ func TestGeneratorGenerate(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { mg := &mocks.ManifestGeneratorMock{ - GenerateFunc: func(mod sp.Module) ([]byte, error) { + GenerateFunc: func(mod sp.Module, env string) ([]byte, error) { if tt.err { return nil, fmt.Errorf("error") } @@ -188,7 +199,7 @@ func TestGeneratorGenerate(t *testing.T) { store: store, } - result, err := gen.Generate(tt.module) + result, err := gen.Generate(tt.module, tt.env) tt.validate(t, result, err) }) } diff --git a/lib/project/deployment/manifest_gen.go b/lib/project/deployment/manifest_gen.go index 561218b8..bfb8c737 100644 --- a/lib/project/deployment/manifest_gen.go +++ b/lib/project/deployment/manifest_gen.go @@ -9,5 +9,5 @@ import ( // ManifestGenerator generates deployment manifests. type ManifestGenerator interface { // Generate generates a deployment manifest for the given module. - Generate(mod sp.Module) ([]byte, error) + Generate(mod sp.Module, env string) ([]byte, error) } diff --git a/lib/project/deployment/mocks/manifest.go b/lib/project/deployment/mocks/manifest.go index 48c2fd50..42fe664c 100644 --- a/lib/project/deployment/mocks/manifest.go +++ b/lib/project/deployment/mocks/manifest.go @@ -4,7 +4,7 @@ package mocks import ( - "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" + sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" "sync" ) @@ -14,7 +14,7 @@ import ( // // // make and configure a mocked deployment.ManifestGenerator // mockedManifestGenerator := &ManifestGeneratorMock{ -// GenerateFunc: func(mod schema.DeploymentModule) ([]byte, error) { +// GenerateFunc: func(mod sp.Module, env string) ([]byte, error) { // panic("mock out the Generate method") // }, // } @@ -25,33 +25,37 @@ import ( // } type ManifestGeneratorMock struct { // GenerateFunc mocks the Generate method. - GenerateFunc func(mod project.Module) ([]byte, error) + GenerateFunc func(mod sp.Module, env string) ([]byte, error) // calls tracks calls to the methods. calls struct { // Generate holds details about calls to the Generate method. Generate []struct { // Mod is the mod argument value. - Mod project.Module + Mod sp.Module + // Env is the env argument value. + Env string } } lockGenerate sync.RWMutex } // Generate calls GenerateFunc. -func (mock *ManifestGeneratorMock) Generate(mod project.Module) ([]byte, error) { +func (mock *ManifestGeneratorMock) Generate(mod sp.Module, env string) ([]byte, error) { if mock.GenerateFunc == nil { panic("ManifestGeneratorMock.GenerateFunc: method is nil but ManifestGenerator.Generate was just called") } callInfo := struct { - Mod project.Module + Mod sp.Module + Env string }{ Mod: mod, + Env: env, } mock.lockGenerate.Lock() mock.calls.Generate = append(mock.calls.Generate, callInfo) mock.lockGenerate.Unlock() - return mock.GenerateFunc(mod) + return mock.GenerateFunc(mod, env) } // GenerateCalls gets all the calls that were made to Generate. @@ -59,10 +63,12 @@ func (mock *ManifestGeneratorMock) Generate(mod project.Module) ([]byte, error) // // len(mockedManifestGenerator.GenerateCalls()) func (mock *ManifestGeneratorMock) GenerateCalls() []struct { - Mod project.Module + Mod sp.Module + Env string } { var calls []struct { - Mod project.Module + Mod sp.Module + Env string } mock.lockGenerate.RLock() calls = mock.calls.Generate diff --git a/lib/project/deployment/module.go b/lib/project/deployment/module.go index 82e6c99e..93865041 100644 --- a/lib/project/deployment/module.go +++ b/lib/project/deployment/module.go @@ -27,8 +27,8 @@ func (d *ModuleBundle) Dump() ([]byte, error) { // NewModuleBundle creates a new deployment module bundle from a project. func NewModuleBundle(p *project.Project) ModuleBundle { - bundle := p.Blueprint.Project.Deployment.Modules - raw := p.RawBlueprint.Get("project.deployment.modules") + bundle := p.Blueprint.Project.Deployment.Bundle + raw := p.RawBlueprint.Get("project.deployment.bundle") return ModuleBundle{ Bundle: bundle, Raw: raw, diff --git a/lib/project/deployment/providers/helm/generator.go b/lib/project/deployment/providers/helm/generator.go index 6e1000a1..ef5f9a4e 100644 --- a/lib/project/deployment/providers/helm/generator.go +++ b/lib/project/deployment/providers/helm/generator.go @@ -15,7 +15,7 @@ type HelmManifestGenerator struct { logger *slog.Logger } -func (h *HelmManifestGenerator) Generate(mod sp.Module) ([]byte, error) { +func (h *HelmManifestGenerator) Generate(mod sp.Module, env string) ([]byte, error) { client := action.NewInstall(&action.Configuration{}) client.ReleaseName = mod.Instance diff --git a/lib/project/deployment/providers/helm/generator_test.go b/lib/project/deployment/providers/helm/generator_test.go index cdb50906..3cc6f037 100644 --- a/lib/project/deployment/providers/helm/generator_test.go +++ b/lib/project/deployment/providers/helm/generator_test.go @@ -40,7 +40,7 @@ func TestHelmManifestGenerator(t *testing.T) { Version: "1.0.0", } - result, err := gen.Generate(mod) + result, err := gen.Generate(mod, "test") require.NoError(t, err) golden, err := os.ReadFile("./testdata/golden.yaml") diff --git a/lib/project/deployment/providers/kcl/client/config.go b/lib/project/deployment/providers/kcl/client/config.go index d91dc65f..a106133c 100644 --- a/lib/project/deployment/providers/kcl/client/config.go +++ b/lib/project/deployment/providers/kcl/client/config.go @@ -8,6 +8,7 @@ import ( // KCLModuleConfig contains the configuration given to a KCL module. type KCLModuleConfig struct { + Env string `json:"env"` Instance string `json:"instance"` Name string `json:"name"` Namespace string `json:"namespace"` diff --git a/lib/project/deployment/providers/kcl/generator.go b/lib/project/deployment/providers/kcl/generator.go index 9b7a45e7..03bc6365 100644 --- a/lib/project/deployment/providers/kcl/generator.go +++ b/lib/project/deployment/providers/kcl/generator.go @@ -32,7 +32,7 @@ type KCLManifestGenerator struct { logger *slog.Logger } -func (g *KCLManifestGenerator) Generate(mod sp.Module) ([]byte, error) { +func (g *KCLManifestGenerator) Generate(mod sp.Module, env string) ([]byte, error) { var conf client.KCLModuleConfig var path string if mod.Path != "" { @@ -44,6 +44,7 @@ func (g *KCLManifestGenerator) Generate(mod sp.Module) ([]byte, error) { path = mod.Path conf = client.KCLModuleConfig{ + Env: env, Instance: mod.Instance, Name: kmod.Package.Name, Namespace: mod.Namespace, @@ -53,6 +54,7 @@ func (g *KCLManifestGenerator) Generate(mod sp.Module) ([]byte, error) { } else { path = fmt.Sprintf("oci://%s/%s?tag=%s", strings.TrimSuffix(mod.Registry, "/"), mod.Name, mod.Version) conf = client.KCLModuleConfig{ + Env: env, Instance: mod.Instance, Name: mod.Name, Namespace: mod.Namespace, diff --git a/lib/project/deployment/providers/kcl/generator_test.go b/lib/project/deployment/providers/kcl/generator_test.go index f88e0932..e90fa7a1 100644 --- a/lib/project/deployment/providers/kcl/generator_test.go +++ b/lib/project/deployment/providers/kcl/generator_test.go @@ -24,6 +24,7 @@ func TestKCLManifestGeneratorGenerate(t *testing.T) { tests := []struct { name string module sp.Module + env string out string files map[string]string err bool @@ -39,11 +40,13 @@ func TestKCLManifestGeneratorGenerate(t *testing.T) { Values: "test", Version: "1.0.0", }, + env: "test", out: "output", err: false, validate: func(t *testing.T, result testResult) { require.NoError(t, result.err) assert.Equal(t, client.KCLModuleConfig{ + Env: "test", Instance: "instance", Namespace: "default", Name: "module", @@ -62,6 +65,7 @@ func TestKCLManifestGeneratorGenerate(t *testing.T) { Path: "/mod", Values: "test", }, + env: "test", out: "output", files: map[string]string{ "/mod/kcl.mod": ` @@ -75,6 +79,7 @@ version = "1.0.0" validate: func(t *testing.T, result testResult) { require.NoError(t, result.err) assert.Equal(t, client.KCLModuleConfig{ + Env: "test", Instance: "instance", Name: "module", Namespace: "default", @@ -95,6 +100,7 @@ version = "1.0.0" Values: "test", Version: "1.0.0", }, + env: "test", out: "output", err: true, validate: func(t *testing.T, result testResult) { @@ -131,7 +137,7 @@ version = "1.0.0" logger: testutils.NewNoopLogger(), } - out, err := g.Generate(tt.module) + out, err := g.Generate(tt.module, tt.env) tt.validate(t, testResult{ conf: c, err: err, diff --git a/lib/schema/blueprint/project/cue_types_gen.go b/lib/schema/blueprint/project/cue_types_gen.go index 2f88c780..db8bcba4 100644 --- a/lib/schema/blueprint/project/cue_types_gen.go +++ b/lib/schema/blueprint/project/cue_types_gen.go @@ -15,16 +15,17 @@ type Deployment struct { // On contains the events that trigger the deployment. On map[string]any/* CUE top */ `json:"on"` - // Modules contains the deployment modules for the project. - Modules ModuleBundle `json:"modules"` + // Bundle contains the deployment modules for the project. + Bundle ModuleBundle `json:"bundle"` } -type ModuleBundle map[string]Module - -type Module struct { - // Env contains the environment this module is being deployed to. +type ModuleBundle struct { Env string `json:"env"` + Modules map[string]Module `json:"modules"` +} + +type Module struct { // Instance contains the instance name to use for all generated resources. Instance string `json:"instance,omitempty"` diff --git a/lib/schema/blueprint/project/deployment.cue b/lib/schema/blueprint/project/deployment.cue index 29de80b5..11771354 100644 --- a/lib/schema/blueprint/project/deployment.cue +++ b/lib/schema/blueprint/project/deployment.cue @@ -4,16 +4,16 @@ package project // On contains the events that trigger the deployment. on: [string]: _ - // Modules contains the deployment modules for the project. - modules: #ModuleBundle + // Bundle contains the deployment modules for the project. + bundle: #ModuleBundle } -#ModuleBundle: [string]: #Module - -#Module: { - // Env contains the environment this module is being deployed to. +#ModuleBundle: { env: string | *"dev" + modules: [string]: #Module +} +#Module: { // Instance contains the instance name to use for all generated resources. instance?: string From c017a0b81fa33af7ff8da268f5036ada444ba156 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Mon, 3 Mar 2025 11:24:02 -0800 Subject: [PATCH 2/3] wip: bumps app module --- foundry/api/blueprint.cue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foundry/api/blueprint.cue b/foundry/api/blueprint.cue index cf4db50e..fe66eb2d 100644 --- a/foundry/api/blueprint.cue +++ b/foundry/api/blueprint.cue @@ -22,7 +22,7 @@ project: { env: "dev" modules: main: { name: "app" - version: "0.4.0" + version: "0.4.3" values: { deployment: containers: main: { image: { From aaee2c6908a75868ba93b29dcf5c25d09f90925a Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Mon, 3 Mar 2025 13:47:32 -0800 Subject: [PATCH 3/3] chore: auto-deploy using env --- foundry/api/blueprint.cue | 2 +- lib/project/deployment/deployer/deployer.go | 7 ++- .../deployment/deployer/deployer_test.go | 48 ++++++++++++++----- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/foundry/api/blueprint.cue b/foundry/api/blueprint.cue index fe66eb2d..19704397 100644 --- a/foundry/api/blueprint.cue +++ b/foundry/api/blueprint.cue @@ -19,7 +19,7 @@ project: { tag: {} } bundle: { - env: "dev" + env: "shared-services" modules: main: { name: "app" version: "0.4.3" diff --git a/lib/project/deployment/deployer/deployer.go b/lib/project/deployment/deployer/deployer.go index 311ed20b..8376c033 100644 --- a/lib/project/deployment/deployer/deployer.go +++ b/lib/project/deployment/deployer/deployer.go @@ -52,6 +52,10 @@ type Deployer struct { // DeployProject deploys the manifests for a project to the GitOps repository. func (d *Deployer) Deploy() error { + if d.project.Blueprint.Project.Deployment.Bundle.Env == "prod" { + return fmt.Errorf("cannot deploy to production environment") + } + r, err := d.clone() if err != nil { return err @@ -134,7 +138,8 @@ func (d *Deployer) Deploy() error { // buildProjectPath builds the path to the project in the GitOps repository. func (d *Deployer) buildProjectPath() string { globalDeploy := d.project.Blueprint.Global.Deployment - return fmt.Sprintf(PATH, globalDeploy.Root, DEFAULT_ENV, d.project.Name) + env := d.project.Blueprint.Project.Deployment.Bundle.Env + return fmt.Sprintf(PATH, globalDeploy.Root, env, d.project.Name) } // checkProjectPath checks if the project path exists and creates it if it does not. diff --git a/lib/project/deployment/deployer/deployer_test.go b/lib/project/deployment/deployer/deployer_test.go index c7623714..91d06b78 100644 --- a/lib/project/deployment/deployer/deployer_test.go +++ b/lib/project/deployment/deployer/deployer_test.go @@ -100,21 +100,21 @@ func TestDeployerDeploy(t *testing.T) { }, ), files: map[string]string{ - mkPath("dev", "project", "env.mod.cue"): `main: values: { key1: "value1" }`, + mkPath("test", "project", "env.mod.cue"): `main: values: { key1: "value1" }`, }, dryrun: false, validate: func(t *testing.T, r testResult) { require.NoError(t, r.err) - e, err := afero.Exists(r.fs, mkPath("dev", "project", "main.yaml")) + e, err := afero.Exists(r.fs, mkPath("test", "project", "main.yaml")) require.NoError(t, err) assert.True(t, e) - e, err = afero.Exists(r.fs, mkPath("dev", "project", "mod.cue")) + e, err = afero.Exists(r.fs, mkPath("test", "project", "mod.cue")) require.NoError(t, err) assert.True(t, e) - c, err := afero.ReadFile(r.fs, mkPath("dev", "project", "main.yaml")) + c, err := afero.ReadFile(r.fs, mkPath("test", "project", "main.yaml")) require.NoError(t, err) assert.Equal(t, "manifest", string(c)) @@ -134,7 +134,7 @@ func TestDeployerDeploy(t *testing.T) { } } }` - c, err = afero.ReadFile(r.fs, mkPath("dev", "project", "mod.cue")) + c, err = afero.ReadFile(r.fs, mkPath("test", "project", "mod.cue")) require.NoError(t, err) assert.Equal(t, mod, string(c)) @@ -172,21 +172,21 @@ func TestDeployerDeploy(t *testing.T) { }, ), files: map[string]string{ - mkPath("dev", "project", "extra.yaml"): "extra", + mkPath("test", "project", "extra.yaml"): "extra", }, dryrun: true, validate: func(t *testing.T, r testResult) { require.NoError(t, r.err) - e, err := afero.Exists(r.fs, mkPath("dev", "project", "main.yaml")) + e, err := afero.Exists(r.fs, mkPath("test", "project", "main.yaml")) require.NoError(t, err) assert.True(t, e) - e, err = afero.Exists(r.fs, mkPath("dev", "project", "mod.cue")) + e, err = afero.Exists(r.fs, mkPath("test", "project", "mod.cue")) require.NoError(t, err) assert.True(t, e) - e, err = afero.Exists(r.fs, mkPath("dev", "project", "extra.yaml")) + e, err = afero.Exists(r.fs, mkPath("test", "project", "extra.yaml")) require.NoError(t, err) assert.False(t, e) @@ -194,13 +194,13 @@ func TestDeployerDeploy(t *testing.T) { require.NoError(t, err) st, err := wt.Status() require.NoError(t, err) - fst := st.File("root/dev/project/extra.yaml") + fst := st.File("root/test/project/extra.yaml") assert.Equal(t, fst.Staging, gg.Deleted) - fst = st.File("root/dev/project/main.yaml") + fst = st.File("root/test/project/main.yaml") assert.Equal(t, fst.Staging, gg.Added) - fst = st.File("root/dev/project/mod.cue") + fst = st.File("root/test/project/mod.cue") assert.Equal(t, fst.Staging, gg.Added) head, err := r.repo.Head() @@ -210,6 +210,30 @@ func TestDeployerDeploy(t *testing.T) { assert.Equal(t, "initial commit", cm.Message) }, }, + { + name: "deploy to production", + project: newProject( + "project", + sp.ModuleBundle{ + Env: "prod", + Modules: map[string]sp.Module{"main": { + Instance: "instance", + Name: "module", + Namespace: "default", + Registry: "registry", + Type: "kcl", + Values: map[string]string{"key": "value"}, + Version: "v1.0.0", + }, + }, + }, + ), + files: map[string]string{}, + dryrun: true, + validate: func(t *testing.T, r testResult) { + assert.Error(t, r.err) + }, + }, } for _, tt := range tests {