Skip to content

Commit 882c990

Browse files
committed
✨ Enhance sample external plugin: add Prometheus ServiceMonitor and kustomization, update PROJECT file handling, and improve test script
1 parent 839a43f commit 882c990

File tree

9 files changed

+181
-55
lines changed

9 files changed

+181
-55
lines changed

docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ module v1
33
go 1.24.5
44

55
require (
6+
github.com/spf13/afero v1.15.0
67
github.com/spf13/pflag v1.0.10
78
sigs.k8s.io/kubebuilder/v4 v4.9.0
8-
sigs.k8s.io/yaml v1.6.0
99
)
1010

1111
replace sigs.k8s.io/kubebuilder/v4 => ../../../../../../../
1212

1313
require (
1414
github.com/gobuffalo/flect v1.0.3 // indirect
1515
github.com/kr/text v0.2.0 // indirect
16-
github.com/spf13/afero v1.15.0 // indirect
1716
go.yaml.in/yaml/v2 v2.4.2 // indirect
1817
golang.org/x/mod v0.28.0 // indirect
1918
golang.org/x/sync v0.17.0 // indirect
2019
golang.org/x/text v0.29.0 // indirect
2120
golang.org/x/tools v0.37.0 // indirect
21+
sigs.k8s.io/yaml v1.6.0 // indirect
2222
)
File renamed without changes.
File renamed without changes.

docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/scaffolds/edit.go

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@ limitations under the License.
1616
package scaffolds
1717

1818
import (
19+
"errors"
1920
"fmt"
2021
"os"
21-
"path/filepath"
2222

23-
"v1/scaffolds/internal/templates/prometheus"
23+
"github.com/spf13/afero"
2424

25+
"v1/internal/test/plugins/prometheus"
26+
27+
"sigs.k8s.io/kubebuilder/v4/pkg/config/store/yaml"
28+
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
2529
"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
2630
"sigs.k8s.io/kubebuilder/v4/pkg/plugin/external"
27-
yamlv3 "sigs.k8s.io/yaml"
2831
)
2932

3033
var EditFlags = []external.Flag{}
@@ -77,48 +80,46 @@ func EditCmd(pr *external.PluginRequest) external.PluginResponse {
7780

7881
// ProjectConfig represents the minimal PROJECT file structure we need
7982
type ProjectConfig struct {
80-
Domain string `yaml:"domain"`
81-
ProjectName string `yaml:"projectName"`
82-
Repo string `yaml:"repo"`
83+
Domain string
84+
ProjectName string
85+
Repo string
8386
}
8487

85-
// loadProjectConfig reads the PROJECT file and extracts necessary information
88+
// loadProjectConfig reads the PROJECT file using the kubebuilder config API.
8689
func loadProjectConfig() (*ProjectConfig, error) {
87-
projectPath := filepath.Join(".", "PROJECT")
88-
89-
if _, err := os.Stat(projectPath); os.IsNotExist(err) {
90-
// Return default values if PROJECT file doesn't exist
91-
return &ProjectConfig{
92-
Domain: "example.com",
93-
ProjectName: "project",
94-
Repo: "example.com/project",
95-
}, nil
96-
}
97-
98-
data, err := os.ReadFile(projectPath)
99-
if err != nil {
100-
return nil, fmt.Errorf("failed to read PROJECT file: %w", err)
90+
store := yaml.New(machinery.Filesystem{FS: afero.NewOsFs()})
91+
if err := store.Load(); err != nil {
92+
if errors.Is(err, os.ErrNotExist) {
93+
return &ProjectConfig{
94+
Domain: "example.com",
95+
ProjectName: "project",
96+
Repo: "example.com/project",
97+
}, nil
98+
}
99+
return nil, fmt.Errorf("failed to load PROJECT file: %w", err)
101100
}
102101

103-
var cfg ProjectConfig
104-
if err := yamlv3.Unmarshal(data, &cfg); err != nil {
105-
return nil, fmt.Errorf("failed to unmarshal PROJECT file: %w", err)
102+
cfg := store.Config()
103+
if cfg == nil {
104+
return nil, fmt.Errorf("PROJECT file is empty or invalid")
106105
}
107106

108-
// Set defaults if fields are empty
109-
if cfg.Domain == "" {
110-
cfg.Domain = "example.com"
107+
domain := cfg.GetDomain()
108+
if domain == "" {
109+
domain = "example.com"
111110
}
112-
if cfg.ProjectName == "" {
113-
cfg.ProjectName = "project"
114-
if cfg.Repo != "" {
115-
// Extract project name from repo path
116-
cfg.ProjectName = filepath.Base(cfg.Repo)
117-
}
111+
projectName := cfg.GetProjectName()
112+
if projectName == "" {
113+
projectName = "project"
118114
}
119-
if cfg.Repo == "" {
120-
cfg.Repo = cfg.Domain + "/" + cfg.ProjectName
115+
repo := cfg.GetRepository()
116+
if repo == "" {
117+
repo = fmt.Sprintf("%s/%s", domain, projectName)
121118
}
122119

123-
return &cfg, nil
120+
return &ProjectConfig{
121+
Domain: domain,
122+
ProjectName: projectName,
123+
Repo: repo,
124+
}, nil
124125
}

docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/test/test.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,10 @@ cd testdata/testplugin
2222
rm -rf *
2323

2424
# Run Kubebuilder commands inside the testplugin directory
25-
kubebuilder init --plugins sampleexternalplugin/v1 --domain sample.domain.com
26-
kubebuilder create api --plugins sampleexternalplugin/v1 --number 2 --group samplegroup --version v1 --kind SampleKind
25+
kubebuilder init --plugins go/v4 --domain sample.domain.com --repo sample.domain.com/test-operator
26+
kubebuilder edit --plugins sampleexternalplugin/v1
27+
28+
# Ensure Prometheus assets were scaffolded
29+
test -f config/prometheus/monitor.yaml
30+
test -f config/prometheus/kustomization.yaml
31+
test -f config/default/kustomization_prometheus_patch.yaml

docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/testdata/testplugin/PROJECT

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# testplugin
2+
// TODO(user): Add simple overview of use/purpose
3+
4+
## Description
5+
// TODO(user): An in-depth paragraph about your project and overview of use
6+
7+
## Getting Started
8+
9+
### Prerequisites
10+
- go version v1.24.0+
11+
- docker version 17.03+.
12+
- kubectl version v1.11.3+.
13+
- Access to a Kubernetes v1.11.3+ cluster.
14+
15+
### To Deploy on the cluster
16+
**Build and push your image to the location specified by `IMG`:**
17+
18+
```sh
19+
make docker-build docker-push IMG=<some-registry>/testplugin:tag
20+
```
21+
22+
**NOTE:** This image ought to be published in the personal registry you specified.
23+
And it is required to have access to pull the image from the working environment.
24+
Make sure you have the proper permission to the registry if the above commands don’t work.
25+
26+
**Install the CRDs into the cluster:**
27+
28+
```sh
29+
make install
30+
```
31+
32+
**Deploy the Manager to the cluster with the image specified by `IMG`:**
33+
34+
```sh
35+
make deploy IMG=<some-registry>/testplugin:tag
36+
```
37+
38+
> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin
39+
privileges or be logged in as admin.
40+
41+
**Create instances of your solution**
42+
You can apply the samples (examples) from the config/sample:
43+
44+
```sh
45+
kubectl apply -k config/samples/
46+
```
47+
48+
>**NOTE**: Ensure that the samples has default values to test it out.
49+
50+
### To Uninstall
51+
**Delete the instances (CRs) from the cluster:**
52+
53+
```sh
54+
kubectl delete -k config/samples/
55+
```
56+
57+
**Delete the APIs(CRDs) from the cluster:**
58+
59+
```sh
60+
make uninstall
61+
```
62+
63+
**UnDeploy the controller from the cluster:**
64+
65+
```sh
66+
make undeploy
67+
```
68+
69+
## Project Distribution
70+
71+
Following the options to release and provide this solution to the users.
72+
73+
### By providing a bundle with all YAML files
74+
75+
1. Build the installer for the image built and published in the registry:
76+
77+
```sh
78+
make build-installer IMG=<some-registry>/testplugin:tag
79+
```
80+
81+
**NOTE:** The makefile target mentioned above generates an 'install.yaml'
82+
file in the dist directory. This file contains all the resources built
83+
with Kustomize, which are necessary to install this project without its
84+
dependencies.
85+
86+
2. Using the installer
87+
88+
Users can just run 'kubectl apply -f <URL for YAML BUNDLE>' to install
89+
the project, i.e.:
90+
91+
```sh
92+
kubectl apply -f https://raw.githubusercontent.com/<org>/testplugin/<tag or branch>/dist/install.yaml
93+
```
94+
95+
### By providing a Helm Chart
96+
97+
1. Build the chart using the optional helm plugin
98+
99+
```sh
100+
kubebuilder edit --plugins=helm/v1-alpha
101+
```
102+
103+
2. See that a chart was generated under 'dist/chart', and users
104+
can obtain this solution from there.
105+
106+
**NOTE:** If you change the project, you need to update the Helm Chart
107+
using the same command above to sync the latest changes. Furthermore,
108+
if you create webhooks, you need to use the above command with
109+
the '--force' flag and manually ensure that any custom configuration
110+
previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml'
111+
is manually re-applied afterwards.
112+
113+
## Contributing
114+
// TODO(user): Add detailed information on how you would like others to contribute to this project
115+
116+
**NOTE:** Run `make help` for more information on all potential `make` targets
117+
118+
More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
119+
120+
## License
121+
122+
Copyright 2025.
123+
124+
Licensed under the Apache License, Version 2.0 (the "License");
125+
you may not use this file except in compliance with the License.
126+
You may obtain a copy of the License at
127+
128+
http://www.apache.org/licenses/LICENSE-2.0
129+
130+
Unless required by applicable law or agreed to in writing, software
131+
distributed under the License is distributed on an "AS IS" BASIS,
132+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133+
See the License for the specific language governing permissions and
134+
limitations under the License.
135+

docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/testdata/testplugin/apiFile.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/testdata/testplugin/initFile.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)