Skip to content

Commit 46d6ff5

Browse files
authored
Create the model and controller (#11)
* Add support for generating the api model, spec and status * add missing fabric8 kube clients * Remove some of the debug logging * Add support for basic controller
1 parent 1a4288c commit 46d6ff5

File tree

10 files changed

+326
-37
lines changed

10 files changed

+326
-37
lines changed

pkg/java/v1/api.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ type createAPISubcommand struct {
4141
}
4242

4343
func (opts createAPIOptions) UpdateResource(res *resource.Resource) {
44+
fmt.Println("UpdateResource called")
45+
4446
res.API = &resource.API{
4547
CRDVersion: opts.CRDVersion,
4648
Namespaced: true,
@@ -56,26 +58,33 @@ var (
5658
)
5759

5860
func (p *createAPISubcommand) BindFlags(fs *pflag.FlagSet) {
61+
fs.SortFlags = false
62+
fs.StringVar(&p.options.CRDVersion, "crd-version", "v1", "crd version to generate")
5963
}
6064

61-
func (p *createAPISubcommand) InjectConfig(c config.Config) {
65+
func (p *createAPISubcommand) InjectConfig(c config.Config) error {
6266
p.config = c
67+
68+
return nil
6369
}
6470

6571
func (p *createAPISubcommand) Run(fs machinery.Filesystem) error {
66-
fmt.Println("create called")
72+
fmt.Println("Run called")
6773
return nil
6874
}
6975

7076
func (p *createAPISubcommand) Validate() error {
77+
fmt.Println("Validate called")
7178
return nil
7279
}
7380

7481
func (p *createAPISubcommand) PostScaffold() error {
82+
fmt.Println("PostScaffold called")
7583
return nil
7684
}
7785

7886
func (p *createAPISubcommand) Scaffold(fs machinery.Filesystem) error {
87+
fmt.Println("Scaffold called")
7988
scaffolder := scaffolds.NewCreateAPIScaffolder(p.config, *p.resource)
8089
scaffolder.InjectFS(fs)
8190
if err := scaffolder.Scaffold(); err != nil {
@@ -86,8 +95,10 @@ func (p *createAPISubcommand) Scaffold(fs machinery.Filesystem) error {
8695
}
8796

8897
func (p *createAPISubcommand) InjectResource(res *resource.Resource) error {
98+
fmt.Println("InjectResource called")
8999
p.resource = res
90100

101+
// RESOURCE: &{{cache zeusville.com v1 Joke} jokes 0xc00082a640 false 0xc00082a680}
91102
p.options.UpdateResource(p.resource)
92103

93104
if err := p.resource.Validate(); err != nil {

pkg/java/v1/scaffolds/api.go

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@ package scaffolds
22

33
import (
44
"fmt"
5+
56
"sigs.k8s.io/kubebuilder/v3/pkg/config"
7+
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
68
"sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
79
"sigs.k8s.io/kubebuilder/v3/pkg/plugins"
810

9-
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
11+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/java/v1/scaffolds/internal/templates/controller"
12+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/java/v1/scaffolds/internal/templates/model"
13+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/java/v1/util"
1014
)
1115

1216
type apiScaffolder struct {
@@ -18,17 +22,55 @@ type apiScaffolder struct {
1822

1923
// NewCreateAPIScaffolder returns a new plugins.Scaffolder for project initialization operations
2024
func NewCreateAPIScaffolder(cfg config.Config, res resource.Resource) plugins.Scaffolder {
25+
fmt.Println("NewCreateAPIScaffolder called")
2126
return &apiScaffolder{
2227
config: cfg,
2328
resource: res,
2429
}
2530
}
2631

2732
func (s *apiScaffolder) InjectFS(fs machinery.Filesystem) {
33+
fmt.Println("InjectFS called")
2834
s.fs = fs
2935
}
3036

3137
func (s *apiScaffolder) Scaffold() error {
3238
fmt.Println("api.Scaffold()")
33-
return nil
39+
40+
if err := s.config.UpdateResource(s.resource); err != nil {
41+
return err
42+
}
43+
44+
// Initialize the machinery.Scaffold that will write the files to disk
45+
scaffold := machinery.NewScaffold(s.fs,
46+
// NOTE: kubebuilder's default permissions are only for root users
47+
machinery.WithDirectoryPermissions(0755),
48+
machinery.WithFilePermissions(0644),
49+
machinery.WithConfig(s.config),
50+
machinery.WithResource(&s.resource),
51+
)
52+
53+
var createAPITemplates []machinery.Builder
54+
createAPITemplates = append(createAPITemplates,
55+
&model.Model{
56+
Package: util.ReverseDomain(s.config.GetDomain()),
57+
ClassName: util.ToClassname(s.resource.Kind),
58+
Version: s.resource.Version,
59+
Group: s.resource.Group,
60+
},
61+
&model.ModelSpec{
62+
Package: util.ReverseDomain(s.config.GetDomain()),
63+
ClassName: util.ToClassname(s.resource.Kind),
64+
},
65+
&model.ModelStatus{
66+
Package: util.ReverseDomain(s.config.GetDomain()),
67+
ClassName: util.ToClassname(s.resource.Kind),
68+
},
69+
&controller.Controller{
70+
Package: util.ReverseDomain(s.config.GetDomain()),
71+
ClassName: util.ToClassname(s.resource.Kind),
72+
},
73+
)
74+
75+
return scaffold.Execute(createAPITemplates...)
3476
}

pkg/java/v1/scaffolds/internal/templates/applicationproperties.go

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package templates
22

33
import (
44
"fmt"
5-
"path/filepath"
6-
"strings"
75

86
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
7+
8+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/java/v1/scaffolds/internal/templates/util"
99
)
1010

1111
var _ machinery.Template = &ApplicationPropertiesFile{}
@@ -16,26 +16,13 @@ type ApplicationPropertiesFile struct {
1616
ProjectName string
1717
}
1818

19-
const (
20-
FilePathSeparator = string(filepath.Separator)
21-
javaPaths = "src" + FilePathSeparator + "main" + FilePathSeparator + "resources"
22-
)
23-
24-
func prependJavaPathResources(filename string) string {
25-
return javaPaths + FilePathSeparator + filename
26-
}
27-
28-
func asResourcesPath(s string) string {
29-
return strings.ReplaceAll(s, ".", FilePathSeparator)
30-
}
31-
3219
func (f *ApplicationPropertiesFile) SetTemplateDefaults() error {
3320
if f.ProjectName == "" {
3421
return fmt.Errorf("invalid Application Properties name")
3522
}
3623

3724
if f.Path == "" {
38-
f.Path = prependJavaPathResources("application.properties")
25+
f.Path = util.PrependResourcePath("application.properties")
3926
}
4027

4128
f.TemplateBody = ApplicationPropertiesTemplate
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package controller
2+
3+
import (
4+
"fmt"
5+
6+
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
7+
8+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/java/v1/scaffolds/internal/templates/util"
9+
)
10+
11+
var _ machinery.Template = &Controller{}
12+
13+
type Controller struct {
14+
machinery.TemplateMixin
15+
16+
// Package is the source files package
17+
Package string
18+
19+
// Name of the operator used for the main file.
20+
ClassName string
21+
}
22+
23+
func (f *Controller) SetTemplateDefaults() error {
24+
if f.ClassName == "" {
25+
return fmt.Errorf("invalid model name")
26+
}
27+
28+
if f.Path == "" {
29+
f.Path = util.PrependJavaPath(f.ClassName+"Controller.java", util.AsPath(f.Package))
30+
}
31+
32+
f.TemplateBody = controllerTemplate
33+
34+
return nil
35+
}
36+
37+
// TODO: pass in the name of the operator i.e. replace Memcached
38+
const controllerTemplate = `package {{ .Package }};
39+
40+
import io.fabric8.kubernetes.api.model.*;
41+
import io.fabric8.kubernetes.api.model.apps.Deployment;
42+
import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
43+
import io.fabric8.kubernetes.api.model.apps.DeploymentSpecBuilder;
44+
import io.fabric8.kubernetes.client.KubernetesClient;
45+
import io.javaoperatorsdk.operator.api.*;
46+
import io.javaoperatorsdk.operator.api.Context;
47+
import io.javaoperatorsdk.operator.processing.event.EventSourceManager;
48+
import java.util.HashMap;
49+
import java.util.List;
50+
import java.util.Map;
51+
import java.util.stream.Collectors;
52+
import org.apache.commons.collections.CollectionUtils;
53+
54+
@Controller
55+
public class {{ .ClassName }}Controller implements ResourceController<{{ .ClassName }}> {
56+
57+
private final KubernetesClient client;
58+
59+
public {{ .ClassName }}Controller(KubernetesClient client) {
60+
this.client = client;
61+
}
62+
63+
// TODO Fill in the rest of the controller
64+
65+
@Override
66+
public void init(EventSourceManager eventSourceManager) {
67+
// TODO: fill in init
68+
}
69+
70+
@Override
71+
public UpdateControl<{{ .ClassName }}> createOrUpdateResource(
72+
{{ .ClassName }} resource, Context<{{ .ClassName }}> context) {
73+
// TODO: fill in logic
74+
75+
return UpdateControl.noUpdate();
76+
}
77+
78+
@Override
79+
public DeleteControl deleteResource({{ .ClassName }} resource, Context<{{ .ClassName }}> context) {
80+
// nothing to do here...
81+
// framework takes care of deleting the resource object
82+
// k8s takes care of deleting deployment and pods because of ownerreference set
83+
return DeleteControl.DEFAULT_DELETE;
84+
}
85+
}
86+
87+
`
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package model
2+
3+
import (
4+
"fmt"
5+
6+
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
7+
8+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/java/v1/scaffolds/internal/templates/util"
9+
)
10+
11+
var _ machinery.Template = &Model{}
12+
13+
type Model struct {
14+
machinery.TemplateMixin
15+
16+
// Package is the source files package
17+
Package string
18+
19+
// Name of the operator used for the main file.
20+
ClassName string
21+
22+
Version string
23+
Group string
24+
}
25+
26+
func (f *Model) SetTemplateDefaults() error {
27+
if f.ClassName == "" {
28+
return fmt.Errorf("invalid model name")
29+
}
30+
31+
if f.Path == "" {
32+
f.Path = util.PrependJavaPath(f.ClassName+".java", util.AsPath(f.Package))
33+
}
34+
35+
f.TemplateBody = modelTemplate
36+
37+
return nil
38+
}
39+
40+
// TODO: pass in the name of the operator i.e. replace Memcached
41+
const modelTemplate = `package {{ .Package }};
42+
43+
import io.fabric8.kubernetes.api.model.Namespaced;
44+
import io.fabric8.kubernetes.client.CustomResource;
45+
import io.fabric8.kubernetes.model.annotation.Group;
46+
import io.fabric8.kubernetes.model.annotation.Version;
47+
48+
@Version("{{ .Version }}")
49+
@Group("{{ .Group }}")
50+
public class {{ .ClassName }} extends CustomResource<{{ .ClassName }}Spec, {{ .ClassName }}Status>
51+
implements Namespaced {}
52+
53+
`
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package model
2+
3+
import (
4+
"fmt"
5+
6+
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
7+
8+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/java/v1/scaffolds/internal/templates/util"
9+
)
10+
11+
var _ machinery.Template = &ModelSpec{}
12+
13+
type ModelSpec struct {
14+
machinery.TemplateMixin
15+
16+
// Package is the source files package
17+
Package string
18+
19+
// Name of the operator used for the main file.
20+
ClassName string
21+
}
22+
23+
func (f *ModelSpec) SetTemplateDefaults() error {
24+
if f.ClassName == "" {
25+
return fmt.Errorf("invalid operator name")
26+
}
27+
28+
if f.Path == "" {
29+
f.Path = util.PrependJavaPath(f.ClassName+"Spec.java", util.AsPath(f.Package))
30+
}
31+
32+
f.TemplateBody = modelSpecTemplate
33+
34+
return nil
35+
}
36+
37+
// TODO: pass in the name of the operator i.e. replace Memcached
38+
const modelSpecTemplate = `package {{ .Package }};
39+
40+
public class {{ .ClassName }}Spec {
41+
42+
// Add Spec information here
43+
}
44+
`

0 commit comments

Comments
 (0)