Paths where every file is placed is hardcoded in kubebuilder. The current scaffold is a good starting point, but some projects may want to use a different layout.
Files that should have a configurable path:
Dockerfile: currently in root directory.main.go: currently in root directory.KIND_types.go, groupversion_info.go & zz-generated.deepcopy.go: currently in the api/VERSION directory.KIND_controller.go & suite_test.go: currently in controllers directory.manager: currently under the bin directory.*.yaml files: currently under config directory.boilerplate.go.txt: currently in hack directory.Haven't used webhooks but they will probably also have some hard-coded paths.
For example, following https://github.com/golang-standards/project-layout, the wanted layout would be:
root
+- build
| +- package
| | +- Dockerfile
| +- manager
+- cmd
| +- manager
| | +- main.go
+- config
| +- boilerplate.go.txt
+- deployments
| +- certmanager
| +- crd
| +- default
| +- manager
| +- prometheus
| +- rbac
| +- samples
| +- webhook
+- internal
| +- api
| | +- v1alpha1
| | | +- KIND_types.go
| | | +- groupversion_info.go
| | | +- zz-generated.deepcopy.go
| +- controllers
| | +- KIND_controller.go
| | +- suite_test.go
Some implementation considerations:
Dockerfile, main.go, manager and all the *.yaml files are required from the Makefile. The rest should be pretty starightforward.
Paths should be stored either as a string or as an array. If stored as a string, / should be used as the separator. Then the scaffolding would split by / and use path/filepath.Join to be platform independent. If stored as an array, only the path/filepath.Join step would be required.
Paths require some templating. {group}, {version} and {kind} could be used. As fmt.Sprintf doesn't support named parameters, they should first be replaced internally by %[1]s, %[2]s and %[3]s, and then use fmt.Sprintf for formatting.
This feature requests would also prepare for multi-group apis. If the api path configuration option contains a {group} tag, multi-group is enabled, if it doesn't, it is disabled.
/kind feature
How would you get the PROJECT configuration values inside the Makefile?
So, I'm a bit wary of this -- kubebuilder is supposed to have opinions. I wouldn't mind having a "scaffold this one file to this location" perhaps, but I'm really not sure how deep we want to go on full configuration of KB itself (willing to be convinced otherwise, but thusfar we've been reluctant to support other API paths, and such).
I do agree that kubebuilder must have an opinion, but I think that some degree of configurable paths would provide nicer project structures while still keeping the starting learning curve smooth.
I have taken into account the design decissions in https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/simplified-scaffolding.md. I think that the effort that was done in reducing the number of scaffolded files was really needed as it was hard to understand for newcommers. However, while having api and controllers as directories under the root project directory makes the files easier to find, they also polute a bit the root directory and do not follow de-facto standards as having go libraries under pkg or internal and commands under cmd.
What about the following configurable paths:
., in my previous example cmd/manager. main.go would be placed in this directory.., in my previous example internal. api/apis, controllers and webhook directories as they are now will be placed inside this directory.bin, in my previous example build. Binaries will be output to this directory (it may allow things like $GOBIN).config, in my previous example deployments. All the k8s and kustomize YAML files subdirectories.., in my previous example build/package. Dockerfile would be placed here. It would still be called with the root directory as the context for docker build.hack, in my previous example config.This would allow some project customization while still providing opinion on how those directories are organized internally. The default values would still be the current ones, and they would only be modified through som flags in kubebuilder init ... command. The paths will be stored in PROJECT. There will be no automated way to change this after creation, as it would require modifying imports though all the project, and other hardcoded paths such as in the Makefile or the Dockerfile.
Since we're talking about making things better: I'd like to raise an open question regarding webhook-related-functions location, is api/.../v1 the right package to define the validation and defaulting?
api/.../v1 package. How about a api/.../v1/validation package?Plugins should be able to work around this, closing in favor of plugins
Most helpful comment
I do agree that kubebuilder must have an opinion, but I think that some degree of configurable paths would provide nicer project structures while still keeping the starting learning curve smooth.
I have taken into account the design decissions in https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/simplified-scaffolding.md. I think that the effort that was done in reducing the number of scaffolded files was really needed as it was hard to understand for newcommers. However, while having
apiandcontrollersas directories under the root project directory makes the files easier to find, they also polute a bit the root directory and do not follow de-facto standards as having go libraries underpkgorinternaland commands undercmd.What about the following configurable paths:
., in my previous examplecmd/manager.main.gowould be placed in this directory.., in my previous exampleinternal.api/apis,controllersandwebhookdirectories as they are now will be placed inside this directory.bin, in my previous examplebuild. Binaries will be output to this directory (it may allow things like$GOBIN).config, in my previous exampledeployments. All the k8s and kustomize YAML files subdirectories.., in my previous examplebuild/package. Dockerfile would be placed here. It would still be called with the root directory as the context for docker build.hack, in my previous exampleconfig.This would allow some project customization while still providing opinion on how those directories are organized internally. The default values would still be the current ones, and they would only be modified through som flags in
kubebuilder init ...command. The paths will be stored in PROJECT. There will be no automated way to change this after creation, as it would require modifying imports though all the project, and other hardcoded paths such as in the Makefile or the Dockerfile.