Skip to content

Commit

Permalink
Merge branch 'kubernetes-sigs:master' into sajiyah-makeinstall
Browse files Browse the repository at this point in the history
  • Loading branch information
Sajiyah-Salat authored Aug 22, 2023
2 parents 960524f + 4d43972 commit ab194c5
Show file tree
Hide file tree
Showing 33 changed files with 369 additions and 147 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ endif

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# target descriptions by '##'. The awk command is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
Expand Down Expand Up @@ -73,7 +73,7 @@ generate-testdata: ## Update/generate the testdata in $GOPATH/src/sigs.k8s.io/ku

.PHONY: generate-docs
generate-docs: ## Update/generate the docs in $GOPATH/src/sigs.k8s.io/kubebuilder
go run hack/docs/generate_samples.go
./hack/docs/generate.sh

.PHONY: check-docs
check-docs: ## Run the script to ensure that the docs are updated
Expand Down
8 changes: 7 additions & 1 deletion docs/book/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ src = "src"
title = "The Kubebuilder Book"

[output.html]
google-analytics = "UA-119864590-1"
curly-quotes = true
additional-css = ["theme/css/markers.css", "theme/css/custom.css", "theme/css/version-dropdown.css"]
git-repository-url = "https://github.com/kubernetes-sigs/kubebuilder"
Expand All @@ -16,3 +15,10 @@ command = "./litgo.sh"

[preprocessor.markerdocs]
command = "./markerdocs.sh"

[context.environment]
environment = { GO_VERSION = "1.20" }

[context.deploy-preview.environment]
environment = { GO_VERSION = "1.20" }

12 changes: 8 additions & 4 deletions docs/book/install-and-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ THIS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)

cd "$THIS_DIR"

[[ -n "$(command -v gimme)" ]] && eval "$(gimme stable)"
if [[ -n "$(command -v gimme)" ]]; then
GO_VERSION=${GO_VERSION:-stable} # Use the provided GO_VERSION or default to 'stable'
eval "$(gimme $GO_VERSION)"
fi
echo go version
GOBIN=$THIS_DIR/functions go install ./...

Expand Down Expand Up @@ -60,14 +63,15 @@ esac

# grab mdbook
# we hardcode linux/amd64 since rust uses a different naming scheme and it's a pain to tran
echo "downloading mdBook-v0.4.21-${arch}-${target}.${ext}"
echo "downloading mdBook-v0.4.34-${arch}-${target}.${ext}"
set -x
curl -sL -o /tmp/mdbook.${ext} https://github.com/rust-lang-nursery/mdBook/releases/download/v0.4.2/mdBook-v0.4.2-${arch}-${target}.${ext}
curl -sL -o /tmp/mdbook.${ext} https://github.com/rust-lang/mdBook/releases/download/v0.4.34/mdBook-v0.4.34-${arch}-${target}.${ext}
${cmd} /tmp/mdbook.${ext}
chmod +x /tmp/mdbook

echo "grabbing the latest released controller-gen"
go install sigs.k8s.io/controller-tools/cmd/[email protected]
go version
go install sigs.k8s.io/controller-tools/cmd/[email protected]

# make sure we add the go bin directory to our path
gobin=$(go env GOBIN)
Expand Down
1 change: 1 addition & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
- [Creating your own plugins](./plugins/creating-plugins.md)
- [Testing your own plugins](./plugins/testing-plugins.md)
- [Plugins Versioning](./plugins/plugins-versioning.md)
- [Extending Kubebuilder with external plugins](./plugins/external-plugins.md)

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ all: build

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# target descriptions by '##'. The awk command is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
Expand Down Expand Up @@ -74,8 +74,8 @@ build: manifests generate fmt vet ## Build manager binary.
run: manifests generate fmt vet ## Run a controller from your host.
go run ./cmd/main.go

# If you wish built the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it.
# If you wish to build the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
docker-build: test ## Build docker image with the manager.
Expand All @@ -85,12 +85,12 @@ docker-build: test ## Build docker image with the manager.
docker-push: ## Push docker image with the manager.
$(CONTAINER_TOOL) push ${IMG}

# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To properly provided solutions that supports more than one platform you should use this option.
# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/
# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option.
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
.PHONY: docker-buildx
docker-buildx: test ## Build and push docker image for the manager for cross-platform support
Expand Down
16 changes: 8 additions & 8 deletions docs/book/src/cronjob-tutorial/testdata/project/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ all: build

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# target descriptions by '##'. The awk command is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
Expand Down Expand Up @@ -74,8 +74,8 @@ build: manifests generate fmt vet ## Build manager binary.
run: manifests generate fmt vet ## Run a controller from your host.
go run ./cmd/main.go

# If you wish built the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it.
# If you wish to build the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
docker-build: test ## Build docker image with the manager.
Expand All @@ -85,12 +85,12 @@ docker-build: test ## Build docker image with the manager.
docker-push: ## Push docker image with the manager.
$(CONTAINER_TOOL) push ${IMG}

# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To properly provided solutions that supports more than one platform you should use this option.
# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/
# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option.
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
.PHONY: docker-buildx
docker-buildx: test ## Build and push docker image for the manager for cross-platform support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Therefore, you can check the changes in the layout results into:
- If your project support multi-group the APIs are scaffold under a directory called `apis`. Rename this directory to `api`
- Move the `controllers` directory under the `internal` and rename it for `controller`
- Now ensure that the imports will be updated accordingly by:
- Update the `main.go` imports to look for the new path of your controllers under the `pkg` directory
- Update the `main.go` imports to look for the new path of your controllers under the `internal/controller` directory

**Then, let's update the scaffolds paths**

Expand Down
16 changes: 8 additions & 8 deletions docs/book/src/multiversion-tutorial/testdata/project/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ all: build

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# target descriptions by '##'. The awk command is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
Expand Down Expand Up @@ -72,8 +72,8 @@ build: manifests generate fmt vet ## Build manager binary.
run: manifests generate fmt vet ## Run a controller from your host.
go run ./cmd/main.go

# If you wish built the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it.
# If you wish to build the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
docker-build: test ## Build docker image with the manager.
Expand All @@ -83,12 +83,12 @@ docker-build: test ## Build docker image with the manager.
docker-push: ## Push docker image with the manager.
docker push ${IMG}

# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To properly provided solutions that supports more than one platform you should use this option.
# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/
# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option.
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
.PHONY: docker-buildx
docker-buildx: test ## Build and push docker image for the manager for cross-platform support
Expand Down
156 changes: 156 additions & 0 deletions docs/book/src/plugins/external-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Extending Kubebuilder with external plugins

## Overview

Kubebuilder's functionality can be extended through the use of external plugins.

An external plugin is an executable (can be written in any language) that implements an execution pattern that Kubebuilder knows how to interact with.

The Kubebuilder CLI loads the external plugin in the specified path and interacts with it through `stdin` & `stdout`.

## When is it useful?

- If you want to create helpers or addons on top of the scaffolds done by Kubebuilder's default scaffolding.

- If you design customized layouts and want to take advantage of functions from Kubebuilder library.

- If you are looking for implementing plugins in a language other than `Go`.

## How to write it?

The inter-process communication between your external plugin and Kubebuilder is through the standard I/O.

Your external plugin can be written in any language, given it adheres to the [PluginRequest][PluginRequest] and [PluginResponse][PluginResponse] type structures.

`PluginRequest` encompasses all the data Kubebuilder collects from the CLI and previously executed plugins in the plugin chain.
Kubebuilder conveys the marshaled PluginRequest (a `JSON` object) to the external plugin over `stdin`.

Below is a sample JSON object of the `PluginRequest` type, triggered by `kubebuilder init --plugins sampleexternalplugin/v1 --domain my.domain`:
```json
{
"apiVersion": "v1alpha1",
"args": ["--domain", "my.domain"],
"command": "init",
"universe": {}
}
```

`PluginResponse` represents the updated state of the project, as modified by the plugin. This data structure is serialized into `JSON` and sent back to Kubebuilder via `stdout`.

Here is a sample JSON representation of the `PluginResponse` type:
```json
{
"apiVersion": "v1alpha1",
"command": "init",
"metadata": {
"description": "The `init` subcommand is meant to initialize a project via Kubebuilder. It scaffolds a single file: `initFile`",
"examples": "kubebuilder init --plugins sampleexternalplugin/v1 --domain my.domain"
},
"universe": {
"initFile": "A simple file created with the `init` subcommand"
},
"error": false,
"errorMsgs": []
}
```

In this example, the `init` command of the plugin has created a new file called `initFile`.

The content of this file is: `A simple file created with the init subcommand`, which is recorded in the `universe` field of the response.

This output is then sent back to Kubebuilder, allowing it to incorporate the changes made by the plugin into the project.

<aside class="note">
<h1>Caution</h1>

When writing your own external plugin, you **should not** directly echo or print anything to the stdout.

This is because Kubebuilder and your plugin are communicating with each other via `stdin` and `stdout` using structured `JSON` data.
Any additional information sent to stdout (such as debug messages or logs) that's not part of the expected PluginResponse JSON structure may cause parsing errors when Kubebuilder tries to read and decode the response from your plugin.

If you need to include logs or debug messages while developing your plugin, consider writing these messages to a log file instead.

</aside>

## How to use it?

### Prerequisites
- kubebuilder CLI > 3.11.0
- An executable for the external plugin.

This could be a plugin that you've created yourself, or one from an external source.
- Configuration of the external plugin's path.

This can be done by setting the `${EXTERNAL_PLUGINS_PATH}` environment variable, or by placing the plugin in a path that follows a `group-like name and version` scheme:
```sh
# for Linux
$HOME/.config/kubebuilder/plugins/${name}/${version}

# for OSX
~/Library/Application Support/kubebuilder/plugins/${name}/${version}
```

### Subcommands:

The external plugin supports the same subcommands as kubebuilder already provides:
- `init`: project initialization.
- `create api`: scaffold Kubernetes API definitions.
- `create webhook`: scaffold Kubernetes webhooks.
- `edit`: update the project configuration.

Also, there are **Optional** subcommands for a better user experience:
- `metadata`: add customized plugin description and examples when a `--help` flag is specified.
- `flags`: specify valid flags for Kubebuilder to pass to the external plugin.

<aside class="note">
<h1>More about `flags` subcommand</h1>

The `flags` subcommand in an external plugin allows for early error detection by informing Kubebuilder about the flags the plugin supports. If an unsupported flag is identified, Kubebuilder can issue an error before the plugin is called to execute.
If a plugin does not implement the `flags` subcommand, Kubebuilder will pass all flags to the plugin, making it the external plugin's responsibility to handle any invalid flags.

</aside>

### Configuration

You can configure your plugin path with a ENV VAR `$EXTERNAL_PLUGINS_PATH` to tell Kubebuilder where to search for the plugin binary, such as:
```sh
export EXTERNAL_PLUGINS_PATH = <custom-path>
```

Otherwise, Kubebuilder would search for the plugins in a default path based on your OS.

Now, you can using it by calling the CLI commands:
```sh
# Initialize a new project with the external plugin named `sampleplugin`
kubebuilder init --plugins sampleplugin/v1

# Display help information of the `init` subcommand of the external plugin
kubebuilder init --plugins sampleplugin/v1 --help

# Create a new API with the above external plugin with a customized flag `number`
kubebuilder create api --plugins sampleplugin/v1 --number 2

# Create a webhook with the above external plugin with a customized flag `hooked`
kubebuilder create webhook --plugins sampleplugin/v1 --hooked

# Update the project configuration with the above external plugin
kubebuilder edit --plugins sampleplugin/v1

# Create new APIs with external plugins v1 and v2 by respecting the plugin chaining order
kubebuilder create api --plugins sampleplugin/v1,sampleplugin/v2

# Create new APIs with the go/v4 plugin and then pass those files to the external plugin by respecting the plugin chaining order
kubebuilder create api --plugins go/v4,sampleplugin/v1
```


## Further resources

- Check the [design proposal of the external plugin](https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-2.md)
- Check the [plugin implementation](https://github.com/kubernetes-sigs/kubebuilder/pull/2338)
- A [sample external plugin written in Go](https://github.com/kubernetes-sigs/kubebuilder/tree/master/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1)
- A [sample external plugin written in Python](https://github.com/rashmigottipati/POC-Phase2-Plugins)
- A [sample external plugin written in JavaScript](https://github.com/Eileen-Yu/kb-js-plugin)

[PluginRequest]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugin/external/types.go#L23
[PluginResponse]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugin/external/types.go#L42
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ all: build

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# target descriptions by '##'. The awk command is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
Expand Down
Loading

0 comments on commit ab194c5

Please sign in to comment.