Skip to content

Commit 068601d

Browse files
committed
pkg/generator: change main and handler generator for 0.0.2 milestone
1 parent a8451c4 commit 068601d

File tree

9 files changed

+186
-31
lines changed

9 files changed

+186
-31
lines changed

commands/operator-sdk/cmd/build.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func buildFunc(cmd *cobra.Command, args []string) {
8282
if err = yaml.Unmarshal(fp, c); err != nil {
8383
cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to unmarshal config file %v: (%v)", configYaml, err))
8484
}
85-
if err = generator.RenderDeployFiles(c, image); err != nil {
85+
if err = generator.RenderOperatorYaml(c, image); err != nil {
8686
cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to generate deploy/operator.yaml: (%v)", err))
8787
}
8888
}

pkg/generator/deploy_tmpl.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,9 @@ roleRef:
7676
name: {{.ProjectName}}
7777
apiGroup: rbac.authorization.k8s.io
7878
`
79+
80+
const crYamlTmpl = `apiVersion: "{{.APIVersion}}"
81+
kind: "{{.Kind}}"
82+
metadata:
83+
name: "example"
84+
`

pkg/generator/gen_deploy.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
const (
2525
operatorTmplName = "deploy/operator.yaml"
2626
rbacTmplName = "deploy/rbac.yaml"
27+
crTmplName = "deploy/cr.yaml"
2728
)
2829

2930
// OperatorYaml contains all the customized data needed to generate deploy/operator.yaml for a new operator
@@ -78,3 +79,24 @@ func renderRBACYaml(w io.Writer, projectName string) error {
7879
r := RBACYaml{ProjectName: projectName}
7980
return t.Execute(w, r)
8081
}
82+
83+
// CRYaml contains all the customized data needed to generate deploy/cr.yaml.
84+
type CRYaml struct {
85+
APIVersion string
86+
Kind string
87+
Name string
88+
}
89+
90+
func renderCustomResourceYaml(w io.Writer, apiVersion, kind string) error {
91+
t := template.New(crTmplName)
92+
t, err := t.Parse(crYamlTmpl)
93+
if err != nil {
94+
return fmt.Errorf("failed to parse cr yaml template: %v", err)
95+
}
96+
97+
r := CRYaml{
98+
APIVersion: apiVersion,
99+
Kind: kind,
100+
}
101+
return t.Execute(w, r)
102+
}

pkg/generator/gen_handler.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,15 @@ import (
2424
type Handler struct {
2525
// imports
2626
OperatorSDKImport string
27+
28+
RepoPath string
29+
Kind string
30+
APIDirName string
31+
Version string
2732
}
2833

2934
// renderHandlerFile generates the stub/handler.go file.
30-
func renderHandlerFile(w io.Writer) error {
35+
func renderHandlerFile(w io.Writer, repoPath, kind, apiDirName, version string) error {
3136
t := template.New("stub/handler.go")
3237
t, err := t.Parse(handlerTmpl)
3338
if err != nil {
@@ -36,6 +41,10 @@ func renderHandlerFile(w io.Writer) error {
3641

3742
h := Handler{
3843
OperatorSDKImport: sdkImport,
44+
RepoPath: repoPath,
45+
Kind: kind,
46+
APIDirName: apiDirName,
47+
Version: version,
3948
}
4049
return t.Execute(w, h)
4150
}

pkg/generator/gen_main.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@ type Main struct {
3333
OperatorSDKImport string
3434
StubImport string
3535
SDKVersionImport string
36+
37+
APIVersion string
38+
Kind string
3639
}
3740

38-
// renderMainFile generates the cmd/<projectName>/main.go file given a repo path ("github.com/coreos/play")
39-
func renderMainFile(w io.Writer, repo string) error {
41+
// renderMainFile generates the cmd/<projectName>/main.go file.
42+
func renderMainFile(w io.Writer, repo, apiVersion, kind string) error {
4043
t := template.New("cmd/<projectName>/main.go")
4144
t, err := t.Parse(mainTmpl)
4245
if err != nil {
@@ -47,6 +50,8 @@ func renderMainFile(w io.Writer, repo string) error {
4750
OperatorSDKImport: sdkImport,
4851
StubImport: filepath.Join(repo, stubDir),
4952
SDKVersionImport: versionImport,
53+
APIVersion: apiVersion,
54+
Kind: kind,
5055
}
5156
return t.Execute(w, m)
5257
}

pkg/generator/generator.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const (
5454
config = "config.yaml"
5555
operatorYaml = deployDir + "/operator.yaml"
5656
rbacYaml = "rbac.yaml"
57+
crYaml = "cr.yaml"
5758
)
5859

5960
type Generator struct {
@@ -127,12 +128,12 @@ func (g *Generator) renderCmd() error {
127128
if err := os.MkdirAll(cpDir, defaultDirFileMode); err != nil {
128129
return err
129130
}
130-
return renderCmdFiles(cpDir, g.repoPath)
131+
return renderCmdFiles(cpDir, g.repoPath, g.apiVersion, g.kind)
131132
}
132133

133-
func renderCmdFiles(cmdProjectDir, repoPath string) error {
134+
func renderCmdFiles(cmdProjectDir, repoPath, apiVersion, kind string) error {
134135
buf := &bytes.Buffer{}
135-
if err := renderMainFile(buf, repoPath); err != nil {
136+
if err := renderMainFile(buf, repoPath, apiVersion, kind); err != nil {
136137
return err
137138
}
138139
return writeFileAndPrint(filepath.Join(cmdProjectDir, main), buf.Bytes(), defaultFileMode)
@@ -159,7 +160,7 @@ func (g *Generator) renderDeploy() error {
159160
if err := os.MkdirAll(dp, defaultDirFileMode); err != nil {
160161
return err
161162
}
162-
return renderRBAC(dp, g.projectName)
163+
return renderDeployFiles(dp, g.projectName, g.apiVersion, g.kind)
163164
}
164165

165166
func renderRBAC(deployDir, projectName string) error {
@@ -170,9 +171,24 @@ func renderRBAC(deployDir, projectName string) error {
170171
return writeFileAndPrint(filepath.Join(deployDir, rbacYaml), buf.Bytes(), defaultFileMode)
171172
}
172173

173-
// RenderDeployFiles generates "deploy/operator.yaml"
174-
// TODO: rethink about when/what to generate when invoking build command.
175-
func RenderDeployFiles(c *Config, image string) error {
174+
func renderDeployFiles(deployDir, projectName, apiVersion, kind string) error {
175+
buf := &bytes.Buffer{}
176+
if err := renderRBACYaml(buf, projectName); err != nil {
177+
return err
178+
}
179+
if err := writeFileAndPrint(filepath.Join(deployDir, rbacYaml), buf.Bytes(), defaultFileMode); err != nil {
180+
return err
181+
}
182+
183+
buf = &bytes.Buffer{}
184+
if err := renderCustomResourceYaml(buf, apiVersion, kind); err != nil {
185+
return err
186+
}
187+
return writeFileAndPrint(filepath.Join(deployDir, crYaml), buf.Bytes(), defaultFileMode)
188+
}
189+
190+
// RenderOperatorYaml generates "deploy/operator.yaml"
191+
func RenderOperatorYaml(c *Config, image string) error {
176192
buf := &bytes.Buffer{}
177193
if err := renderOperatorYaml(buf, c.Kind, c.APIVersion, c.ProjectName, image); err != nil {
178194
return err
@@ -238,7 +254,8 @@ func renderCodegenFiles(codegenDir, repoPath, apiDirName, version, projectName s
238254

239255
func (g *Generator) renderPkg() error {
240256
v := version(g.apiVersion)
241-
apiDir := filepath.Join(g.projectName, apisDir, apiDirName(g.apiVersion), v)
257+
adn := apiDirName(g.apiVersion)
258+
apiDir := filepath.Join(g.projectName, apisDir, adn, v)
242259
if err := os.MkdirAll(apiDir, defaultDirFileMode); err != nil {
243260
return err
244261
}
@@ -250,7 +267,7 @@ func (g *Generator) renderPkg() error {
250267
if err := os.MkdirAll(sDir, defaultDirFileMode); err != nil {
251268
return err
252269
}
253-
return renderStubFiles(sDir)
270+
return renderStubFiles(sDir, g.repoPath, g.kind, adn, v)
254271
}
255272

256273
func renderAPIFiles(apiDir, groupName, version, kind string) error {
@@ -277,9 +294,9 @@ func renderAPIFiles(apiDir, groupName, version, kind string) error {
277294
return writeFileAndPrint(filepath.Join(apiDir, types), buf.Bytes(), defaultFileMode)
278295
}
279296

280-
func renderStubFiles(stubDir string) error {
297+
func renderStubFiles(stubDir, repoPath, kind, apiDirName, version string) error {
281298
buf := &bytes.Buffer{}
282-
if err := renderHandlerFile(buf); err != nil {
299+
if err := renderHandlerFile(buf, repoPath, kind, apiDirName, version); err != nil {
283300
return err
284301
}
285302
return writeFileAndPrint(filepath.Join(stubDir, handler), buf.Bytes(), defaultFileMode)

pkg/generator/generator_test.go

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,25 @@ import (
1919
"testing"
2020
)
2121

22+
const (
23+
// test constants for app-operator
24+
appRepoPath = "github.com/example-inc/app-operator"
25+
appKind = "App"
26+
appApiDirName = "app"
27+
appAPIVersion = appGroupName + "/" + appVersion
28+
appVersion = "v1alpha1"
29+
appGroupName = "app.example.com"
30+
)
31+
2232
const mainExp = `package main
2333
2434
import (
2535
"context"
2636
"runtime"
2737
28-
stub "github.com/coreos/play/pkg/stub"
38+
stub "github.com/example-inc/app-operator/pkg/stub"
2939
sdk "github.com/coreos/operator-sdk/pkg/sdk"
30-
sdkVersion "github.com/coreos/operator-sdk/version"
40+
sdkVersion "github.com/coreos/operator-sdk/version"
3141
3242
"github.com/sirupsen/logrus"
3343
)
@@ -40,15 +50,15 @@ func printVersion() {
4050
4151
func main() {
4252
printVersion()
43-
sdk.Watch("apps/v1", "Deployment", "default")
53+
sdk.Watch("app.example.com/v1alpha1", "App", "default")
4454
sdk.Handle(stub.NewHandler())
45-
sdk.Run(context.TODO())
55+
sdk.Run(context.TODO())
4656
}
4757
`
4858

4959
func TestGenMain(t *testing.T) {
5060
buf := &bytes.Buffer{}
51-
if err := renderMainFile(buf, "github.com/coreos/play"); err != nil {
61+
if err := renderMainFile(buf, appRepoPath, appAPIVersion, appKind); err != nil {
5262
t.Error(err)
5363
return
5464
}
@@ -61,10 +71,16 @@ func TestGenMain(t *testing.T) {
6171
const handlerExp = `package stub
6272
6373
import (
74+
"github.com/example-inc/app-operator/pkg/apis/app/v1alpha1"
75+
76+
"github.com/coreos/operator-sdk/pkg/sdk/action"
6477
"github.com/coreos/operator-sdk/pkg/sdk/handler"
6578
"github.com/coreos/operator-sdk/pkg/sdk/types"
6679
"github.com/sirupsen/logrus"
67-
apps_v1 "k8s.io/api/apps/v1"
80+
"k8s.io/api/core/v1"
81+
"k8s.io/apimachinery/pkg/api/errors"
82+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
83+
"k8s.io/apimachinery/pkg/runtime/schema"
6884
)
6985
7086
func NewHandler() handler.Handler {
@@ -76,18 +92,55 @@ type Handler struct {
7692
}
7793
7894
func (h *Handler) Handle(ctx types.Context, event types.Event) error {
79-
// Change me
8095
switch o := event.Object.(type) {
81-
case *apps_v1.Deployment:
82-
logrus.Printf("Received Deployment: %v", o.Name)
96+
case *v1alpha1.App:
97+
err := action.Create(newbusyBoxPod(o))
98+
if err != nil && !errors.IsAlreadyExists(err) {
99+
logrus.Errorf("Failed to create busybox pod : %v", err)
100+
return err
101+
}
83102
}
84103
return nil
85104
}
105+
106+
// newbusyBoxPod demonstrates how to create a busybox pod
107+
func newbusyBoxPod(cr *v1alpha1.App) *v1.Pod {
108+
labels := map[string]string{
109+
"app": "busy-box",
110+
}
111+
return &v1.Pod{
112+
TypeMeta: metav1.TypeMeta{
113+
Kind: "Pod",
114+
APIVersion: "v1",
115+
},
116+
ObjectMeta: metav1.ObjectMeta{
117+
Name: "busy-box",
118+
Namespace: "default",
119+
OwnerReferences: []metav1.OwnerReference{
120+
*metav1.NewControllerRef(cr, schema.GroupVersionKind{
121+
Group: v1alpha1.SchemeGroupVersion.Group,
122+
Version: v1alpha1.SchemeGroupVersion.Version,
123+
Kind: "App",
124+
}),
125+
},
126+
Labels: labels,
127+
},
128+
Spec: v1.PodSpec{
129+
Containers: []v1.Container{
130+
{
131+
Name: "busybox",
132+
Image: "busybox",
133+
Command: []string{"sleep", "3600"},
134+
},
135+
},
136+
},
137+
}
138+
}
86139
`
87140

88141
func TestGenHandler(t *testing.T) {
89142
buf := &bytes.Buffer{}
90-
if err := renderHandlerFile(buf); err != nil {
143+
if err := renderHandlerFile(buf, appRepoPath, appKind, appApiDirName, appVersion); err != nil {
91144
t.Error(err)
92145
return
93146
}

pkg/generator/handler_tmpl.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,16 @@ package generator
1818
const handlerTmpl = `package stub
1919
2020
import (
21+
"{{.RepoPath}}/pkg/apis/{{.APIDirName}}/{{.Version}}"
22+
23+
"{{.OperatorSDKImport}}/action"
2124
"{{.OperatorSDKImport}}/handler"
2225
"{{.OperatorSDKImport}}/types"
2326
"github.com/sirupsen/logrus"
24-
apps_v1 "k8s.io/api/apps/v1"
27+
"k8s.io/api/core/v1"
28+
"k8s.io/apimachinery/pkg/api/errors"
29+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30+
"k8s.io/apimachinery/pkg/runtime/schema"
2531
)
2632
2733
func NewHandler() handler.Handler {
@@ -33,11 +39,48 @@ type Handler struct {
3339
}
3440
3541
func (h *Handler) Handle(ctx types.Context, event types.Event) error {
36-
// Change me
3742
switch o := event.Object.(type) {
38-
case *apps_v1.Deployment:
39-
logrus.Printf("Received Deployment: %v", o.Name)
43+
case *{{.Version}}.{{.Kind}}:
44+
err := action.Create(newbusyBoxPod(o))
45+
if err != nil && !errors.IsAlreadyExists(err) {
46+
logrus.Errorf("Failed to create busybox pod : %v", err)
47+
return err
48+
}
4049
}
4150
return nil
4251
}
52+
53+
// newbusyBoxPod demonstrates how to create a busybox pod
54+
func newbusyBoxPod(cr *{{.Version}}.{{.Kind}}) *v1.Pod {
55+
labels := map[string]string{
56+
"app": "busy-box",
57+
}
58+
return &v1.Pod{
59+
TypeMeta: metav1.TypeMeta{
60+
Kind: "Pod",
61+
APIVersion: "v1",
62+
},
63+
ObjectMeta: metav1.ObjectMeta{
64+
Name: "busy-box",
65+
Namespace: "default",
66+
OwnerReferences: []metav1.OwnerReference{
67+
*metav1.NewControllerRef(cr, schema.GroupVersionKind{
68+
Group: {{.Version}}.SchemeGroupVersion.Group,
69+
Version: {{.Version}}.SchemeGroupVersion.Version,
70+
Kind: "{{.Kind}}",
71+
}),
72+
},
73+
Labels: labels,
74+
},
75+
Spec: v1.PodSpec{
76+
Containers: []v1.Container{
77+
{
78+
Name: "busybox",
79+
Image: "busybox",
80+
Command: []string{"sleep", "3600"},
81+
},
82+
},
83+
},
84+
}
85+
}
4386
`

0 commit comments

Comments
 (0)