Skip to content

Commit 9e37ab1

Browse files
committed
Merge remote-tracking branch 'kb-plugin/main'
2 parents b58b402 + 760ef0c commit 9e37ab1

25 files changed

+1959
-1
lines changed

.gitignore

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Binaries for programs and plugins
2+
*.exe
3+
*.exe~
4+
*.dll
5+
*.so
6+
*.dylib
7+
8+
# Test binary, built with `go test -c`
9+
*.test
10+
11+
# Output of the go coverage tool, specifically when used with LiteIDE
12+
*.out
13+
14+
# Dependency directories (remove the comment below to include it)
15+
# vendor/

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,4 @@
198198
distributed under the License is distributed on an "AS IS" BASIS,
199199
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200200
See the License for the specific language governing permissions and
201-
limitations under the License.
201+
limitations under the License.

Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
lint:
2+
@go fmt ./...
3+
4+
test:
5+
@ginkgo ./...
6+
7+
.PHONY: test lint

README.md

+78
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,81 @@ Operator SDK is under Apache 2.0 license. See the [LICENSE][license_file] file f
2424
[of-home]: https://github.com/operator-framework
2525
[of-blog]: https://coreos.com/blog/introducing-operator-framework
2626
[operator-link]: https://coreos.com/operators/
27+
28+
# Enable kubebuilder-plugin for operator-sdk
29+
30+
31+
To use kubebuilder-plugin for java operators we need to clone the operator-sdk repo.
32+
33+
### Updates in Operator-SDK go.mod
34+
35+
- Add the kubebuilder plugin to `go.mod`
36+
37+
```
38+
github.com/java-operator-sdk/kubebuilder-plugin v0.0.0-20210225171707-e42ea87455e3
39+
```
40+
41+
- Replace the kubebuilder-plugin path in go-mod pointing to the local dir of your kube-builder repo. Example.
42+
43+
```
44+
github.com/java-operator-sdk/kubebuilder-plugin => /Users/sushah/go/src/github.com/sujil02/kubebuilder-plugin
45+
```
46+
47+
### Updates in Operator-SDK `internal/cmd/operator-sdk/cli/cli.go`
48+
49+
- Add the java-operator-sdk import
50+
51+
```
52+
javav1 "github.com/java-operator-sdk/kubebuilder-plugin/pkg/quarkus/v1"
53+
```
54+
55+
- Introduce the java bundle in `GetPluginsCLIAndRoot()` method.
56+
```
57+
javaBundle, _ := plugin.NewBundle("quarkus"+plugins.DefaultNameQualifier, plugin.Version{Number: 1},
58+
&javav1.Plugin{},
59+
)
60+
```
61+
62+
- Add the created javaBundle to the `cli.New`
63+
64+
```
65+
cli.WithPlugins(
66+
ansibleBundle,
67+
gov2Bundle,
68+
gov3Bundle,
69+
helmBundle,
70+
javaBundle,
71+
),
72+
```
73+
74+
75+
### Build and Install the Operator-SDK
76+
```
77+
go mod tidy
78+
make install
79+
```
80+
81+
Now that the plugin is integrated with the `operator-sdk` you can run the `init` command to generate the sample java operator
82+
83+
- Use the quarkus plugin flag
84+
- Pick the domain and project name as prefered.
85+
86+
```
87+
operator-sdk init --plugins quarkus --domain xyz.com --project-name java-op
88+
```
89+
90+
Once the operator is scaffolded check for the following files
91+
92+
```
93+
├── PROJECT
94+
├── pom.xml
95+
└── src
96+
└── main
97+
├── java
98+
│   └── com
99+
│   └── xyz
100+
│   └── JavaOpOperator.java
101+
└── resources
102+
└── application.properties
103+
104+
```

go.mod

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module github.com/java-operator-sdk/kubebuilder-plugin
2+
3+
go 1.15
4+
5+
require github.com/spf13/pflag v1.0.5
6+
7+
require (
8+
github.com/onsi/ginkgo v1.15.2
9+
github.com/onsi/gomega v1.11.0
10+
k8s.io/apimachinery v0.20.2
11+
sigs.k8s.io/kubebuilder/v3 v3.0.0-beta.1
12+
)

go.sum

+714
Large diffs are not rendered by default.

pkg/quarkus/v1/api.go

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright 2021 The Java Operator SDK Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package v1
18+
19+
import (
20+
"errors"
21+
"fmt"
22+
23+
"github.com/spf13/pflag"
24+
"sigs.k8s.io/kubebuilder/v3/pkg/config"
25+
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
26+
"sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
27+
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
28+
pluginutil "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util"
29+
30+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/quarkus/v1/scaffolds"
31+
)
32+
33+
type createAPIOptions struct {
34+
CRDVersion string
35+
}
36+
37+
type createAPISubcommand struct {
38+
config config.Config
39+
resource *resource.Resource
40+
options createAPIOptions
41+
}
42+
43+
func (opts createAPIOptions) UpdateResource(res *resource.Resource) {
44+
fmt.Println("UpdateResource called")
45+
46+
res.API = &resource.API{
47+
CRDVersion: opts.CRDVersion,
48+
Namespaced: true,
49+
}
50+
51+
// Ensure that Path is empty and Controller false as this is not a Go project
52+
res.Path = ""
53+
res.Controller = false
54+
}
55+
56+
var (
57+
_ plugin.CreateAPISubcommand = &createAPISubcommand{}
58+
)
59+
60+
func (p *createAPISubcommand) BindFlags(fs *pflag.FlagSet) {
61+
fs.SortFlags = false
62+
fs.StringVar(&p.options.CRDVersion, "crd-version", "v1", "crd version to generate")
63+
}
64+
65+
func (p *createAPISubcommand) InjectConfig(c config.Config) error {
66+
p.config = c
67+
68+
return nil
69+
}
70+
71+
func (p *createAPISubcommand) Run(fs machinery.Filesystem) error {
72+
fmt.Println("Run called")
73+
return nil
74+
}
75+
76+
func (p *createAPISubcommand) Validate() error {
77+
fmt.Println("Validate called")
78+
return nil
79+
}
80+
81+
func (p *createAPISubcommand) PostScaffold() error {
82+
fmt.Println("PostScaffold called")
83+
return nil
84+
}
85+
86+
func (p *createAPISubcommand) Scaffold(fs machinery.Filesystem) error {
87+
fmt.Println("Scaffold called")
88+
scaffolder := scaffolds.NewCreateAPIScaffolder(p.config, *p.resource)
89+
scaffolder.InjectFS(fs)
90+
if err := scaffolder.Scaffold(); err != nil {
91+
return err
92+
}
93+
94+
return nil
95+
}
96+
97+
func (p *createAPISubcommand) InjectResource(res *resource.Resource) error {
98+
fmt.Println("InjectResource called")
99+
p.resource = res
100+
101+
// RESOURCE: &{{cache zeusville.com v1 Joke} jokes 0xc00082a640 false 0xc00082a680}
102+
p.options.UpdateResource(p.resource)
103+
104+
if err := p.resource.Validate(); err != nil {
105+
return err
106+
}
107+
108+
// Check that resource doesn't have the API scaffolded
109+
if res, err := p.config.GetResource(p.resource.GVK); err == nil && res.HasAPI() {
110+
return errors.New("the API resource already exists")
111+
}
112+
113+
// Check that the provided group can be added to the project
114+
if !p.config.IsMultiGroup() && p.config.ResourcesLength() != 0 && !p.config.HasGroup(p.resource.Group) {
115+
return fmt.Errorf("multiple groups are not allowed by default, to enable multi-group set 'multigroup: true' in your PROJECT file")
116+
}
117+
118+
// Selected CRD version must match existing CRD versions.
119+
if pluginutil.HasDifferentCRDVersion(p.config, p.resource.API.CRDVersion) {
120+
return fmt.Errorf("only one CRD version can be used for all resources, cannot add %q", p.resource.API.CRDVersion)
121+
}
122+
123+
return nil
124+
}

pkg/quarkus/v1/init.go

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright 2021 The Java Operator SDK Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package v1
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"path/filepath"
23+
"strings"
24+
25+
"github.com/java-operator-sdk/kubebuilder-plugin/pkg/quarkus/v1/scaffolds"
26+
"github.com/spf13/pflag"
27+
"k8s.io/apimachinery/pkg/util/validation"
28+
29+
"sigs.k8s.io/kubebuilder/v3/pkg/config"
30+
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
31+
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
32+
)
33+
34+
// This file represents the CLI for this plugin.
35+
36+
const (
37+
groupFlag = "group"
38+
versionFlag = "version"
39+
kindFlag = "kind"
40+
)
41+
42+
type initSubcommand struct {
43+
apiSubcommand createAPISubcommand
44+
45+
config config.Config
46+
47+
// For help text.
48+
commandName string
49+
50+
// Flags
51+
group string
52+
domain string
53+
version string
54+
kind string
55+
projectName string
56+
}
57+
58+
var (
59+
_ plugin.InitSubcommand = &initSubcommand{}
60+
)
61+
62+
func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
63+
subcmdMeta.Description = `Initialize a new project based on the java-operator-sdk project.
64+
65+
Writes the following files:
66+
- a basic, Quarkus-based operator set-up
67+
- a pom.xml file to build the project with Maven
68+
`
69+
p.commandName = cliMeta.CommandName
70+
}
71+
72+
func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) {
73+
//// TODO: include flags required for this plugin
74+
75+
fs.SortFlags = false
76+
fs.StringVar(&p.domain, "domain", "my.domain", "domain for groups")
77+
fs.StringVar(&p.projectName, "project-name", "", "name of this project, the default being directory name")
78+
79+
fs.StringVar(&p.group, groupFlag, "", "resource Group")
80+
fs.StringVar(&p.version, versionFlag, "", "resource Version")
81+
fs.StringVar(&p.kind, kindFlag, "", "resource Kind")
82+
p.apiSubcommand.BindFlags(fs)
83+
}
84+
85+
func (p *initSubcommand) InjectConfig(c config.Config) error {
86+
p.config = c
87+
88+
if err := p.config.SetDomain(p.domain); err != nil {
89+
return err
90+
}
91+
92+
// Assign a default project name
93+
if p.projectName == "" {
94+
dir, err := os.Getwd()
95+
if err != nil {
96+
return fmt.Errorf("error getting current directory: %v", err)
97+
}
98+
p.projectName = strings.ToLower(filepath.Base(dir))
99+
}
100+
// Check if the project name is a valid k8s namespace (DNS 1123 label).
101+
if err := validation.IsDNS1123Label(p.projectName); err != nil {
102+
return fmt.Errorf("project name (%s) is invalid: %v", p.projectName, err)
103+
}
104+
if err := p.config.SetProjectName(p.projectName); err != nil {
105+
return err
106+
}
107+
108+
return nil
109+
}
110+
111+
func (p *initSubcommand) Validate() error {
112+
// TODO: validate the conditions you expect before running the plugin
113+
return nil
114+
}
115+
116+
func (p *initSubcommand) PostScaffold() error {
117+
// TODO: add anything you want to do AFTER the scaffolding has happened.
118+
return nil
119+
}
120+
121+
func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error {
122+
scaffolder := scaffolds.NewInitScaffolder(p.config)
123+
scaffolder.InjectFS(fs)
124+
return scaffolder.Scaffold()
125+
}

0 commit comments

Comments
 (0)