Skip to content

Commit 373948c

Browse files
Add katee apps to describe command
1 parent e46cf65 commit 373948c

File tree

10 files changed

+280
-6
lines changed

10 files changed

+280
-6
lines changed

cmd/cmds/describe.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,20 @@ type CF_App struct {
2020
ManifestPath string `yaml:"manifest_path,omitempty"`
2121
Filter string `yaml:"filter,omitempty"`
2222
}
23+
24+
type Katee_App struct {
25+
Name string `yaml:"name,omitempty"`
26+
Namespace string `yaml:"space,omitempty"`
27+
ManifestPath string `yaml:"manifest_path,omitempty"`
28+
Filter string `yaml:"filter,omitempty"`
29+
}
2330
type Output struct {
2431
Usage string `yaml:"usage,omitempty"`
2532
Team string `yaml:"team,omitempty"`
2633

27-
Pipeline Pipeline `yaml:"pipeline,omitempty"`
28-
CF_Apps []CF_App `yaml:"cf_apps,omitempty"`
34+
Pipeline Pipeline `yaml:"pipeline,omitempty"`
35+
CF_Apps []CF_App `yaml:"cf_apps,omitempty"`
36+
Katee_Apps []Katee_App `yaml:"katee_apps,omitempty"`
2937
}
3038

3139
func explainPipeline(resp halfpipe.Response) (o Output) {
@@ -52,6 +60,24 @@ func explainPipeline(resp halfpipe.Response) (o Output) {
5260
ManifestPath: t.Manifest,
5361
Filter: fmt.Sprintf(`.resources[] | select(.slug | test("^cf_.*_%s_%s$"))`, t.Space, t.CfApplication.Name),
5462
})
63+
case manifest.DeployKatee:
64+
app := Katee_App{
65+
Name: t.Name,
66+
Namespace: "",
67+
ManifestPath: t.VelaManifest,
68+
Filter: "",
69+
}
70+
71+
if t.Namespace != "" {
72+
app.Namespace = t.Namespace
73+
} else {
74+
app.Namespace = fmt.Sprintf("katee-%s", resp.Manifest.Team)
75+
}
76+
77+
// katee_v2_katee-monetise-live_subscriptions-schedule
78+
app.Filter = fmt.Sprintf(`.resources[] | select(.slug | test("^katee_v2_%s_%s$"))`, app.Namespace, t.KateeManifest.Metadata.Name)
79+
80+
o.Katee_Apps = append(o.Katee_Apps, app)
5581
}
5682
}
5783

cmd/cmds/helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func createDefaulter(projectData project.Data, renderer halfpipe.Renderer) defau
118118
func createController(projectData project.Data, fs afero.Afero, currentDir string, renderer halfpipe.Renderer) halfpipe.Controller {
119119
return halfpipe.NewController(
120120
createDefaulter(projectData, renderer),
121-
mapper.New(),
121+
mapper.New(fs),
122122
[]linters.Linter{
123123
linters.NewTopLevelLinter(),
124124
linters.NewTriggersLinter(fs, currentDir, project.BranchResolver, gitconfig.OriginURL),

controller_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func testController() controller {
3333
_ = fs.MkdirAll("/pwd/foo/.git", 0777)
3434
return controller{
3535
defaulter: defaults.New(defaults.Concourse, project.Data{}),
36-
mapper: mapper.New(),
36+
mapper: mapper.New(fs),
3737
renderer: fakeRenderer{},
3838
}
3939
}

manifest/deploy_katee.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type DeployKatee struct {
1818
CheckInterval int `json:"check_interval,omitempty" yaml:"check_interval,omitempty"`
1919
MaxChecks int `json:"max_checks,omitempty" yaml:"max_checks,omitempty"`
2020
GitHubEnvironment GitHubEnvironment `json:"github_environment,omitempty" yaml:"github_environment,omitempty"`
21+
KateeManifest VelaManifest `json:"-" yaml:"-"`
2122
}
2223

2324
func (d DeployKatee) ReadsFromArtifacts() bool {

manifest/secret_validator.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ func (s secretValidator) validate(i interface{}, fieldName string, secretTag str
182182
reflect.TypeOf(Update{}),
183183
reflect.TypeOf(Platform("")),
184184
reflect.TypeOf(ComposeFiles{}),
185-
reflect.TypeOf(GitHubEnvironment{}):
185+
reflect.TypeOf(GitHubEnvironment{}),
186+
reflect.TypeOf(VelaManifest{}):
186187
return
187188

188189
default:

manifest/vela_manifest.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package manifest
2+
3+
import (
4+
"gopkg.in/yaml.v3"
5+
)
6+
7+
type Metadata struct {
8+
Name string `yaml:"name"`
9+
Namespace string `yaml:"namespace"`
10+
}
11+
type VelaManifest struct {
12+
Kind string `yaml:"kind"`
13+
Metadata Metadata
14+
}
15+
16+
func UnmarshalVelaManifest(bytes []byte) (vm VelaManifest, err error) {
17+
err = yaml.Unmarshal(bytes, &vm)
18+
if err != nil {
19+
return vm, err
20+
}
21+
return vm, nil
22+
}

manifest/vela_manifest_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package manifest
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestUnmarshalVelaManifest(t *testing.T) {
10+
velaYaml := `apiVersion: core.oam.dev/v1beta1
11+
kind: Application
12+
metadata:
13+
name: my-app
14+
namespace: katee-my-team
15+
spec:
16+
components:
17+
- name: my-component
18+
type: snstateless
19+
properties:
20+
image: nginx:latest
21+
env:
22+
- name: FOO
23+
value: bar
24+
- name: SECRET
25+
value: ${MY_SECRET}
26+
`
27+
28+
vm, err := UnmarshalVelaManifest([]byte(velaYaml))
29+
30+
assert.NoError(t, err)
31+
assert.Equal(t, "Application", vm.Kind)
32+
assert.Equal(t, "my-app", vm.Metadata.Name)
33+
assert.Equal(t, "katee-my-team", vm.Metadata.Namespace)
34+
}
35+
36+
func TestUnmarshalVelaManifest_InvalidYAML(t *testing.T) {
37+
invalidYaml := `this is not: valid: yaml:`
38+
39+
_, err := UnmarshalVelaManifest([]byte(invalidYaml))
40+
41+
assert.Error(t, err)
42+
}

mapper/katee.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package mapper
2+
3+
import (
4+
"github.com/spf13/afero"
5+
"github.com/springernature/halfpipe/manifest"
6+
)
7+
8+
type katee struct {
9+
fs afero.Afero
10+
}
11+
12+
func (k katee) Apply(original manifest.Manifest) (updated manifest.Manifest, err error) {
13+
updated = original
14+
u, err := k.updateTasks(updated.Tasks)
15+
if err != nil {
16+
return
17+
}
18+
updated.Tasks = u
19+
return updated, nil
20+
}
21+
22+
func (k katee) updateTasks(tasks manifest.TaskList) (updated manifest.TaskList, err error) {
23+
for _, task := range tasks {
24+
switch task := task.(type) {
25+
case manifest.Parallel:
26+
u, e := k.updateTasks(task.Tasks)
27+
if e != nil {
28+
err = e
29+
return
30+
}
31+
task.Tasks = u
32+
updated = append(updated, task)
33+
case manifest.Sequence:
34+
u, e := k.updateTasks(task.Tasks)
35+
if e != nil {
36+
err = e
37+
return
38+
}
39+
task.Tasks = u
40+
updated = append(updated, task)
41+
case manifest.DeployKatee:
42+
mappedTask, e := k.mapKatee(task)
43+
if e != nil {
44+
err = e
45+
return
46+
}
47+
updated = append(updated, mappedTask)
48+
default:
49+
updated = append(updated, task)
50+
}
51+
}
52+
return updated, err
53+
}
54+
55+
func (k katee) mapKatee(task manifest.DeployKatee) (updated manifest.DeployKatee, err error) {
56+
updated = task
57+
58+
content, err := k.fs.ReadFile(task.VelaManifest)
59+
if err != nil {
60+
return
61+
}
62+
63+
velaManifest, err := manifest.UnmarshalVelaManifest(content)
64+
if err != nil {
65+
return
66+
}
67+
68+
updated.KateeManifest = velaManifest
69+
return
70+
}
71+
72+
func NewKateeMapper(fs afero.Afero) Mapper {
73+
return katee{fs: fs}
74+
}

mapper/katee_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package mapper
2+
3+
import (
4+
"testing"
5+
6+
"github.com/spf13/afero"
7+
"github.com/springernature/halfpipe/manifest"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestKateeMapper_ReturnsErrorWhenManifestCannotBeOpened(t *testing.T) {
12+
fs := afero.Afero{Fs: afero.NewMemMapFs()}
13+
mapper := NewKateeMapper(fs)
14+
15+
_, err := mapper.Apply(manifest.Manifest{Tasks: manifest.TaskList{
16+
manifest.DeployKatee{
17+
VelaManifest: "nonexistent.yaml",
18+
},
19+
}})
20+
21+
assert.Error(t, err)
22+
assert.Contains(t, err.Error(), "nonexistent.yaml")
23+
}
24+
25+
func TestKateeMapper_ParsesManifestAndPopulatesKateeManifest(t *testing.T) {
26+
fs := afero.Afero{Fs: afero.NewMemMapFs()}
27+
velaContent := `kind: Application
28+
metadata:
29+
name: "hello"
30+
namespace: "default"
31+
spec:
32+
components:
33+
- name: my-app
34+
type: snstateless
35+
properties:
36+
image: nginx:latest
37+
`
38+
fs.WriteFile("vela.yaml", []byte(velaContent), 0644)
39+
40+
mapper := NewKateeMapper(fs)
41+
updated, err := mapper.Apply(manifest.Manifest{Tasks: manifest.TaskList{
42+
manifest.DeployKatee{
43+
VelaManifest: "vela.yaml",
44+
},
45+
}})
46+
47+
assert.NoError(t, err)
48+
deployKatee := updated.Tasks[0].(manifest.DeployKatee)
49+
assert.Equal(t, "Application", deployKatee.KateeManifest.Kind)
50+
assert.Equal(t, "hello", deployKatee.KateeManifest.Metadata.Name)
51+
assert.Equal(t, "default", deployKatee.KateeManifest.Metadata.Namespace)
52+
53+
}
54+
55+
func TestKateeMapper_HandlesParallelAndSequenceTasks(t *testing.T) {
56+
fs := afero.Afero{Fs: afero.NewMemMapFs()}
57+
velaContent := `kind: Application
58+
spec:
59+
components:
60+
- name: nested-app
61+
type: worker
62+
`
63+
fs.WriteFile("vela.yaml", []byte(velaContent), 0644)
64+
65+
mapper := NewKateeMapper(fs)
66+
updated, err := mapper.Apply(manifest.Manifest{Tasks: manifest.TaskList{
67+
manifest.Parallel{
68+
Tasks: manifest.TaskList{
69+
manifest.DeployKatee{
70+
VelaManifest: "vela.yaml",
71+
},
72+
manifest.Sequence{
73+
Tasks: manifest.TaskList{
74+
manifest.DeployKatee{
75+
VelaManifest: "vela.yaml",
76+
},
77+
},
78+
},
79+
},
80+
},
81+
}})
82+
83+
assert.NoError(t, err)
84+
85+
parallel := updated.Tasks[0].(manifest.Parallel)
86+
deployKatee1 := parallel.Tasks[0].(manifest.DeployKatee)
87+
assert.Equal(t, "Application", deployKatee1.KateeManifest.Kind)
88+
89+
sequence := parallel.Tasks[1].(manifest.Sequence)
90+
deployKatee2 := sequence.Tasks[0].(manifest.DeployKatee)
91+
assert.Equal(t, "Application", deployKatee2.KateeManifest.Kind)
92+
}
93+
94+
func TestKateeMapper_ReturnsErrorForInvalidYAML(t *testing.T) {
95+
fs := afero.Afero{Fs: afero.NewMemMapFs()}
96+
fs.WriteFile("vela.yaml", []byte("invalid: yaml: content:"), 0644)
97+
98+
mapper := NewKateeMapper(fs)
99+
_, err := mapper.Apply(manifest.Manifest{Tasks: manifest.TaskList{
100+
manifest.DeployKatee{
101+
VelaManifest: "vela.yaml",
102+
},
103+
}})
104+
105+
assert.Error(t, err)
106+
}

mapper/mapper.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mapper
22

33
import (
4+
"github.com/spf13/afero"
45
"github.com/springernature/halfpipe/manifest"
56
)
67

@@ -25,12 +26,13 @@ func (m mapper) Apply(original manifest.Manifest) (updated manifest.Manifest, er
2526
return updated, nil
2627
}
2728

28-
func New() Mapper {
29+
func New(fs afero.Afero) Mapper {
2930
return mapper{
3031
mappers: []Mapper{
3132
NewUpdatePipelineMapper(),
3233
NewNotificationsMapper(),
3334
NewCfMapper(),
35+
NewKateeMapper(fs),
3436
NewGitTriggerMapper(),
3537
},
3638
}

0 commit comments

Comments
 (0)