Skip to content

Commit 8f2920a

Browse files
authored
refactor: passes env down to deployment modules (#146)
1 parent ef602b2 commit 8f2920a

File tree

17 files changed

+169
-105
lines changed

17 files changed

+169
-105
lines changed

cli/cmd/cmds/module/template.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (c *TemplateCmd) Run(ctx run.RunContext) error {
5555
manifests := make(map[string][]byte)
5656
gen := generator.NewGenerator(ctx.ManifestGeneratorStore, ctx.Logger)
5757
if c.Module != "" {
58-
mod, ok := bundle.Bundle[c.Module]
58+
mod, ok := bundle.Bundle.Modules[c.Module]
5959
if !ok {
6060
return fmt.Errorf("module %q not found", c.Module)
6161
}
@@ -65,7 +65,7 @@ func (c *TemplateCmd) Run(ctx run.RunContext) error {
6565
mod.Path = path
6666
}
6767

68-
out, err := gen.Generate(mod)
68+
out, err := gen.Generate(mod, bundle.Bundle.Env)
6969
if err != nil {
7070
return fmt.Errorf("failed to generate manifest: %w", err)
7171
}
@@ -75,13 +75,13 @@ func (c *TemplateCmd) Run(ctx run.RunContext) error {
7575
} else {
7676
if c.SetPath != nil {
7777
for name, path := range c.SetPath {
78-
mod, ok := bundle.Bundle[name]
78+
mod, ok := bundle.Bundle.Modules[name]
7979
if !ok {
8080
return fmt.Errorf("module %q not found", name)
8181
}
8282

8383
mod.Path = path
84-
bundle.Bundle[name] = mod
84+
bundle.Bundle.Modules[name] = mod
8585
}
8686
}
8787

foundry/api/blueprint.cue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ project: {
1818
merge: {}
1919
tag: {}
2020
}
21-
modules: {
22-
main: {
21+
bundle: {
22+
env: "shared-services"
23+
modules: main: {
2324
name: "app"
24-
version: "0.4.0"
25+
version: "0.4.3"
2526
values: {
2627
deployment: containers: main: {
2728
image: {

lib/project/blueprint/defaults/deployment.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func (d DeploymentModuleSetter) SetDefault(v cue.Value) (cue.Value, error) {
1313
projectName, _ := v.LookupPath(cue.ParsePath("project.name")).String()
1414
registry, _ := v.LookupPath(cue.ParsePath("global.deployment.registries.modules")).String()
1515

16-
modules := v.LookupPath(cue.ParsePath("project.deployment.modules"))
16+
modules := v.LookupPath(cue.ParsePath("project.deployment.bundle.modules"))
1717
if !modules.Exists() || modules.Err() != nil {
1818
return v, nil
1919
}
@@ -30,14 +30,14 @@ func (d DeploymentModuleSetter) SetDefault(v cue.Value) (cue.Value, error) {
3030
if projectName != "" {
3131
instance := module.LookupPath(cue.ParsePath("instance"))
3232
if !instance.Exists() {
33-
v = v.FillPath(cue.ParsePath(fmt.Sprintf("project.deployment.modules.%s.instance", moduleName)), projectName)
33+
v = v.FillPath(cue.ParsePath(fmt.Sprintf("project.deployment.bundle.modules.%s.instance", moduleName)), projectName)
3434
}
3535
}
3636

3737
if registry != "" {
3838
r := module.LookupPath(cue.ParsePath("registry"))
3939
if !r.Exists() {
40-
v = v.FillPath(cue.ParsePath(fmt.Sprintf("project.deployment.modules.%s.registry", moduleName)), registry)
40+
v = v.FillPath(cue.ParsePath(fmt.Sprintf("project.deployment.bundle.modules.%s.registry", moduleName)), registry)
4141
}
4242
}
4343
}

lib/project/deployment/deployer/deployer.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ type Deployer struct {
5252

5353
// DeployProject deploys the manifests for a project to the GitOps repository.
5454
func (d *Deployer) Deploy() error {
55+
if d.project.Blueprint.Project.Deployment.Bundle.Env == "prod" {
56+
return fmt.Errorf("cannot deploy to production environment")
57+
}
58+
5559
r, err := d.clone()
5660
if err != nil {
5761
return err
@@ -134,7 +138,8 @@ func (d *Deployer) Deploy() error {
134138
// buildProjectPath builds the path to the project in the GitOps repository.
135139
func (d *Deployer) buildProjectPath() string {
136140
globalDeploy := d.project.Blueprint.Global.Deployment
137-
return fmt.Sprintf(PATH, globalDeploy.Root, DEFAULT_ENV, d.project.Name)
141+
env := d.project.Blueprint.Project.Deployment.Bundle.Env
142+
return fmt.Sprintf(PATH, globalDeploy.Root, env, d.project.Name)
138143
}
139144

140145
// checkProjectPath checks if the project path exists and creates it if it does not.

lib/project/deployment/deployer/deployer_test.go

Lines changed: 64 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestDeployerDeploy(t *testing.T) {
3838
Blueprint: sb.Blueprint{
3939
Project: &sp.Project{
4040
Deployment: &sp.Deployment{
41-
Modules: bundle,
41+
Bundle: bundle,
4242
},
4343
},
4444
Global: &sg.Global{
@@ -85,51 +85,56 @@ func TestDeployerDeploy(t *testing.T) {
8585
project: newProject(
8686
"project",
8787
sp.ModuleBundle{
88-
"main": {
89-
Instance: "instance",
90-
Name: "module",
91-
Namespace: "default",
92-
Registry: "registry",
93-
Type: "kcl",
94-
Values: map[string]string{"key": "value"},
95-
Version: "v1.0.0",
88+
Env: "test",
89+
Modules: map[string]sp.Module{
90+
"main": {
91+
Instance: "instance",
92+
Name: "module",
93+
Namespace: "default",
94+
Registry: "registry",
95+
Type: "kcl",
96+
Values: map[string]string{"key": "value"},
97+
Version: "v1.0.0",
98+
},
9699
},
97100
},
98101
),
99102
files: map[string]string{
100-
mkPath("dev", "project", "env.mod.cue"): `main: values: { key1: "value1" }`,
103+
mkPath("test", "project", "env.mod.cue"): `main: values: { key1: "value1" }`,
101104
},
102105
dryrun: false,
103106
validate: func(t *testing.T, r testResult) {
104107
require.NoError(t, r.err)
105108

106-
e, err := afero.Exists(r.fs, mkPath("dev", "project", "main.yaml"))
109+
e, err := afero.Exists(r.fs, mkPath("test", "project", "main.yaml"))
107110
require.NoError(t, err)
108111
assert.True(t, e)
109112

110-
e, err = afero.Exists(r.fs, mkPath("dev", "project", "mod.cue"))
113+
e, err = afero.Exists(r.fs, mkPath("test", "project", "mod.cue"))
111114
require.NoError(t, err)
112115
assert.True(t, e)
113116

114-
c, err := afero.ReadFile(r.fs, mkPath("dev", "project", "main.yaml"))
117+
c, err := afero.ReadFile(r.fs, mkPath("test", "project", "main.yaml"))
115118
require.NoError(t, err)
116119
assert.Equal(t, "manifest", string(c))
117120

118121
mod := `{
119-
main: {
120-
env: ""
121-
instance: "instance"
122-
name: "module"
123-
namespace: "default"
124-
registry: "registry"
125-
type: "kcl"
126-
values: {
127-
key: "value"
122+
env: "test"
123+
modules: {
124+
main: {
125+
instance: "instance"
126+
name: "module"
127+
namespace: "default"
128+
registry: "registry"
129+
type: "kcl"
130+
values: {
131+
key: "value"
132+
}
133+
version: "v1.0.0"
128134
}
129-
version: "v1.0.0"
130135
}
131136
}`
132-
c, err = afero.ReadFile(r.fs, mkPath("dev", "project", "mod.cue"))
137+
c, err = afero.ReadFile(r.fs, mkPath("test", "project", "mod.cue"))
133138
require.NoError(t, err)
134139
assert.Equal(t, mod, string(c))
135140

@@ -153,7 +158,8 @@ func TestDeployerDeploy(t *testing.T) {
153158
project: newProject(
154159
"project",
155160
sp.ModuleBundle{
156-
"main": {
161+
Env: "test",
162+
Modules: map[string]sp.Module{"main": {
157163
Instance: "instance",
158164
Name: "module",
159165
Namespace: "default",
@@ -162,38 +168,39 @@ func TestDeployerDeploy(t *testing.T) {
162168
Values: map[string]string{"key": "value"},
163169
Version: "v1.0.0",
164170
},
171+
},
165172
},
166173
),
167174
files: map[string]string{
168-
mkPath("dev", "project", "extra.yaml"): "extra",
175+
mkPath("test", "project", "extra.yaml"): "extra",
169176
},
170177
dryrun: true,
171178
validate: func(t *testing.T, r testResult) {
172179
require.NoError(t, r.err)
173180

174-
e, err := afero.Exists(r.fs, mkPath("dev", "project", "main.yaml"))
181+
e, err := afero.Exists(r.fs, mkPath("test", "project", "main.yaml"))
175182
require.NoError(t, err)
176183
assert.True(t, e)
177184

178-
e, err = afero.Exists(r.fs, mkPath("dev", "project", "mod.cue"))
185+
e, err = afero.Exists(r.fs, mkPath("test", "project", "mod.cue"))
179186
require.NoError(t, err)
180187
assert.True(t, e)
181188

182-
e, err = afero.Exists(r.fs, mkPath("dev", "project", "extra.yaml"))
189+
e, err = afero.Exists(r.fs, mkPath("test", "project", "extra.yaml"))
183190
require.NoError(t, err)
184191
assert.False(t, e)
185192

186193
wt, err := r.repo.Worktree()
187194
require.NoError(t, err)
188195
st, err := wt.Status()
189196
require.NoError(t, err)
190-
fst := st.File("root/dev/project/extra.yaml")
197+
fst := st.File("root/test/project/extra.yaml")
191198
assert.Equal(t, fst.Staging, gg.Deleted)
192199

193-
fst = st.File("root/dev/project/main.yaml")
200+
fst = st.File("root/test/project/main.yaml")
194201
assert.Equal(t, fst.Staging, gg.Added)
195202

196-
fst = st.File("root/dev/project/mod.cue")
203+
fst = st.File("root/test/project/mod.cue")
197204
assert.Equal(t, fst.Staging, gg.Added)
198205

199206
head, err := r.repo.Head()
@@ -203,6 +210,30 @@ func TestDeployerDeploy(t *testing.T) {
203210
assert.Equal(t, "initial commit", cm.Message)
204211
},
205212
},
213+
{
214+
name: "deploy to production",
215+
project: newProject(
216+
"project",
217+
sp.ModuleBundle{
218+
Env: "prod",
219+
Modules: map[string]sp.Module{"main": {
220+
Instance: "instance",
221+
Name: "module",
222+
Namespace: "default",
223+
Registry: "registry",
224+
Type: "kcl",
225+
Values: map[string]string{"key": "value"},
226+
Version: "v1.0.0",
227+
},
228+
},
229+
},
230+
),
231+
files: map[string]string{},
232+
dryrun: true,
233+
validate: func(t *testing.T, r testResult) {
234+
assert.Error(t, r.err)
235+
},
236+
},
206237
}
207238

208239
for _, tt := range tests {
@@ -248,7 +279,7 @@ func TestDeployerDeploy(t *testing.T) {
248279
map[deployment.Provider]func(*slog.Logger) deployment.ManifestGenerator{
249280
deployment.ProviderKCL: func(logger *slog.Logger) deployment.ManifestGenerator {
250281
return &dm.ManifestGeneratorMock{
251-
GenerateFunc: func(mod sp.Module) ([]byte, error) {
282+
GenerateFunc: func(mod sp.Module, env string) ([]byte, error) {
252283
return []byte("manifest"), nil
253284
},
254285
}

lib/project/deployment/generator/generator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ func (d *Generator) GenerateBundle(b deployment.ModuleBundle, env cue.Value) (Ge
4040
}
4141

4242
results := make(map[string][]byte)
43-
for name, module := range nb.Bundle {
43+
for name, module := range nb.Bundle.Modules {
4444
d.logger.Debug("Generating module", "name", name)
45-
result, err := d.Generate(module)
45+
result, err := d.Generate(module, b.Bundle.Env)
4646
if err != nil {
4747
return GeneratorResult{}, fmt.Errorf("failed to generate module %s: %w", name, err)
4848
}
@@ -57,7 +57,7 @@ func (d *Generator) GenerateBundle(b deployment.ModuleBundle, env cue.Value) (Ge
5757
}
5858

5959
// Generate generates manifests for a deployment module.
60-
func (d *Generator) Generate(m sp.Module) ([]byte, error) {
60+
func (d *Generator) Generate(m sp.Module, env string) ([]byte, error) {
6161
if err := deployment.Validate(m); err != nil {
6262
return nil, fmt.Errorf("failed to validate module: %w", err)
6363
}
@@ -67,7 +67,7 @@ func (d *Generator) Generate(m sp.Module) ([]byte, error) {
6767
return nil, fmt.Errorf("failed to get generator for module: %w", err)
6868
}
6969

70-
manifests, err := mg.Generate(m)
70+
manifests, err := mg.Generate(m, env)
7171
if err != nil {
7272
return nil, fmt.Errorf("failed to generate manifest for module: %w", err)
7373
}

0 commit comments

Comments
 (0)