diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 0c35ae885f6..6bc3edb3f32 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -36,7 +36,7 @@ body: Code & details examples `````markdown - Some code code written in Go: + Some code written in Go: ```go type Manager struct { diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 8af6803acd5..e0385693029 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -36,7 +36,7 @@ body: Code & details examples `````markdown - Some code code written in Go: + Some code written in Go: ```go type Manager struct { @@ -75,7 +75,7 @@ body: Does it require a particular Kubernetes version? - Is there currently another isssue associated with this (use github syntax + Is there currently another issue associated with this (use github syntax like `#xyz` to link to it)? validations: {required: true} diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..12bdbe3a634 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,56 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + # Workflow files stored in the + # default location of `.github/workflows` + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: ":seedling:" + labels: + - "ok-to-test" + + # Maintain dependencies for go + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" + labels: + - "ok-to-test" + + # Maintain dependencies for dockerfile in the branches + - package-ecosystem: docker + directory: "/build/thirdparty/darwin" + target-branch: "tools-releases" + schedule: + interval: daily + - package-ecosystem: docker + directory: "/build/thirdparty/linux" + target-branch: "tools-releases" + schedule: + interval: "weekly" + + # Maintain dependencies for dockerfile scaffold in the projects + - package-ecosystem: docker + directory: "testdata/project-v3" + schedule: + interval: daily + - package-ecosystem: docker + directory: "testdata/project-v4" + schedule: + interval: "weekly" + + # Maintain dependencies for go in external plugin sample + - package-ecosystem: "gomod" + directory: "docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1" + schedule: + interval: "weekly" + labels: + - "ok-to-test" diff --git a/.github/workflows/apidiff.yml b/.github/workflows/apidiff.yml index 691a138379b..bc7ab234085 100644 --- a/.github/workflows/apidiff.yml +++ b/.github/workflows/apidiff.yml @@ -6,49 +6,22 @@ on: pull_request: jobs: - check_docs_only: - name: check_docs_only - runs-on: ubuntu-18.04 - outputs: - skip: ${{ steps.check_docs_only.outputs.skip }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: check_docs_only - # Since PR's are squashed prior to merging to the branch checked out (default branch), - # HEAD^ will resolve to the previous point in history. - run: | - REF="HEAD^" - [[ -z "${{ github.base_ref }}" ]] || REF=$(git show-ref ${{ github.base_ref }} | head -1 | cut -d' ' -f2) - echo "::set-output name=skip::$(test/check-docs-only.sh $REF)" - go-apidiff: name: Verify API differences runs-on: ubuntu-latest - needs: check_docs_only # Pull requests from different repository only trigger this checks - if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) && needs.check_docs_only.outputs.skip != 'true' + if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) steps: - name: Clone the code uses: actions/checkout@v3 with: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: "1.19" + go-version: '~1.20' - name: Execute go-apidiff - uses: joelanford/go-apidiff@v0.4.0 + uses: joelanford/go-apidiff@v0.6.0 with: compare-imports: true print-compatible: true - - name: Report failure - uses: nashmaniac/create-issue-action@v1.1 - # Only report failures of pushes (PRs have are visible through the Checks section) to the default branch - if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/master' - with: - title: 🐛 go-apidiff failed for ${{ github.sha }} - token: ${{ secrets.GITHUB_TOKEN }} - labels: kind/bug - body: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index bd071310451..b4276d63d91 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,47 +6,27 @@ on: pull_request: jobs: - check_docs_only: - name: check_docs_only - runs-on: ubuntu-18.04 - outputs: - skip: ${{ steps.check_docs_only.outputs.skip }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: check_docs_only - # Since PR's are squashed prior to merging to the branch checked out (default branch), - # HEAD^ will resolve to the previous point in history. - run: | - REF="HEAD^" - [[ -z "${{ github.base_ref }}" ]] || REF=$(git show-ref ${{ github.base_ref }} | head -1 | cut -d' ' -f2) - echo "::set-output name=skip::$(test/check-docs-only.sh $REF)" - lint: name: golangci-lint runs-on: ubuntu-latest - needs: check_docs_only # Pull requests from the same repository won't trigger this checks as they were already triggered by the push - if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) && needs.check_docs_only.outputs.skip != 'true' + if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) steps: - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: 1.19 + go-version: '~1.20' - name: Clone the code uses: actions/checkout@v3 - name: Run linter uses: golangci/golangci-lint-action@v3 with: - version: v1.49 # Always uses the latest patch version. + version: v1.51 only-new-issues: true # Show only new issues if it's a pull request - - name: Report failure - uses: nashmaniac/create-issue-action@v1.1 - # Only report failures of pushes (PRs have are visible through the Checks section) to the default branch - if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/master' - with: - title: 🐛 Lint failed for ${{ github.sha }} - token: ${{ secrets.GITHUB_TOKEN }} - labels: kind/bug - body: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + + yamllint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Run yamllint make target + run: make yamllint diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3bc15ff18e8..4f5f4328436 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,17 +9,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Fetch all tags run: git fetch --force --tags - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: - go-version: '~1.19' + go-version: '~1.20' - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v2 + uses: goreleaser/goreleaser-action@v4 with: version: v1.11.2 args: release -f ./build/.goreleaser.yml --rm-dist diff --git a/.github/workflows/testdata.yml b/.github/workflows/testdata.yml index 827554deeed..a9873c867a2 100644 --- a/.github/workflows/testdata.yml +++ b/.github/workflows/testdata.yml @@ -16,21 +16,14 @@ jobs: - name: Clone the code uses: actions/checkout@v3 - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: '1.19' + go-version: '~1.20' - name: Remove pre-installed kustomize # This step is needed as the following one tries to remove # kustomize for each test but has no permission to do so run: sudo rm -f /usr/local/bin/kustomize - name: Verify testdata directory run: make check-testdata - - name: Report failure - uses: nashmaniac/create-issue-action@v1.1 - # Only report failures of pushes (PRs have are visible through the Checks section) to the default branch - if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/master' - with: - title: 🐛 Testadata verification failed for ${{ github.sha }} - token: ${{ secrets.GITHUB_TOKEN }} - labels: kind/bug - body: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + - name: Verify docs update + run: make check-docs diff --git a/.github/workflows/unit-tests-legacy.yml b/.github/workflows/unit-tests-legacy.yml index 48725829266..ca2a4751174 100644 --- a/.github/workflows/unit-tests-legacy.yml +++ b/.github/workflows/unit-tests-legacy.yml @@ -21,30 +21,12 @@ jobs: - name: Clone the code uses: actions/checkout@v3 - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - # the go/v2 cannot be updated and is scaffold with golang 1.13 - # (version used by its dep version of the controller-runtime) - # however, we are unable to downgrade the version here - # because we will face errors - # So we are keeping the latest version where it works - # and highlighting that must be fixed - # Therefore, we probably will deprecate go/v2 soon since we cannot upgrade it - # to use the versions of controller-runtime > v0.9 - # and controller-tools > v0.6 as k8s > 1.21 then it might not be valid we spend effort on this fix - go-version: "1.17" + go-version: "1.19" # This step is needed as the following one tries to remove # kustomize for each test but has no permission to do so - name: Remove pre-installed kustomize run: sudo rm -f /usr/local/bin/kustomize - name: Perform the test run: make test-legacy - - name: Report failure - uses: nashmaniac/create-issue-action@v1.1 - # Only report failures of pushes (PRs have are visible through the Checks section) to the default branch - if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/master' - with: - title: 🐛 Unit tests failed on ${{ matrix.os }} for ${{ github.sha }} - token: ${{ secrets.GITHUB_TOKEN }} - labels: kind/bug - body: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index d1f4edc3917..a6b88c4f1dc 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -6,23 +6,6 @@ on: pull_request: jobs: - check_docs_only: - name: check_docs_only - runs-on: ubuntu-18.04 - outputs: - skip: ${{ steps.check_docs_only.outputs.skip }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: check_docs_only - # Since PR's are squashed prior to merging to the branch checked out (default branch), - # HEAD^ will resolve to the previous point in history. - run: | - REF="HEAD^" - [[ -z "${{ github.base_ref }}" ]] || REF=$(git show-ref ${{ github.base_ref }} | head -1 | cut -d' ' -f2) - echo "::set-output name=skip::$(test/check-docs-only.sh $REF)" - test: name: ${{ matrix.os }} runs-on: ${{ matrix.os }} @@ -31,16 +14,15 @@ jobs: os: - ubuntu-latest - macos-latest - needs: check_docs_only # Pull requests from the same repository won't trigger this checks as they were already triggered by the push - if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) && needs.check_docs_only.outputs.skip != 'true' + if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) steps: - name: Clone the code uses: actions/checkout@v3 - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: "1.19" + go-version: '~1.20' # This step is needed as the following one tries to remove # kustomize for each test but has no permission to do so - name: Remove pre-installed kustomize @@ -48,7 +30,7 @@ jobs: - name: Perform the test run: make test - name: Report failure - uses: nashmaniac/create-issue-action@v1.1 + uses: nashmaniac/create-issue-action@v1.2 # Only report failures of pushes (PRs have are visible through the Checks section) to the default branch if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/master' with: @@ -61,15 +43,14 @@ jobs: name: Code coverage needs: - test - - check_docs_only runs-on: ubuntu-latest # Pull requests from the same repository won't trigger this checks as they were already triggered by the push - if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) && needs.check_docs_only.outputs.skip != 'true' + if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) steps: - name: Clone the code uses: actions/checkout@v3 - name: Setup Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: "1.19" - name: Generate the coverage output @@ -78,12 +59,3 @@ jobs: uses: shogo82148/actions-goveralls@v1 with: path-to-profile: coverage-all.out - - name: Report failure - uses: nashmaniac/create-issue-action@v1.1 - # Only report failures of pushes (PRs have are visible through the Checks section) to the default branch - if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/master' - with: - title: 🐛 Coverage report failed for ${{ github.sha }} - token: ${{ secrets.GITHUB_TOKEN }} - labels: kind/bug - body: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 0cb5bf54830..03bc6556d2f 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -13,6 +13,6 @@ jobs: steps: - name: Verifier action id: verifier - uses: kubernetes-sigs/kubebuilder-release-tools@v0.2.0 + uses: kubernetes-sigs/kubebuilder-release-tools@v0.3.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 12072430047..3cd3d73e21f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ .idea/ .vscode/ - +WORKSPACE # don't check in the build output of the book docs/book/book/ +# ignore auto-generated dir by `mdbook serve` +docs/book/src/docs + # Editor temp files *~ \#*# @@ -22,3 +25,4 @@ docs/book/book/ # skip testdata go.sum, since it may have # different result depending on go version /testdata/**/go.sum +/docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1/bin \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 88e1f7b5285..8ca78c49c23 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,3 +1,7 @@ +run: + deadline: 5m + allow-parallel-runners: true + issues: # don't skip warning about doc comments # don't exclude the default set of lint @@ -7,14 +11,51 @@ issues: exclude-rules: - linters: [gosec] path: "test/e2e/*" + - path: "hack/docs/*" + linters: + - lll + - gosec linters-settings: govet: enable=fieldalignment: true revive: rules: - - name: if-return - disabled: true + # The following rules are recommended https://github.com/mgechev/revive#recommended-configuration + - name: blank-imports + - name: context-as-argument + - name: context-keys-type + - name: dot-imports + - name: error-return + - name: error-strings + - name: error-naming + - name: exported + disabled: true # TODO: Investigate if it should be enabled. Disabled for now due to many findings. + - name: if-return + disabled: true # TODO: Investigate if it should be enabled. Disabled for now due to many findings. + - name: increment-decrement + - name: var-naming + disabled: true # TODO: Investigate if it should be enabled. Disabled for now due to many findings. + - name: var-declaration + - name: package-comments + disabled: true # TODO: Investigate if it should be enabled. Disabled for now due to many findings. + - name: range + - name: receiver-naming + - name: time-naming + - name: unexported-return + - name: indent-error-flow + - name: errorf + - name: empty-block + disabled: true # TODO: Investigate if it should be enabled. Disabled for now due to many findings. + - name: superfluous-else + - name: unused-parameter + - name: unreachable-code + - name: redefines-builtin-id + # + # Rules in addition to the recommended configuration above. + # + - name: bool-literal-in-expr + - name: constant-logical-expr linters: disable-all: true @@ -40,6 +81,3 @@ linters: - unconvert - unparam - unused - -run: - deadline: 5m diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 87f6354caa9..f1c031764b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ Please see https://git.k8s.io/community/CLA.md for more info. ## Prerequisites -- [go](https://golang.org/dl/) version v1.16+. +- [go](https://golang.org/dl/) version v1.20+. - [docker](https://docs.docker.com/install/) version 17.03+. - [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) version v1.11.3+. - [kustomize](https://github.com/kubernetes-sigs/kustomize/blob/master/site/content/en/docs/Getting%20started/installation.md) v3.1.0+ @@ -62,6 +62,63 @@ Following the targets that can be used to test your changes locally. **NOTE** To use the `make lint` is required to install `golangci-lint` locally. More info: https://github.com/golangci/golangci-lint#install +### Test Plugin + +If your intended PR creates a new plugin, make sure the PR also provides test cases. Testing should include: + +1. `e2e tests` to validate the behavior of the proposed plugin. +2. `sample projects` to verify the scaffolded output from the plugin. + +#### 1. Plugin E2E Tests + +All the plugins provided by Kubebuilder should be validated through `e2e-tests` across multiple platforms. + +Current Kubebuilder provides the testing framework that includes testing code based on [ginkgo](https://github.com/onsi/ginkgo), [Github Actions](https://github.com/Kavinjsir/kubebuilder/blob/docs%2Ftest-plugin/.github/workflows/testdata.yml) for unit tests, and multiple env tests driven by [test-infra](https://github.com/kubernetes/test-infra/blob/master/config/jobs/kubernetes-sigs/kubebuilder/kubebuilder-presubmits.yaml). + +To fully test the proposed plugin: + +1. Create a new package(folder) under `test/e2e/`. +2. Create [e2e_suite_test.go](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/v4/e2e_suite_test.go), which imports the necessary testing framework. +3. Create `generate_test.go` ([ref](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/v4/generate_test.go)). That should: + - Introduce/Receive a `TextContext` instance + - Trigger the plugin's bound subcommands. See [Init](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L213), [CreateAPI](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.6.0/test/e2e/utils/test_context.go#L222) + - Use [PluginUtil](https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin/util) to verify the scaffolded outputs. See [InsertCode](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/pkg/plugin/util/util.go#L67), [ReplaceInFile](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.6.0/pkg/plugin/util/util.go#L196), [UncommendCode](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.6.0/pkg/plugin/util/util.go#L86) +4. Create `plugin_cluster_test.go` ([ref](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/v4/plugin_cluster_test.go)). That should: + + - 4.1. Setup testing environment, e.g: + + - Cleanup environment, create temp dir. See [Prepare](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L97) + - If your test will cover the provided features then, ensure that you install prerequisites CRDs: See [InstallCertManager](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L138), [InstallPrometheusManager](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.6.0/test/e2e/utils/test_context.go#L171) + + - 4.2. Run the function from `generate_test.go`. + + - 4.3. Further make sure the scaffolded output works, e.g: + + - Execute commands in your `Makefile`. See [Make](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L240) + - Temporary load image of the testing controller. See [LoadImageToKindCluster](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L283) + - Call Kubectl to validate running resources. See [utils.Kubectl](https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/test/e2e/utils#Kubectl) + + - 4.4. Delete temporary resources after testing exited, e.g: + - Uninstall prerequisites CRDs: See [UninstallPrometheusOperManager](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L183) + - Delete temp dir. See [Destroy](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L255) + +5. Add the command in [test/e2e/plugin](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/setup.sh#L65) to run your testing code: + +```shell +go test $(dirname "$0")/ $flags -timeout 30m +``` + +#### 2. Sample Projects from the Plugin + +It is also necessary to test consistency of the proposed plugin across different env and the integration with other plugins. + +This is performed by generating sample projects based on the plugins. The CI workflow defined in Github Action would validate the availability and the consistency. + +See: + +- [test/testdata/generated.sh](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/testdata/generate.sh#L144) +- [make generate](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/Makefile#L70) + ## PR Process See [VERSIONING.md](VERSIONING.md) for a full description. TL;DR: @@ -82,6 +139,13 @@ changes, which don't deserve a release note. Please don't abuse it. You can also use the equivalent emoji directly, since GitHub doesn't render the `:xyz:` aliases in PR titles. +If the PR is "plugin" scoped, you may also append the responding plugin names in the prefix. +[For instance](https://github.com/kubernetes-sigs/kubebuilder/commit/0b36d0c4021bbf52f29d5a990157466761ec180c): + +``` +🐛 (kustomize/v2-alpha): Fix typo issue in the labels added to the manifests +``` + Individual commits should not be tagged separately, but will generally be assumed to match the PR. For instance, if you have a bugfix in with a breaking change, it's generally encouraged to submit the bugfix diff --git a/Makefile b/Makefile index 8289e0ae7c4..3e49bccab68 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright 2019 The Kubernetes Authors. +# Copyright 2023 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -63,7 +63,7 @@ install: build ## Build and install the binary with the current source code. Use ##@ Development .PHONY: generate -generate: generate-testdata ## Update/generate all mock data. You should run this commands to update the mock data after your changes. +generate: generate-testdata generate-docs ## Update/generate all mock data. You should run this commands to update the mock data after your changes. go mod tidy .PHONY: generate-testdata @@ -71,19 +71,31 @@ generate-testdata: ## Update/generate the testdata in $GOPATH/src/sigs.k8s.io/ku rm -rf testdata/ ./test/testdata/generate.sh +.PHONY: generate-docs +generate-docs: ## Update/generate the docs in $GOPATH/src/sigs.k8s.io/kubebuilder + go run hack/docs/generate_samples.go + +.PHONY: check-docs +check-docs: ## Run the script to ensure that the docs are updated + ./hack/docs/check.sh + .PHONY: lint -lint: golangci-lint ## Run golangci-lint linter +lint: golangci-lint yamllint ## Run golangci-lint linter & yamllint $(GOLANGCI_LINT) run .PHONY: lint-fix lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes $(GOLANGCI_LINT) run --fix +.PHONY: yamllint +yamllint: + @docker run --rm $$(tty -s && echo "-it" || echo) -v $(PWD):/data cytopia/yamllint:latest testdata -d "{extends: relaxed, rules: {line-length: {max: 120}}}" --no-warnings + GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint golangci-lint: @[ -f $(GOLANGCI_LINT) ] || { \ set -e ;\ - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell dirname $(GOLANGCI_LINT)) v1.49.0 ;\ + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell dirname $(GOLANGCI_LINT)) v1.51.2 ;\ } .PHONY: apidiff @@ -92,7 +104,7 @@ apidiff: go-apidiff ## Run the go-apidiff to verify any API differences compared .PHONY: go-apidiff go-apidiff: - go install github.com/joelanford/go-apidiff@v0.4.0 + go install github.com/joelanford/go-apidiff@v0.5.0 ##@ Tests @@ -139,6 +151,8 @@ test-e2e-ci: ## Run the end-to-end tests (used in the CI)` .PHONY: test-book test-book: ## Run the cronjob tutorial's unit tests to make sure we don't break it cd ./docs/book/src/cronjob-tutorial/testdata/project && make test + cd ./docs/book/src/component-config-tutorial/testdata/project && make test + cd ./docs/book/src/multiversion-tutorial/testdata/project && make test .PHONY: test-license test-license: ## Run the license check diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 0d25ac98220..5e7e45ceda9 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -4,26 +4,27 @@ aliases: # active folks who can be contacted to perform admin-related # tasks on the repo, or otherwise approve any PRs. kubebuilder-admins: - - pwittrock - camilamacedo86 + - varshaprasad96 # non-admin folks who can approve any PRs in the repo kubebuilder-approvers: - - jmrodri - - varshaprasad96 # folks who can review and LGTM any PRs in the repo (doesn't include # approvers & admins -- those count too via the OWNERS file) kubebuilder-reviewers: - - joelanford - rashmigottipati - everettraven + - Kavinjsir # folks who may have context on ancient history, # but are no longer directly involved kubebuilder-emeritus-approvers: + - adirio - directxman12 - droot - - mengqiy - estroz - - adirio + - jmrodri + - joelanford + - mengqiy + - pwittrock diff --git a/README.md b/README.md index aad4f893766..e4321e5e62f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Unit tests](https://github.com/kubernetes-sigs/kubebuilder/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/kubernetes-sigs/kubebuilder/actions/workflows/unit-tests.yml) [![Go Report Card](https://goreportcard.com/badge/sigs.k8s.io/kubebuilder)](https://goreportcard.com/report/sigs.k8s.io/kubebuilder) [![Coverage Status](https://coveralls.io/repos/github/kubernetes-sigs/kubebuilder/badge.svg?branch=master)](https://coveralls.io/github/kubernetes-sigs/kubebuilder?branch=master) +[![Latest release](https://badgen.net/github/release/kubernetes-sigs/kubebuilder)](https://github.com/kubernetes-sigs/kubebuilder/lreleases) ## Kubebuilder @@ -126,16 +127,7 @@ supporting Windows are welcome. ### Apple Silicon -Apple Silicon (`darwin/arm64`) is supported using the `go/v4-alpha` plugin which provides support for this platform. - -```bash -kubebuilder init --domain my.domain --repo my.domain/guestbook --plugins=go/v4-alpha -``` - -**Note**: The `go/v4-alpha` plugin is an unstable version and can have breaking changes in future releases. The previous kustomize -version (`v3.Y.Z`) used in the `go/v3` has no available binaries for this -platform [kubernetes-sigs/kustomize/issues/4612](https://github.com/kubernetes-sigs/kustomize/issues/4612) -Because of this, we cannot support this `darwin/arm64` on the stable scaffold done by default with the Kubebuilder with the `go/v3` plugin. +Apple Silicon (`darwin/arm64`) support begins with the `go/v4` plugin. ## Community Meetings diff --git a/RELEASE.md b/RELEASE.md index c5c6fe00929..25912d01afb 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -7,7 +7,7 @@ to create a new branch. Instead, you will just need to ensure that all major fix `release-MAJOR.MINOR` branch. To know more about versioning check https://semver.org/. **Note:** Before `3.5.*` release this project was released based on `MAJOR`. A change to the -the process was done to ensure that we have an aligned process under the org (similar to `controller-runtime` and +process was done to ensure that we have an aligned process under the org (similar to `controller-runtime` and `controller-tools`) and to make it easier to produce patch releases. ## How to do a release @@ -50,28 +50,6 @@ For more info, see the release page: https://github.com/kubernetes-sigs/kubebuil 2. Announce the new release via email is sent to `kubebuilder@googlegroups.com` with the subject `[ANNOUNCE] Kubebuilder $VERSION is released` -## What to do if things goes wrong? How to release from my local env as a workaround? - -As a workaround we can release from locally by: - -PS.: _This workaround uses the google cloud. Note that we move the binary CLI release from google cloud to use Github Actions instead_ - -1. Download google container builder: https://github.com/GoogleCloudPlatform/cloud-build-local -2. Verify that you can use the cloud-build-local CLI tool -3. Ensure that you are locally in the branch created for the release (`release-`) -4. Ensure that it has no changes in the code source ( `git status`) -5. Create the directory `cloudbuild` (`mkdir cloudbuild`) -6. Then, update the file `build/cloudbuild_local.yaml` with: - -The following change is required for Goreleaser be able to add the binaries in the release page. - -```sh -env: ["SNAPSHOT=1","GITHUB_TOKEN=your github token with access in the repo"] -``` -**NOTE** You can create a token [here](https://github.com/settings/tokens/new). - -7. Then, update the file `build/build_kubebuilder.sh` to remove the flag `--snapshot` (Otherwise, the binaries will be built with snapshot git commit hash instead of the tag version) -8. Run the command to trigger the release `$ cloud-build-local --config=build/cloudbuild_local.yaml --dryrun=false --write-workspace=./cloudbuild .` ## HEAD releases @@ -86,13 +64,8 @@ The releases occur in an account in the Google Cloud (See [here](https://console ### To build the Kubebuilder CLI binaries: -A trigger `build-kb-release` is configured to call [build/cloudbuild.yaml](build/cloudbuild.yaml). -This trigger will be executed when any new tag be published. -The tags must be built from the release branch (Currently, `release-3`). - -Also, we have a trigger to generate snapshots builds from the master branch. -This trigger will call [build/cloudbuild_snapshot.yaml](build/cloudbuild_snapshot.yaml) -when any change needs to be performed on master. +A trigger GitHub action [release](.github/workflows/release.yml) is trigged when a new tag is pushed. +This action will caall the job [./build/.goreleaser.yml](./build/.goreleaser.yml). ### To build the Kubebuilder-tools: (Artifacts required to use ENV TEST) @@ -146,4 +119,4 @@ However, the image should still be built and maintained since other projects und [kubebuilder-release-tools]: https://github.com/kubernetes-sigs/kubebuilder-release-tools [release-notes-generation]: https://github.com/kubernetes-sigs/kubebuilder-release-tools/blob/master/README.md#release-notes-generation -[release-process]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/VERSIONING.md#releasing \ No newline at end of file +[release-process]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/VERSIONING.md#releasing diff --git a/WORKSPACE b/WORKSPACE deleted file mode 100644 index 10ef0117cb9..00000000000 --- a/WORKSPACE +++ /dev/null @@ -1,12 +0,0 @@ -http_archive( - name = "io_bazel_rules_go", - url = "https://github.com/bazelbuild/rules_go/releases/download/0.9.0/rules_go-0.9.0.tar.gz", - sha256 = "4d8d6244320dd751590f9100cf39fd7a4b75cd901e1f3ffdfd6f048328883695", -) -load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains") -go_rules_dependencies() -go_register_toolchains() - -load("@io_bazel_rules_go//proto:def.bzl", "proto_register_toolchains") -proto_register_toolchains() - diff --git a/build/.goreleaser.yml b/build/.goreleaser.yml index e08fa0806a3..71f948e7e5e 100644 --- a/build/.goreleaser.yml +++ b/build/.goreleaser.yml @@ -44,7 +44,7 @@ builds: - darwin_amd64 - darwin_arm64 env: - - KUBERNETES_VERSION=1.24.1 + - KUBERNETES_VERSION=1.27.1 - CGO_ENABLED=0 # Only binaries of the form "kubebuilder_${goos}_${goarch}" will be released. diff --git a/build/build_kubebuilder.sh b/build/build_kubebuilder.sh deleted file mode 100755 index 6569396b865..00000000000 --- a/build/build_kubebuilder.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2018 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script runs goreleaser using the build/.goreleaser.yml config. -# While it can be run locally, it is intended to be run by cloudbuild -# in the goreleaser/goreleaser image. - -function usage() { - echo " - This script runs goreleaser using the build/.goreleaser.yml config. - While it can be run locally, it is intended to be run by cloudbuild - in the goreleaser/goreleaser image. - - GORELEASER_FLAGS: contains flags to pass to the goreleaser binary (default: only --config is set). - - SNAPSHOT: if set to any value, runs goreleaser in snapshot mode with mock release notes (default: unset). - - NOTES_FLAGS: contains flags to pass to the notes binary (sigs.k8s.io/kubebuilder-release-tools/notes). - Does nothing if SNAPSHOT is set. (default: unset). - - Examples: - - # Run in snapshot mode: fake release notes, nothing is published, binaries build in '$(pwd)/dist' - \$ SNAPSHOT=1 $0 - - # Add a release type to the release notes - \$ NOTES_FLAGS=\"-r beta\" $0 -" -} - -# GORELEASER_FLAGS contains flags for goreleaser such that the binary can be run -# in local/snapshot/prod mode from the same script. -# NOTE: if --snapshot is in GORELEASER_FLAGS, the release is not published to GitHub -# and the build is available under $PWD/dist. -GORELEASER_FLAGS="${GORELEASER_FLAGS:-}" -# NOTES_FLAGS contains flags for the release notes generator (see install_notes for details). -NOTES_FLAGS="${NOTES_FLAGS:-}" -# SNAPSHOT is set by the CLI flag parser if --snapshot is a passed flag. -# If not set, release notes are not generated. -SNAPSHOT="${SNAPSHOT:-}" - -while [ $# -gt 0 ]; do - case $1 in - -h|--help) - usage - exit 0 - ;; - esac -done - - -# install_notes installs kubebuilder's release notes generator globally with name "notes". -function install_notes() { - local tmp=$(mktemp -d) - pushd "$tmp" - go mod init tmp - # Get by commit because v0.1.1 cannot be retrieved via `go get`. - go get sigs.k8s.io/kubebuilder-release-tools/notes@4777888c377a26956f1831d5b9207eea1fa3bf29 - popd - rm -rf "$tmp" -} - -set -o errexit -set -o pipefail - -# Generate real release notes. -if [ -z "$SNAPSHOT" ]; then - tmp_notes="$(mktemp)" - trap "rm -f ${tmp_notes}" EXIT - install_notes - if [[ -n "${CLOUD_BUILD}" ]]; then - # we refresh just before this, no point (plus, we fiddle with the current branch a bit) - NOTES_FLAGS+=" --use-upstream=false" - # we can look for tag alpha/beta here too - # (TODO(directxman12): this should be in the tool) - [[ "${TAG_NAME}" == "v"*"-alpha."* ]] && NOTES_FLAGS+=" -r alpha" - [[ "${TAG_NAME}" == "v"*"-beta."* ]] && NOTES_FLAGS+=" -r beta" - [[ "${TAG_NAME}" == "v"*"-rc."* ]] && NOTES_FLAGS+=" -r rc" - fi - # TODO(cmacedo): figure out how to download the release notes and let it available in the cloud build - # Currently it does not work: https://github.com/kubernetes-sigs/kubebuilder/issues/2667 - # notes $NOTES_FLAGS | tee "$tmp_notes" - notes="Mock Release Notes for $(git describe --tags --always --broken)" - # we need to delete the tag for the release notes script, so restore it when done so that - # go releaser can find the right tag - if [[ -n "${TAG_NAME}" ]]; then - git tag ${TAG_NAME} - fi - GORELEASER_FLAGS="${GORELEASER_FLAGS} --release-notes=${tmp_notes}" -else - # TODO(estroz): figure out how to generate snapshot release notes with the kubebuilder generator. - echo "Running in snapshot mode. Release notes will not be generated from commits." - notes="Mock Release Notes for $(git describe --tags --always --broken)" - GORELEASER_FLAGS="${GORELEASER_FLAGS} --snapshot --rm-dist --skip-validate --release-notes <(echo \"${notes}\")" -fi - -# eval to run process substitution. -eval goreleaser release --config=build/.goreleaser.yml $GORELEASER_FLAGS diff --git a/build/cloudbuild.yaml b/build/cloudbuild.yaml deleted file mode 100644 index 70c62748c40..00000000000 --- a/build/cloudbuild.yaml +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2018 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Instructions to run locally: -# Download google container builder: https://github.com/GoogleCloudPlatform/cloud-build-local -# $ mkdir cloudbuild -# $ cloud-build-local --config=build/cloudbuild_local.yaml --dryrun=false --write-workspace=./cloudbuild . -# Release tar will be in ./cloudbuild - -steps: -- name: "gcr.io/cloud-builders/git" - entrypoint: 'bash' - args: - - '-c' - - | - git fetch --tags --unshallow - git for-each-ref --contains HEAD - # TAG_NAME is defined by GCB, so uses 1 dollar sign, BRANCH_NAME is bash, so we need to escape it - # with two dollar signs - export BRANCH_NAME=$(git for-each-ref --format="%(refname:strip=-1)" --contains HEAD 'refs/remotes/origin/release-*') - export ALL_BRANCHES=$(git for-each-ref --format="%(refname:strip=-1)" 'refs/remotes/origin/release-*') - echo "branch: $${BRANCH_NAME}, tag: ${TAG_NAME}, all release branches: $${ALL_BRANCHES}" - for branch in $${ALL_BRANCHES}; do - git branch $${branch} origin/$${branch} - done - git branch -f $${BRANCH_NAME} HEAD - git checkout $${BRANCH_NAME} - git branch --set-upstream-to=origin/$${BRANCH_NAME} - git tag -d ${TAG_NAME} -- name: "goreleaser/goreleaser:v1.11.2" - entrypoint: "bash" - args: ["build/build_kubebuilder.sh"] - env: - - 'TAG_NAME=$TAG_NAME' - - 'CLOUD_BUILD=true' - - 'GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}' \ No newline at end of file diff --git a/build/cloudbuild_local.yaml b/build/cloudbuild_local.yaml deleted file mode 100644 index ed97f90aa34..00000000000 --- a/build/cloudbuild_local.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2018 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Instructions to run locally: -# Download google container builder: https://github.com/GoogleCloudPlatform/cloud-build-local -# $ mkdir cloudbuild -# $ cloud-build-local --config=build/cloudbuild_local.yaml --dryrun=false --write-workspace=./cloudbuild . -# Release tar will be in ./cloudbuild - -steps: -- name: "goreleaser/goreleaser:v1.11.2" - entrypoint: "bash" - env: ["SNAPSHOT=1"] - args: ["build/build_kubebuilder.sh"] diff --git a/build/cloudbuild_snapshot.yaml b/build/cloudbuild_snapshot.yaml deleted file mode 100644 index 9eaf2d4ffc4..00000000000 --- a/build/cloudbuild_snapshot.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2018 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Instructions to run locally: -# Download google container builder: https://github.com/GoogleCloudPlatform/cloud-build-local -# $ mkdir cloudbuild -# $ cloud-build-local --config=build/cloudbuild_snapshot.yaml --dryrun=false --write-workspace=./cloudbuild . -# Release tar will be in ./cloudbuild - -steps: -- name: "goreleaser/goreleaser:v1.11.2" - entrypoint: "bash" - env: ["SNAPSHOT=1"] - args: ["build/build_kubebuilder.sh"] - timeout: 30m -- name: "ubuntu" - args: ["tar", "-zcvf", "kubebuilder_linux_amd64.tar.gz", "-C", "dist/kubebuilder_linux_amd64_v1", "kubebuilder"] -- name: "gcr.io/cloud-builders/gsutil" - args: ["-h", "Content-Type:application/gzip", "cp", "kubebuilder_linux_amd64.tar.gz", "gs://kubebuilder-release/kubebuilder_master_linux_amd64.tar.gz"] -- name: "ubuntu" - args: ["tar", "-zcvf", "kubebuilder_linux_arm64.tar.gz", "-C", "dist/kubebuilder_linux_arm64", "kubebuilder"] -- name: "gcr.io/cloud-builders/gsutil" - args: ["-h", "Content-Type:application/gzip", "cp", "kubebuilder_linux_arm64.tar.gz", "gs://kubebuilder-release/kubebuilder_master_linux_arm64.tar.gz"] -- name: "ubuntu" - args: ["tar", "-zcvf", "kubebuilder_linux_ppc64le.tar.gz", "-C", "dist/kubebuilder_linux_ppc64le", "kubebuilder"] -- name: "gcr.io/cloud-builders/gsutil" - args: ["-h", "Content-Type:application/gzip", "cp", "kubebuilder_linux_ppc64le.tar.gz", "gs://kubebuilder-release/kubebuilder_master_linux_ppc64le.tar.gz"] -- name: "ubuntu" - args: ["tar", "-zcvf", "kubebuilder_darwin_amd64.tar.gz", "-C", "dist/kubebuilder_darwin_amd64_v1", "kubebuilder"] -- name: "gcr.io/cloud-builders/gsutil" - args: ["-h", "Content-Type:application/gzip", "cp", "kubebuilder_darwin_amd64.tar.gz", "gs://kubebuilder-release/kubebuilder_master_darwin_amd64.tar.gz"] -- name: "ubuntu" - args: ["tar", "-zcvf", "kubebuilder_darwin_arm64.tar.gz", "-C", "dist/kubebuilder_darwin_arm64", "kubebuilder"] -- name: "gcr.io/cloud-builders/gsutil" - args: ["-h", "Content-Type:application/gzip", "cp", "kubebuilder_darwin_arm64.tar.gz", "gs://kubebuilder-release/kubebuilder_master_darwin_arm64.tar.gz"] - - diff --git a/cmd/main.go b/cmd/main.go index 7dc5d59d92e..7f59bb26161 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -25,29 +25,37 @@ import ( cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2" cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3" "sigs.k8s.io/kubebuilder/v3/pkg/machinery" - "sigs.k8s.io/kubebuilder/v3/pkg/model/stage" "sigs.k8s.io/kubebuilder/v3/pkg/plugin" kustomizecommonv1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v1" - kustomizecommonv2alpha "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2-alpha" + kustomizecommonv2alpha "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2" "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang" declarativev1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/declarative/v1" deployimagev1alpha1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/deploy-image/v1alpha1" golangv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2" golangv3 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3" + golangv4 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v4" grafanav1alpha1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/optional/grafana/v1alpha" ) func main() { + const deprecateMessageGoV3Bundle = "This version is deprecated." + + "The `go/v3` cannot scaffold projects using kustomize versions v4x+" + + " and cannot fully support Kubernetes 1.25+." + + "It is recommended to upgrade your project to the latest versions available (go/v4)." + + "Please, check the migration guide to learn how to upgrade your project" + // Bundle plugin which built the golang projects scaffold by Kubebuilder go/v3 - gov3Bundle, _ := plugin.NewBundle(golang.DefaultNameQualifier, plugin.Version{Number: 3}, - kustomizecommonv1.Plugin{}, - golangv3.Plugin{}, + gov3Bundle, _ := plugin.NewBundleWithOptions(plugin.WithName(golang.DefaultNameQualifier), + plugin.WithVersion(plugin.Version{Number: 3}), + plugin.WithDeprecationMessage(deprecateMessageGoV3Bundle), + plugin.WithPlugins(kustomizecommonv1.Plugin{}, golangv3.Plugin{}), ) - // Bundle plugin which built the golang projects scaffold by Kubebuilder go/v3 with kustomize alpha-v2 - gov4Bundle, _ := plugin.NewBundle(golang.DefaultNameQualifier, plugin.Version{Number: 4, Stage: stage.Alpha}, - kustomizecommonv2alpha.Plugin{}, - golangv3.Plugin{}, + + // Bundle plugin which built the golang projects scaffold by Kubebuilder go/v4 with kustomize alpha-v2 + gov4Bundle, _ := plugin.NewBundleWithOptions(plugin.WithName(golang.DefaultNameQualifier), + plugin.WithVersion(plugin.Version{Number: 4}), + plugin.WithPlugins(kustomizecommonv2alpha.Plugin{}, golangv4.Plugin{}), ) fs := machinery.Filesystem{ @@ -64,6 +72,7 @@ func main() { cli.WithPlugins( golangv2.Plugin{}, golangv3.Plugin{}, + golangv4.Plugin{}, gov3Bundle, gov4Bundle, &kustomizecommonv1.Plugin{}, @@ -74,7 +83,7 @@ func main() { ), cli.WithPlugins(externalPlugins...), cli.WithDefaultPlugins(cfgv2.Version, golangv2.Plugin{}), - cli.WithDefaultPlugins(cfgv3.Version, gov3Bundle), + cli.WithDefaultPlugins(cfgv3.Version, gov4Bundle), cli.WithDefaultProjectVersion(cfgv3.Version), cli.WithCompletion(), ) diff --git a/designs/code-generate-image-plugin.md b/designs/code-generate-image-plugin.md index a2cafabc65c..719eba97eac 100644 --- a/designs/code-generate-image-plugin.md +++ b/designs/code-generate-image-plugin.md @@ -1,15 +1,6 @@ ---- -title: Neat-Enhancement-Idea -authors: - - "@camilamacedo86" -reviewers: - - TBD -approvers: - - TBD -creation-date: 2020-11-09 -last-updated: 2021-02-14 -status: implementable ---- +| Authors | Creation Date | Status | Extra | +|---------------|---------------|-------------|---| +| @camilamacedo86 | 2021-02-14 | Implemented | [deploy-image-plugin-v1-alpha](https://book.kubebuilder.io/plugins/deploy-image-plugin-v1-alpha.html) | # New Plugin (`deploy-image.go.kubebuilder.io/v1beta1`) to generate code diff --git a/designs/crd_version_conversion.md b/designs/crd_version_conversion.md index 3bb0d748550..e5358a0460d 100644 --- a/designs/crd_version_conversion.md +++ b/designs/crd_version_conversion.md @@ -1,7 +1,8 @@ -# API Versioning in Kubebuilder +| Authors | Creation Date | Status | Extra | +|---------------|---------------|-------------|-------| +| @droot | 01/30/2019| implementable | - | -Authors: @droot -Last Updated on: 01/30/2019 +# API Versioning in Kubebuilder This document describes high level design and workflow for supporting multiple versions in an API built using Kubebuilder. Multi-version support was added as an alpha feature in kubernetes project in 1.13 release. Here are links to some recommended reading material. diff --git a/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md b/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md index e96e9a0f649..463cecf3848 100644 --- a/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md +++ b/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md @@ -1,3 +1,7 @@ +| Authors | Creation Date | Status | Extra | +|---------------|---------------|-------------|-----------------------------------------------------------------| +| @adirio | Mar 9, 2021 | Implemented | [Plugins doc](https://book.kubebuilder.io/plugins/plugins.html) | + # Extensible CLI and Scaffolding Plugins - Phase 1.5 Continuation of [Extensible CLI and Scaffolding Plugins](./extensible-cli-and-scaffolding-plugins-phase-1.md). diff --git a/designs/extensible-cli-and-scaffolding-plugins-phase-1.md b/designs/extensible-cli-and-scaffolding-plugins-phase-1.md index 0e9d75c6c9d..0b1f679a3cf 100644 --- a/designs/extensible-cli-and-scaffolding-plugins-phase-1.md +++ b/designs/extensible-cli-and-scaffolding-plugins-phase-1.md @@ -1,3 +1,8 @@ + +| Authors | Creation Date | Status | Extra | +|---------------|---------------|-------------|-----------------------------------------------------------------| +| @estroz,@joelanford | Dec 10, 2019 | Implemented | [Plugins doc](https://book.kubebuilder.io/plugins/plugins.html) | + # Extensible CLI and Scaffolding Plugins ## Overview diff --git a/designs/extensible-cli-and-scaffolding-plugins-phase-2.md b/designs/extensible-cli-and-scaffolding-plugins-phase-2.md index 249d30d6171..13da9089211 100644 --- a/designs/extensible-cli-and-scaffolding-plugins-phase-2.md +++ b/designs/extensible-cli-and-scaffolding-plugins-phase-2.md @@ -1,3 +1,7 @@ +| Authors | Creation Date | Status | Extra | +|---------------|---------------|-------------|-----------------------------------------------------------------| +| @rashmigottipati | Mar 9, 2021 | partial implemented | [Plugins doc](https://book.kubebuilder.io/plugins/plugins.html) | + # Extensible CLI and Scaffolding Plugins - Phase 2 ## Overview @@ -134,7 +138,7 @@ plugins: - domain: testproject.org group: crew kind: Captain - version: v2-alpha + version: v2 declarative.go.kubebuilder.io/v1: resources: - domain: testproject.org @@ -173,7 +177,7 @@ The following scenarios shows what `kubebuilder` will send/receive to the extern * External plugin to `kubebuilder`: * The plugin reads the `PluginRequest` through its `stdin` and processes the request based on the `Command` that was sent. If the `Command` doesn't match what the plugin supports, it writes back an error immediately without any further processing. If the `Command` matches what the plugin supports, it constructs a `PluginResponse` containing the `Command` that was executed by the plugin, and modified `Universe` based on the new files that were scaffolded by the external plugin, `Error` and `ErrorMsg` that add any error information, and writes the `PluginResponse` back to `kubebuilder` through `stdout`. -* Note: If `--help` flag is being passed from `kubebuilder` to the external plugin through `PluginRequest`, the plugin attaches its help text information in the `Help` field of the `PluginResponse`. Both `PluginRequest` and `PluginResponse` also contain `APIVersion` field to have compatible versioned schemas. +* Note: If `--help` flag is being passed from `kubebuilder` to the external plugin through `PluginRequest`, the plugin attaches its help text information in the `Metadata` field of the `PluginResponse`. Both `PluginRequest` and `PluginResponse` also contain `APIVersion` field to have compatible versioned schemas. * Handling plugin failures across the chain: @@ -208,9 +212,9 @@ type PluginResponse struct { // Command holds the command that gets executed by the plugin such as init, create api, etc. Command string `json:"command"` - // Help contains the plugin specific help text that the plugin returns to kubebuilder when it receives + // Metadata contains the plugin specific help text that the plugin returns to Kubebuilder when it receives // `--help` flag from Kubebuilder. - Help string `json:"help,omitempty"` + Metadata plugin.SubcommandMetadata `json:"metadata"` // APIVersion defines the versioned schema of the PluginResponse that will be written back to kubebuilder. // Initially, this will be marked as alpha (v1alpha1). diff --git a/designs/helper_to_upgrade_projects_by_rescaffolding.md b/designs/helper_to_upgrade_projects_by_rescaffolding.md new file mode 100644 index 00000000000..3ec6c329e5b --- /dev/null +++ b/designs/helper_to_upgrade_projects_by_rescaffolding.md @@ -0,0 +1,212 @@ +| Authors | Creation Date | Status | Extra | +|------------------------------------|---------------|-------------|---| +| @camilamacedo86,@Kavinjsir,@varshaprasad96 | Feb, 2023 | Implementable | - | + +Experimental Helper to upgrade projects by re-scaffolding +=================== + +This proposal aims to provide a new alpha command with a helper which +would be able to re-scaffold the project from the scratch based on +the [PROJECT config][project-config]. + +## Example + +By running a command like following, users would be able to re-scaffold the whole project from the scratch using the +current version of KubeBuilder binary available. + +```shell +kubebuilder alpha generate [OPTIONS] +``` + +### Workflows + +Following some examples of the workflows + +**To update the project with minor changes provided** + +See that for each KubeBuilder release the plugins versions used to scaffold +the projects might have bug fixes and new incremental features added to the +templates which will result in changes to the files that are generated by +the tool for new projects. + +In this case, you used previously the tool to generate the project +and now would like to update your project with the latest changes +provided for the same plugin version. Therefore, you will need to: + +- Download and install KubeBuilder binary ( latest / upper release ) +- You will run the command in the root directory of your project: `kubebuilder alpha generate` +- Then, the command will remove the content of your local directory and re-scaffold the project from the scratch +- It will allow you to compare your local branch with the remote branch of your project to re-add the code on top OR + if you do not use the flag `--no-backup` then you can compare the local directory with the copy of your project + copied to the path `.backup/project-name/` before the re-scaffold be done. +- Therefore, you can run make all and test the final result. You will have after all your project updated. + +**To update the project with major changes provided** + +In this case, you are looking for to migrate the project from, for example, +`go/v3` to `go/v4`. The steps are very similar to the above ones. However, +in this case you need to inform the plugin that you want to use to do the scaffold +from scratch `kubebuilder alpha generate --plugins=go/v4`. + +## Open Questions + +N/A + +## Summary + +Therefore, a new command can be designed to load user configs from the [PROJECT config][project-config] file, and run the corresponding kubebuilder subcommands to generate the project based on the new kubebuilder version. Thus, it makes it easier for the users to migrate their operator projects to the new scaffolding. + +## Motivation + +A common scenario is to upgrade the project based on the newer Kubebuilder. The recommended (straightforward) steps are: + +- a) re-scaffold all files from scratch using the upper version/plugins +- b) copy user-defined source code to the new layout + +The proposed command will automate the process at maximum, therefore helping operator authors with minimizing the manual effort. + +The main motivation of this proposal is to provide a helper for upgrades and +make less painful this process. Examples: + +- See the discussion [How to regenerate scaffolding?](https://github.com/kubernetes-sigs/kubebuilder/discussions/2864) +- From [slack channel By Paul Laffitte](https://kubernetes.slack.com/archives/CAR30FCJZ/p1675166014762669) + +### Goals + +- Help users upgrade their project with the latest changes +- Help users to re-scaffold projects from scratch based on what was done previously with the tool +- Make less painful the process to upgrade + +### Non-Goals + +- Change the default layout or how the KubeBuilder CLI works +- Deal with customizations or deviations from the proposed layout +- Be able to perform the project upgrade to the latest changes without human interactions +- Deal and support external plugins +- Provides support to [declarative](https://book.kubebuilder.io/plugins/declarative-v1.html) plugin + since it is desired and planned to decouple this solution and donate this plugin to its own authors [More info](https://github.com/kubernetes-sigs/kubebuilder/issues/3186) +- Provide support to older version before having the Project config (Kubebuilder < 3x) and the go/v2 layout which exists to ensure a backwards compatibility with legacy layout provided by Kubebuilder 2x + +## Proposal + +The proposed solution to achieve this goal is to create an alpha command as described +in the example section above, see: + +```shell +kubebuilder alpha generate \ + --input-dir= + --output-dir= + --no-backup + --backup-path= + --plugins= +``` + +**Where**: + +- input-dir: [Optional] If not informed, then, by default, it is the current directory (project directory). If the `PROJECT` file does not exist, it will fail. +- output-dir: [Optional] If not informed then, it should be the current repository. +- no-backup: [Optional] If not informed then, the current directory should be copied to the path `.backup/project-name` +- backup: [Optional] If not informed then, the backup will be copied to the path `.backup/project-name` +- plugins: [Optional] If not informed then, it is the same plugin chain available in the layout field +- binary: [Optional] If not informed then, the command will use KubeBuilder binary installed globaly. + +> Note that the backup created in the current directory must be prefixed with `.`. Otherwise the tool +will not able to perform the scaffold to create a new project from the scratch. + +This command would mainly perform the following operations: + +- 1. Check the flags +- 2. If the backup flag be used, then check if is a valid path and make a backup of the current project +- 3. Copy the whole current directory to `.backup/project-name` +- 4. Ensure that the output path is clean. By default it is the current directory project where the project was scaffolded previously and it should be cleaned up before to do the re-scaffold. +Only the content under `.backup/project-name` should be kept. +- 4. Read the [PROJECT config][project-config] +- 5. Re-run all commands using the KubeBuilder binary to recreate the project in the output directory + +The command should also provide a comprensive help with examples of the proposed workflows. So that, users +are able to understand how to use it when run `--help`. + +### User Stories + +**As an Operator author:** + +- I can re-generate my project from scratch based on the proposed helper, which executes all the +commands according to my previous input to the project. That way, I can easily migrate my project to the new layout +using the newer CLI/plugin versions, which support the latest changes, bug fixes, and features. +- I can regenerate my project from the scratch based on all commands that I used the tool to build +my project previously but informing a new init plugin chain, so that I could upgrade my current project to new +layout versions and experiment alpha ones. +- I would like to re-generate the project from the scratch using the same config provide in the PROJECT file and inform +a path to do a backup of my current directory so that I can also use the backup to compare with the new scaffold and add my custom code +on top again without the need to compare my local directory and new scaffold with any outside source. + +**As a Kubebuiler maintainer:** + +- I can leverage this helper to easily migrate tutorial projects of the Kubebuilder book. +- I can leverage on this helper to encourage its users to migrate to upper versions more often, making it easier to maintain the project. + +### Implementation Details/Notes/Constraints + +Note that in the [e2e tests](https://github.com/kubernetes-sigs/kubebuilder/tree/master/test/e2e) the binary is used to do the scaffolds. +Also, very similar to the implementation that exist in the integration test KubeBuilder has +a code implementation to re-generate the samples used in the docs and add customizations on top, +for further information check the [hack/docs](https://github.com/kubernetes-sigs/kubebuilder/tree/master/hack/docs). + +This subcommand could have a similar implementation that could be used by the tests and this plugin. +Note that to run the commands using the binaries we are mainly using the following golang implementation: + +```go +cmd := exec.Command(t.BinaryName, Options) +_, err := t.Run(cmd) +``` + +### Risks and Mitigations + +**Hard to keep the command maintained** + +A risk to consider is that it would be hard to keep this command maintained +because we need to develop specific code operations for each plugin. The mitigation for +this problem could be developing a design more generic that could work with all plugins. + +However, initially a more generic design implementation does not appear to be achievable and +would be considered out of the scope of this proposal (no goal). It should to be considered +as a second phase of this implementation. + +Therefore, the current achievable mitigation in place is that KubeBuilder's policy of not providing official +support of maintaining and distributing many plugins. + +### Proof of Concept + +All input data is tracked. Also, as described above we have examples of code implementation +that uses the binary to scaffold the projects. Therefore, the goal of this project seems +very reasonable and achievable. An initial work to try to address this requirement can +be checked in this [pull request](https://github.com/kubernetes-sigs/kubebuilder/pull/3022) + +## Drawbacks + +- If the value that feature provides does not pay off the effort to keep it + maintained, then we would need to deprecate and remove the feature in the long term. + +## Alternatives + +N/A + +## Implementation History + +The idea of automate the re-scaffold of the project is what motivates +us track all input data in to the [project config][project-config] +in the past. We also tracked the [issue](https://github.com/kubernetes-sigs/kubebuilder/issues/2068) +based on discussion that we have to indeed try to add further +specific implementations to do operations per major bumps. For example: + +To upgrade from go/v3 to go/v4 we know exactly what are the changes in the layout +then, we could automate these specific operations as well. However, this first idea is harder yet +to be addressed and maintained. + +## Future Vision + +We could use it to do cool future features such as creating a GitHub action which would push-pull requests against the project repositories to help users be updated with, for example, minor changes. By using this command, we might able to git clone the project and to do a new scaffold and then use some [git strategy merge](https://www.geeksforgeeks.org/merge-strategies-in-git/) to result in a PR to purpose the required changes. + +We probably need to store the CLI tool tag release used to do the scaffold to persuade this idea. So that we can know if the project requires updates or not. + +[project-config]: https://book.kubebuilder.io/reference/project-config.html diff --git a/designs/integrating-kubebuilder-and-osdk.md b/designs/integrating-kubebuilder-and-osdk.md index 24de989be0d..df4ec362cc8 100644 --- a/designs/integrating-kubebuilder-and-osdk.md +++ b/designs/integrating-kubebuilder-and-osdk.md @@ -1,3 +1,7 @@ +| Authors | Creation Date | Status | Extra | +|---------------|---------------|-------------|-------| +| @joelanford | Sep 6, 2019 | implemented | - | + Integrating Kubebuilder and Operator SDK ======================================== diff --git a/designs/simplified-scaffolding.md b/designs/simplified-scaffolding.md index 01eae04d417..bdbacaa8d8f 100644 --- a/designs/simplified-scaffolding.md +++ b/designs/simplified-scaffolding.md @@ -1,3 +1,7 @@ +| Authors | Creation Date | Status | Extra | +|---------------|---------------|-------------|---| +| @DirectXMan12 | Mar 6, 2019 | Implemented | - | + Simplified Builder-Based Scaffolding ==================================== diff --git a/designs/template.md b/designs/template.md index 0dea375b4a6..52ae3ddab85 100644 --- a/designs/template.md +++ b/designs/template.md @@ -1,4 +1,8 @@ -Title of the Design +| Authors | Creation Date | Status | Extra | +|---------------|---------------|-------------|---| +| @name | date | Implementeble | - | + +Title of the Design/Proposal =================== + +## Open Questions [optional] + + + +## Summary + + + +## Motivation + + + +### Goals + + + +### Non-Goals + + + +## Proposal + + + +### User Stories + + + +### Implementation Details/Notes/Constraints [optional] + + + +### Risks and Mitigations + + + +### Proof of Concept [optional] + + + +## Drawbacks + + + +## Alternatives + + diff --git a/docs/README.md b/docs/README.md index e6b1dd79ca5..63c3996b1a5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,10 +3,11 @@ The kubebuilder book is served using [mdBook](https://github.com/rust-lang-nursery/mdBook). If you want to test changes to the book locally, follow these directions: 1. Follow the instructions at [https://github.com/rust-lang-nursery/mdBook#installation](https://github.com/rust-lang-nursery/mdBook#installation) to - install mdBook. -1. cd into the `docs/book` directory -1. Run `mdbook serve` -1. Visit [http://localhost:3000](http://localhost:3000) + install mdBook. +2. Make sure [controller-gen](https://pkg.go.dev/sigs.k8s.io/controller-tools/cmd/controller-gen) is install in `$GOPATH`. +3. cd into the `docs/book` directory +4. Run `mdbook serve` +5. Visit [http://localhost:3000](http://localhost:3000) # Steps to deploy diff --git a/docs/book/book.toml b/docs/book/book.toml index 7aadb547fc5..c6244a05df3 100644 --- a/docs/book/book.toml +++ b/docs/book/book.toml @@ -7,7 +7,9 @@ title = "The Kubebuilder Book" [output.html] google-analytics = "UA-119864590-1" curly-quotes = true -additional-css = ["theme/css/markers.css", "theme/css/custom.css"] +additional-css = ["theme/css/markers.css", "theme/css/custom.css", "theme/css/version-dropdown.css"] +git-repository-url = "https://github.com/kubernetes-sigs/kubebuilder" +edit-url-template = "https://github.com/kubernetes-sigs/kubebuilder/edit/master/docs/book/{path}" [preprocessor.literatego] command = "./litgo.sh" diff --git a/docs/book/install-and-build.sh b/docs/book/install-and-build.sh index 0e145825d64..1d6fc263592 100755 --- a/docs/book/install-and-build.sh +++ b/docs/book/install-and-build.sh @@ -60,14 +60,14 @@ 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.2-${arch}-${target}.${ext}" +echo "downloading mdBook-v0.4.21-${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} ${cmd} /tmp/mdbook.${ext} chmod +x /tmp/mdbook echo "grabbing the latest released controller-gen" -go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0 +go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.12.0 # make sure we add the go bin directory to our path gobin=$(go env GOBIN) diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index 105cca3c0d2..40773b5e525 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -16,7 +16,7 @@ - [Adding a new API](./cronjob-tutorial/new-api.md) - [Designing an API](./cronjob-tutorial/api-design.md) - - [A Brief Aside: What's the rest of this stuff?](./cronjob-tutorial/other-api-files.md) + - [A Brief Aside: What's the rest of this stuff?](./cronjob-tutorial/other-api-files.md) - [What's in a controller?](./cronjob-tutorial/controller-overview.md) - [Implementing a controller](./cronjob-tutorial/controller-implementation.md) @@ -26,7 +26,7 @@ - [Implementing defaulting/validating webhooks](./cronjob-tutorial/webhook-implementation.md) - [Running and deploying the controller](./cronjob-tutorial/running.md) - - [Deploying the cert manager](./cronjob-tutorial/cert-manager.md) + - [Deploying cert-manager](./cronjob-tutorial/cert-manager.md) - [Deploying webhooks](./cronjob-tutorial/running-webhook.md) - [Writing tests](./cronjob-tutorial/writing-tests.md) @@ -39,7 +39,7 @@ - [Hubs, spokes, and other wheel metaphors](./multiversion-tutorial/conversion-concepts.md) - [Implementing conversion](./multiversion-tutorial/conversion.md) - - [and setting up the webhooks](./multiversion-tutorial/webhooks.md) + - [and setting up the webhooks](./multiversion-tutorial/webhooks.md) - [Deployment and Testing](./multiversion-tutorial/deployment.md) @@ -50,21 +50,28 @@ - [Using a custom type](./component-config-tutorial/custom-type.md) - - [Adding a new Config Type](./component-config-tutorial/config-type.md) - - [Updating main](./component-config-tutorial/updating-main.md) - - [Defining your Custom Config](./component-config-tutorial/define-custom-config.md) + - [Adding a new Config Type](./component-config-tutorial/config-type.md) + - [Updating main](./component-config-tutorial/updating-main.md) + - [Defining your Custom Config](./component-config-tutorial/define-custom-config.md) + --- - [Migrations](./migrations.md) - - [Kubebuilder v1 vs v2](./migration/v1vsv2.md) + - [Legacy (before <= v3.0.0)](./migration/legacy.md) + - [Kubebuilder v1 vs v2](migration/legacy/v1vsv2.md) - [Migration Guide](./migration/legacy/migration_guide_v1tov2.md) - - [Kubebuilder v2 vs v3](./migration/v2vsv3.md) - - [Migration Guide](./migration/migration_guide_v2tov3.md) - - [Migration by updating the files](./migration/manually_migration_guide_v2_v3.md) + - [Kubebuilder v2 vs v3](migration/legacy/v2vsv3.md) + - [Migration Guide](migration/legacy/migration_guide_v2tov3.md) + - [Migration by updating the files](migration/legacy/manually_migration_guide_v2_v3.md) + - [From v3.0.0 with plugins](./migration/v3-plugins.md) + - [go/v3 vs go/v4](migration/v3vsv4.md) + + - [Migration Guide](migration/migration_guide_gov3_to_gov4.md) + - [Migration by updating the files](migration/manually_migration_guide_gov3_to_gov4.md) - [Single Group to Multi-Group](./migration/multi-group.md) --- @@ -73,6 +80,7 @@ - [Generating CRDs](./reference/generating-crd.md) - [Using Finalizers](./reference/using-finalizers.md) + - [Raising Events](./reference/raising-events.md) - [Watching Resources](./reference/watching-resources.md) - [Resources Managed by the Operator](./reference/watching-resources/operator-managed.md) - [Externally Managed Resources](./reference/watching-resources/externally-managed.md) @@ -82,22 +90,22 @@ - [Webhooks for Core Types](reference/webhook-for-core-types.md) - [Markers for Config/Code Generation](./reference/markers.md) - - [CRD Generation](./reference/markers/crd.md) - - [CRD Validation](./reference/markers/crd-validation.md) - - [CRD Processing](./reference/markers/crd-processing.md) - - [Webhook](./reference/markers/webhook.md) - - [Object/DeepCopy](./reference/markers/object.md) - - [RBAC](./reference/markers/rbac.md) + - [CRD Generation](./reference/markers/crd.md) + - [CRD Validation](./reference/markers/crd-validation.md) + - [CRD Processing](./reference/markers/crd-processing.md) + - [Webhook](./reference/markers/webhook.md) + - [Object/DeepCopy](./reference/markers/object.md) + - [RBAC](./reference/markers/rbac.md) - [controller-gen CLI](./reference/controller-gen.md) - [completion](./reference/completion.md) - [Artifacts](./reference/artifacts.md) - - [Platform Support](platform.md) + - [Platform Support](./reference/platform.md) - [Configuring EnvTest](./reference/envtest.md) - [Metrics](./reference/metrics.md) - - [Reference](./reference/metrics-reference.md) + - [Reference](./reference/metrics-reference.md) - [Makefile Helpers](./reference/makefile-helpers.md) - [Project config](./reference/project-config.md) @@ -107,20 +115,26 @@ - [Plugins][plugins] - [Available Plugins](./plugins/available-plugins.md) + - [To scaffold a project](./plugins/to-scaffold-project.md) - [go/v2 (Deprecated)](./plugins/go-v2-plugin.md) - [go/v3 (Default init scaffold)](./plugins/go-v3-plugin.md) - - [go/v4-alpha](./plugins/go-v4-plugin.md) - - [kustomize/v1](./plugins/kustomize-v1.md) - - [kustomize/v2-alpha](./plugins/kustomize-v2-alpha.md) + - [go/v4](./plugins/go-v4-plugin.md) + - [To add optional features](./plugins/to-add-optional-features.md) - [declarative/v1](./plugins/declarative-v1.md) - [grafana/v1-alpha](./plugins/grafana-v1-alpha.md) - [deploy-image/v1-alpha](./plugins/deploy-image-plugin-v1-alpha.md) + - [To be extended for others tools](./plugins/to-be-extended.md) + - [kustomize/v1 (Deprecated)](./plugins/kustomize-v1.md) + - [kustomize/v2](./plugins/kustomize-v2.md) - [Extending the CLI](./plugins/extending-cli.md) - [Creating your own plugins](./plugins/creating-plugins.md) + - [Testing your own plugins](./plugins/testing-plugins.md) - [Plugins Versioning](./plugins/plugins-versioning.md) ---- -[Appendix: The TODO Landing Page](./TODO.md) +--- +[FAQ](./faq.md) + +[Appendix: The TODO Landing Page](./TODO.md) [plugins]: ./plugins/plugins.md diff --git a/docs/book/src/component-config-tutorial/api-changes.md b/docs/book/src/component-config-tutorial/api-changes.md index 850fb1411cb..edd39223edd 100644 --- a/docs/book/src/component-config-tutorial/api-changes.md +++ b/docs/book/src/component-config-tutorial/api-changes.md @@ -1,5 +1,17 @@ # Changing things up + + This tutorial will show you how to create a custom configuration file for your project by modifying a project generated with the `--component-config` flag passed to the `init` command. The full tutorial's source can be found @@ -14,7 +26,7 @@ steps](/quick-start.md#installation) before continuing. kubebuilder init --domain tutorial.kubebuilder.io --component-config ``` -## Setting up an exising project +## Setting up an existing project If you've previously generated a project we can add support for parsing the config file by making the following changes to `main.go`. @@ -57,7 +69,7 @@ loading the config from the file. -Lastly, we'll change the `NewManager` call to use the `options` varible we +Lastly, we'll change the `NewManager` call to use the `options` variable we defined above. ```go @@ -106,13 +118,16 @@ configMapGenerator: - controller_manager_config.yaml ``` -Update the file `default/kustomization.yaml` by adding under the patchesStrategicMerge: the following patch: +Update the file `default/kustomization.yaml` by adding under the [`patchesStrategicMerge:` key](https://kubectl.docs.kubernetes.io/references/kustomize/builtins/#_patchesstrategicmerge_) the following patch: +```yaml +patchesStrategicMerge: # Mount the controller config file for loading manager configurations # through a ComponentConfig type - manager_config_patch.yaml +``` -Update the file `default/manager_config_patch.yaml` by adding under the spec: the following patch: +Update the file `default/manager_config_patch.yaml` by adding under the `spec:` key the following patch: ```yaml spec: @@ -131,4 +146,3 @@ spec: configMap: name: manager-config ``` - diff --git a/docs/book/src/component-config-tutorial/config-type.md b/docs/book/src/component-config-tutorial/config-type.md index 5a9660b001e..518f360ed81 100644 --- a/docs/book/src/component-config-tutorial/config-type.md +++ b/docs/book/src/component-config-tutorial/config-type.md @@ -1,26 +1,39 @@ # Adding a new Config Type + + To scaffold out a new config Kind, we can use `kubebuilder create api`. ```bash kubebuilder create api --group config --version v2 --kind ProjectConfig --resource --controller=false --make=false ``` +Then, run `make build` to implement the interface for your API type, which would generate the file `zz_generated.deepcopy.go`. This will create a new type file in `api/config/v2/` for the `ProjectConfig` -kind. We'll need to change this file to embed the +kind. We'll need to change this file to embed the [v1alpha1.ControllerManagerConfigurationSpec](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/#ControllerManagerConfigurationSpec) {{#literatego ./testdata/projectconfig_types.go}} -Lastly, we'll change the `main.go` to reference this type for parsing the file. \ No newline at end of file +Lastly, we'll change the `main.go` to reference this type for parsing the file. diff --git a/docs/book/src/component-config-tutorial/custom-type.md b/docs/book/src/component-config-tutorial/custom-type.md index 76dfeda43d2..55910168e48 100644 --- a/docs/book/src/component-config-tutorial/custom-type.md +++ b/docs/book/src/component-config-tutorial/custom-type.md @@ -1,5 +1,17 @@ # Using a Custom Type + + -While Kubebuilder v2 will not scaffold out a project structure compatible -with multiple API groups in the same repository by default, it's possible -to modify the default project structure to support it. - Let's migrate the [CronJob example][cronjob-tutorial]. + + +To change the layout of your project to support Multi-Group run the command +`kubebuilder edit --multigroup=true`. Once you switch to a multi-group layout, the new Kinds +will be generated in the new layout but additional manual work is needed +to move the old API groups to the new layout. + Generally, we use the prefix for the API group as the directory name. We can check `api/v1/groupversion_info.go` to find that out: @@ -28,56 +38,75 @@ can check `api/v1/groupversion_info.go` to find that out: package v1 ``` -Then, we'll rename `api` to `apis` to be more clear, and we'll move our -existing APIs into a new subdirectory, "batch": +Then, we'll rename move our existing APIs into a new subdirectory, "batch": ```bash -mkdir apis/batch -mv api/* apis/batch -# After ensuring that all was moved successfully remove the old directory `api/` -rm -rf api/ +mkdir api/batch +mv api/* api/batch ``` +After moving the APIs to a new directory, the same needs to be applied to the controllers. For go/v4: -After moving the APIs to a new directory, the same needs to be applied to the controllers: +```bash +mkdir internal/controller/batch +mv internal/controller/* internal/controller/batch/ +``` + diff --git a/docs/book/src/multiversion-tutorial/webhooks.md b/docs/book/src/multiversion-tutorial/webhooks.md index be87f45d721..52f10804d97 100644 --- a/docs/book/src/multiversion-tutorial/webhooks.md +++ b/docs/book/src/multiversion-tutorial/webhooks.md @@ -20,7 +20,7 @@ setup, from when we built our defaulting and validating webhooks! Similarly, our existing main file is sufficient: -{{#literatego ./testdata/project/main.go}} +{{#literatego ./testdata/project/cmd/main.go}} Everything's set up and ready to go! All that's left now is to test out our webhooks. diff --git a/docs/book/src/plugins/available-plugins.md b/docs/book/src/plugins/available-plugins.md index ba7744d0d36..3f723d05274 100644 --- a/docs/book/src/plugins/available-plugins.md +++ b/docs/book/src/plugins/available-plugins.md @@ -2,28 +2,14 @@ This section describes the plugins supported and shipped in with the Kubebuilder project. -| Plugin | Key | Description | -| ---------------------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [go.kubebuilder.io/v2 - (Deprecated)](go-v2-plugin.md) | `go/v2` | Golang plugin responsible for scaffolding the legacy layout provided with Kubebuilder CLI >= `2.0.0` and < `3.0.0`. | -| [go.kubebuilder.io/v3 - (Default scaffold with Kubebuilder init)](go-v3-plugin.md) | `go/v3` | Default scaffold used for creating a project when no plugin(s) are provided. Responsible for scaffolding Golang projects and its configurations. | -| [go.kubebuilder.io/v4-alpha - (Add Apple Sillicom Support)](go-v4-plugin.md) | `go/v4` | Scaffold composite by `base.go.kubebuilder.io/v3` and [kustomize.common.kubebuilder.io/v2-alpha](kustomize-v2-alpha.md). Responsible for scaffolding Golang projects and its configurations. | -| [declarative.go.kubebuilder.io/v1](declarative-v1.md) | `declarative/v1` | Optional plugin used to scaffold APIs/controllers using the [kubebuilder-declarative-pattern][kubebuilder-declarative-pattern] project. | -| [kustomize.common.kubebuilder.io/v1](kustomize-v1.md) | `kustomize/v1` | Responsible for scaffold all manifests to configure the projects with [kustomize(v3)][kustomize]. (create and update the `config/` directory). This plugin is used in the composition to create the plugin (`go/v3`). | -| [kustomize.common.kubebuilder.io/v2-alpha](kustomize-v2-alpha.md) | `kustomize/v2-alpha` | It has the same purpose of `kustomize/v1`. However, it works with [kustomize][kustomize] version `v4` and addresses the required changes for future kustomize configurations. It will probably be used with the future `go/v4-alpha` plugin. | -| `base.go.kubebuilder.io/v3` | `base/v3` | Responsible for scaffold all files which specific requires Golang. This plugin is used in the composition to create the plugin (`go/v3`) | -| [grafana.kubebuilder.io/v1-alpha](grafana-v1-alpha.md) | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. | -| [deploy-image.go.kubebuilder.io/v1-alpha](deploy-image-plugin-v1-alpha) | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). | - -> Note: **ALPHA** plugins can introduce breaking changes. For further info see [Plugins Versioning](./plugins/plugins-versioning.md). +{{#include to-scaffold-project.md }} +{{#include to-add-optional-features.md }} +{{#include to-be-extended.md }} +**ALPHA** plugins can introduce breaking changes. For further info see [Plugins Versioning](./plugins/plugins-versioning.md). -[create-plugins]: creating-plugins.md -[kubebuilder-declarative-pattern]: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern -[kustomize]: https://kustomize.io/ + \ No newline at end of file diff --git a/docs/book/src/plugins/creating-plugins.md b/docs/book/src/plugins/creating-plugins.md index 2c599b87a19..b9fbcb29367 100644 --- a/docs/book/src/plugins/creating-plugins.md +++ b/docs/book/src/plugins/creating-plugins.md @@ -1,8 +1,50 @@ # Creating your own plugins +[extending-cli]: extending-cli.md +[controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime +[operator-pattern]: https://kubernetes.io/docs/concepts/extend-kubernetes/operator +[sdk-ansible]: https://sdk.operatorframework.io/docs/building-operators/ansible/ +[sdk-cli-pkg]: https://pkg.go.dev/github.com/operator-framework/operator-sdk/internal/cmd/operator-sdk/cli +[sdk-helm]: https://sdk.operatorframework.io/docs/building-operators/helm/ +[sdk]: https://github.com/operator-framework/operator-sdk + ## Overview -You can extend the Kubebuilder API to create your own plugins. If [extending the CLI][extending-cli], your plugin will be implemented in your project and registered to the CLI as has been done by the [SDK][sdk] project. See its [cli code][sdk-cli-pkg] as an example. +You can extend the Kubebuilder API to create your own plugins. If [extending the CLI][extending-cli], your plugin will be implemented in your project and registered to the CLI as has been done by the [SDK][sdk] project. See its [CLI code][sdk-cli-pkg] as an example. + +## When it is useful? + +- If you are looking to create plugins which support and work with another language. +- If you would like to create helpers and integrations on top of the scaffolds done by the plugins provided by Kubebuiler. +- If you would like to have customized layouts according to your needs. + +## How the plugins can be used? + +Kubebuilder provides a set of plugins to scaffold the projects, to help you extend and re-use its implementation to provide additional features. +For further information see [Available Plugins][available-plugins]. + +Therefore, if you have a need you might want to propose a solution by adding a new plugin +which would be shipped with Kubebuilder by default. + +However, you might also want to have your own tool to address your specific scenarios and by taking advantage of what is provided by Kubebuilder as a library. +That way, you can focus on addressing your needs and keep your solutions easier to maintain. + +Note that by using Kubebuilder as a library, you can import its plugins and then create your own plugins that do customizations on top. +For instance, `Operator-SDK` does with the plugins [manifest][operator-sdk-manifest] and [scorecard][operator-sdk-scorecard] to add its features. +Also see [here][operator-sdk-plugin-ref]. + +Another option implemented with the [Extensible CLI and Scaffolding Plugins - Phase 2][plugins-phase2-design-doc] is +to extend Kibebuilder as a LIB to create only a specific plugin that can be called and used with +Kubebuilder as well. + + ## Language-based Plugins @@ -15,9 +57,10 @@ Note that Kubebuilder provides the `kustomize.common.kubebuilder.io` to help in In this way, currently, you can [Extend the CLI][extending-cli] and use the `Bundle Plugin` to create your language plugins such as: ```go - mylanguagev1Bundle, _ := plugin.NewBundle(language.DefaultNameQualifier, plugin.Version{Number: 1}, - kustomizecommonv1.Plugin{}, // extend the common base from Kuebebuilder - mylanguagev1.Plugin{}, // your plugin language which will do the scaffolds for the specific language on top of the common base + mylanguagev1Bundle, _ := plugin.NewBundle(plugin.WithName(language.DefaultNameQualifier), + plugin.WithVersion(plugin.Version{Number: 1}), + plugin.WithPlugins(kustomizecommonv1.Plugin{}, mylanguagev1.Plugin{}), // extend the common base from Kubebuilder + // your plugin language which will do the scaffolds for the specific language on top of the common base ) ``` @@ -25,14 +68,14 @@ If you do not want to develop your plugin using Golang, you can follow its stand ```sh kubebuilder init --plugins=kustomize -``` +``` Then you can, for example, create your implementations for the sub-commands `create api` and `create webhook` using your language of preference. -## Custom Plugins +## Custom Plugins + +Note that users are also able to use plugins to customize their scaffolds and address specific needs. + +See that Kubebuilder provides the [`deploy-image`][deploy-image] plugin that allows the user to create the controller & CRs which will deploy and manage an image on the cluster: -Note that users are also able to use plugins to customize their scaffold and address specific needs. See that Kubebuilder provides the [declarative][declarative-code] plugin which can be used when for example an API is scaffold: +```sh +kubebuilder create api --group example.com --version v1alpha1 --kind Memcached --image=memcached:1.6.15-alpine --image-container-command="memcached,-m=64,modern,-v" --image-container-port="11211" --run-as-user="1001" --plugins="deploy-image/v1-alpha" +``` + +This plugin will perform a custom scaffold following the [Operator Pattern][operator-pattern]. + +Another example is the [`grafana`][grafana] plugin that scaffolds a new folder container manifests to visualize operator status on Grafana Web UI: ```sh -kubebuider create api [options] --plugins=go/v3,declarative/v1 -``` +kubebuilder edit --plugins="grafana.kubebuilder.io/v1-alpha" +``` + +In this way, by [Extending the Kubebuilder CLI][extending-cli], you can also create custom plugins such this one. -This plugin will perform a custom scaffold using the [kubebuilder declarative pattern][kubebuilder-declarative-pattern]. +Feel free to check the implementation under: -In this way, by [Extending the Kubebuilder CLI][extending-cli], you can also create custom plugins such this one. Feel free to check its implementation in [`pkg/plugins/golang/declarative`][declarative-code]. +- deploy-image: +- grafana: -## Future vision for Kubebuilder Plugins +## Plugin Scaffolding -As the next steps for the plugins, its possible to highlight three initiatives so far, which are: +Your plugin may add code on top of what is scaffolded by default with Kubebuilder sub-commands(`init`, `create`, ...). +This is common as you may expect your plugin to: -- [Plugin phase 2.0][plugin-2.0]: allow the Kubebuilder CLI or any other CLI, which is [Extending the Kubebuilder CLI][extending-cli], to discover external plugins, in this way, allow the users to use these external options as helpers to perform the scaffolds with the tool. -- [Config-gen][config-gen]: the config-gen option has been provided as an alpha option in the Kubebuilder CLI(`kubebuilder alpha config-gen`) to encourage its contributions. The idea of this option would simplify the config scaffold. For further information see its [README][config-gen-readme]. -- [New Plugin (`deploy-image.go.kubebuilder.io/v1beta1`) to generate code][new-plugin-gen]: its purpose is to provide an arch-type that will scaffold the APIs and Controllers with the required code to deploy and manage solutions on the cluster. +- Create API +- Update controller manager logic +- Generate corresponding manifests -Please, feel to contribute with them as well. Your contribution to the project is very welcome. +### Boilerplates + +The Kubebuilder internal plugins use boilerplates to generate the files of code. + +For instance, the go/v3 scaffolds the `main.go` file by defining an object that [implements the machinery interface][kubebuilder-machinery]. +In the [implementation][go-v3-settemplatedefault] of `Template.SetTemplateDefaults`, the [raw template][go-v3-main-template] is set to the body. +Such object that implements the machinery interface will later pass to the [execution of scaffold][go-v3-scaffold-execute]. + +Similar, you may also design your code of plugin implementation by such reference. +You can also view the other parts of the code file given by the links above. + +If your plugin is expected to modify part of the existing files with its scaffold, you may use functions provided by [sigs.k8s.io/kubebuilder/v3/pkg/plugin/util][kb-util]. +See [example of deploy-image][example-of-deploy-image-2]. +In brief, the util package helps you customize your scaffold in a lower level. + +### Use Kubebuilder Machinery Lib + +Notice that Kubebuilder also provides [machinery pkg][kubebuilder-machinery-pkg] where you can: + +- Define file I/O behavior. +- Add markers to the scaffolded file. +- Define the template for scaffolding. + +#### Overwrite A File + +You might want for example to overwrite a scaffold done by using the option: + +```go + f.IfExistsAction = machinery.OverwriteFile +``` + +Let's imagine that you would like to have a helper plugin that would be called in a chain with `go/v4` to add customizations on top. +Therefore after we generate the code calling the subcommand to `init` from `go/v4` we would like to overwrite the Makefile to change this scaffold via our plugin. +In this way, we would implement the Bollerplate for our Makefile and then use this option to ensure that it would be overwritten. + +See [example of deploy-image][example-of-deploy-image-1]. + +### A Combination of Multiple Plugins + +Since your plugin may work frequently with other plugins, the executing command for scaffolding may become cumbersome, e.g: + +```shell +kubebuilder create api --plugins=go/v3,kustomize/v1,yourplugin/v1 +``` + +You can probably define a method to your scaffolder that calls the plugin scaffolding method in order. +See [example of deploy-image][example-of-deploy-image-3]. + +#### Define Plugin Bundles + +Alternatively, you can create a plugin bundle to include the target plugins. For instance: + +```go + mylanguagev1Bundle, _ := plugin.NewBundle(plugin.WithName(language.DefaultNameQualifier), + plugin.WithVersion(plugin.Version{Number: 1}), + plugin.WithPlugins(kustomizecommonv1.Plugin{}, mylanguagev1.Plugin{}), // extend the common base from Kuebebuilder + // your plugin language which will do the scaffolds for the specific language on top of the common base + ) +``` -[sdk-cli-pkg]: https://github.com/operator-framework/operator-sdk/blob/master/internal/cmd/operator-sdk/cli/cli.go -[sdk-ansible]: https://github.com/operator-framework/operator-sdk/tree/master/internal/plugins/ansible/v1 -[sdk-helm]: https://github.com/operator-framework/operator-sdk/tree/master/internal/plugins/helm/v1 -[operator-pattern]: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ [controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime -[plugin-2.0]: https://github.com/kubernetes-sigs/kubebuilder/issues/1378 -[config-gen-readme]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/cli/alpha/config-gen/README.md -[config-gen]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/cli/alpha/config-gen -[plugins-phase1-design-doc-1.5]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md -[extending-cli]: extending-cli.md -[new-plugin-gen]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/code-generate-image-plugin.md -[kubebuilder-declarative-pattern]: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern -[declarative-code]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugins/golang/declarative -[sdk]: https://github.com/operator-framework/operator-sdk \ No newline at end of file +[deploy-image]: https://github.com/kubernetes-sigs/kubebuilder/tree/v3.7.0/pkg/plugins/golang/deploy-image/v1alpha1 +[grafana]: https://github.com/kubernetes-sigs/kubebuilder/tree/v3.7.0/pkg/plugins/optional/grafana/v1alpha +[extending-cli]: ./extending-cli.md +[kb-util]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin/util +[example-of-deploy-image-1]: https://github.com/kubernetes-sigs/kubebuilder/blob/df1ed6ccf19df40bd929157a91eaae6a9215bfc6/pkg/plugins/golang/deploy-image/v1alpha1/scaffolds/internal/templates/api/types.go#L58 +[example-of-deploy-image-2]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugins/golang/deploy-image/v1alpha1/scaffolds/api.go#L170-L266 +[example-of-deploy-image-3]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugins/golang/deploy-image/v1alpha1/scaffolds/api.go#L77-L98 +[available-plugins]: ./available-plugins.md +[operator-sdk-manifest]: https://github.com/operator-framework/operator-sdk/tree/v1.23.0/internal/plugins/manifests/v2 +[operator-sdk-scorecard]: https://github.com/operator-framework/operator-sdk/tree/v1.23.0/internal/plugins/scorecard/v2 +[operator-sdk-plugin-ref]: https://github.com/operator-framework/operator-sdk/blob/v1.23.0/internal/cmd/operator-sdk/cli/cli.go#L78-L160 +[plugins-section]: ??? +[plugins-phase1-design-doc]: https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/designs/extensible-cli-and-scaffolding-plugins-phase-1.md#extensible-cli-and-scaffolding-plugins +[plugins-phase1-design-doc-1.5]: https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md#extensible-cli-and-scaffolding-plugins---phase-15 +[plugins-phase2-design-doc]: https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/designs/extensible-cli-and-scaffolding-plugins-phase-2.md#extensible-cli-and-scaffolding-plugins---phase-2 +[go-v3-main-template]: https://github.com/kubernetes-sigs/kubebuilder/blob/3bfc84ec8767fa760d1771ce7a0cb05a9a8f6286/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go#L183 +[kubebuilder-machinery]: https://github.com/kubernetes-sigs/kubebuilder/blob/3bfc84ec8767fa760d1771ce7a0cb05a9a8f6286/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go#L28 +[go-v3-settemplatedefault]: https://github.com/kubernetes-sigs/kubebuilder/blob/3bfc84ec8767fa760d1771ce7a0cb05a9a8f6286/pkg/plugins/golang/v3/scaffolds/internal/templates/main.go#L40 +[go-v3-scaffold-execute]: https://github.com/kubernetes-sigs/kubebuilder/blob/3bfc84ec8767fa760d1771ce7a0cb05a9a8f6286/pkg/plugins/golang/v3/scaffolds/init.go#L120 +[kubebuilder-machinery-pkg]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/machinery#section-documentation diff --git a/docs/book/src/plugins/declarative-v1.md b/docs/book/src/plugins/declarative-v1.md index a7595c2c471..c3513618dae 100644 --- a/docs/book/src/plugins/declarative-v1.md +++ b/docs/book/src/plugins/declarative-v1.md @@ -1,31 +1,30 @@ # Declarative Plugin -The declarative plugin allows you to create [controllers][controller-runtime] using the [kubebuilder-declarative-pattern][kubebuilder-declarative-pattern]. -By using the declarative plugin, you can make the required changes on top of what is scaffolded by default when you create a Go project with Kubebuilder and the Golang plugins (i.e. go/v2, go/v3). +The declarative plugin allows you to create [controllers][controller-runtime] using the [kubebuilder-declarative-pattern][kubebuilder-declarative-pattern]. +By using the declarative plugin, you can make the required changes on top of what is scaffolded by default when you create a Go project with Kubebuilder and the Golang plugins (i.e. go/v2, go/v3). - + ## When to use it ? -- If you are looking to scaffold one or more [controllers][controller-runtime] following [the pattern][kubebuilder-declarative-pattern] ( See an e.g. of the reconcile method implemented [here][addon-v3-controller]) +- If you are looking to scaffold one or more [controllers][controller-runtime] following [the pattern][kubebuilder-declarative-pattern] ( See an e.g. of the reconcile method implemented [here][addon-v3-controller]) - If you want to have manifests shipped inside your Manager container. The declarative plugin works with channels, which allow you to push manifests. [More info][addon-channels-info] ## How to use it ? The declarative plugin requires to be used with one of the available Golang plugins -If you want that any API(s) and its respective controller(s) generate to reconcile them of your project adopt this partner then: +If you want that any API(s) and its respective controller(s) generate to reconcile them of your project adopt this partner then: ```sh kubebuilder init --plugins=go/v3,declarative/v1 --domain example.org --repo example.org/guestbook-operator ``` -If you want to adopt this pattern for specific API(s) and its respective controller(s) (not for any API/controller scaffold using Kubebuilder CLI) then: +If you want to adopt this pattern for specific API(s) and its respective controller(s) (not for any API/controller scaffold using Kubebuilder CLI) then: ```sh kubebuilder create api --plugins=go/v3,declarative/v1 --version v1 --kind Guestbook @@ -35,30 +34,30 @@ kubebuilder create api --plugins=go/v3,declarative/v1 --version v1 --kind Guestb The declarative plugin implements the following subcommands: -* init (`$ kubebuilder init [OPTIONS]`) -* create api (`$ kubebuilder create api [OPTIONS]`) +- init (`$ kubebuilder init [OPTIONS]`) +- create api (`$ kubebuilder create api [OPTIONS]`) ## Affected files The following scaffolds will be created or updated by this plugin: -* `controllers/*_controller.go` -* `api/*_types.go` -* `channels/packages///manifest.yaml` -* `channels/stable` -* `Dockerfile` +- `controllers/*_controller.go` +- `api/*_types.go` +- `channels/packages///manifest.yaml` +- `channels/stable` +- `Dockerfile` ## Further resources -* Read more about the [declarative pattern][kubebuilder-declarative-pattern] -* Watch the KubeCon 2018 Video [Managing Addons with Operators][kubecon-video] -* Check the [plugin implementation][plugin-implementation] +- Read more about the [declarative pattern][kubebuilder-declarative-pattern] +- Watch the KubeCon 2018 Video [Managing Addons with Operators][kubecon-video] +- Check the [plugin implementation][plugin-implementation] -[dockerfile-addon]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/testdata/project-v3-addon/Dockerfile#L16-L19 [addon-channels-info]: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern/blob/master/docs/addon/walkthrough/README.md#adding-a-manifest [controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime [kubebuilder-declarative-pattern]: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern [testdata]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata/ [kubecon-video]: https://www.youtube.com/watch?v=LPejvfBR5_w [plugin-implementation]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/pkg/plugins/golang/declarative -[addon-v3-controller]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata/project-v3-addon \ No newline at end of file +[addon-v3-controller]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata/project-v3-declarative-v1 + diff --git a/docs/book/src/plugins/extending-cli.md b/docs/book/src/plugins/extending-cli.md index 953f98c99e6..683e1c01975 100644 --- a/docs/book/src/plugins/extending-cli.md +++ b/docs/book/src/plugins/extending-cli.md @@ -42,9 +42,9 @@ var ( // GetPluginsCLI returns the plugins based CLI configured to be used in your CLI binary func GetPluginsCLI() (*cli.CLI) { // Bundle plugin which built the golang projects scaffold by Kubebuilder go/v3 - gov3Bundle, _ := plugin.NewBundle(golang.DefaultNameQualifier, plugin.Version{Number: 3}, - kustomizecommonv1.Plugin{}, - golangv3.Plugin{}, + gov3Bundle, _ := plugin.NewBundle(plugin.WithName(golang.DefaultNameQualifier), + plugin.WithVersion(plugin.Version{Number: 3}), + plugin.WithPlugins(kustomizecommonv1.Plugin{}, golangv3.Plugin{}), ) @@ -175,10 +175,9 @@ Once a plugin is deprecated, have it implement a [Deprecated][deprecate-plugin-d ```go // see that will be like myplugin.example/v1` - myPluginBundle, _ := plugin.NewBundle(``,``, - pluginA.Plugin{}, - pluginB.Plugin{}, - pluginC.Plugin{}, + myPluginBundle, _ := plugin.NewBundle(plugin.WithName(``), + plugin.WithVersion(``), + plugin.WithPlugins(pluginA.Plugin{}, pluginB.Plugin{}, pluginC.Plugin{}), ) ``` @@ -186,7 +185,7 @@ Once a plugin is deprecated, have it implement a [Deprecated][deprecate-plugin-d Note that it means that when a user of your CLI calls this plugin, the execution of the sub-commands will be sorted by the order to which they were added in a chain: -> sub-command of plugin A -> sub-command of plugin B -> sub-command of plugin C +> `sub-command` of plugin A ➔ `sub-command` of plugin B ➔ `sub-command` of plugin C Then, to initialize using this "Plugin Bundle" which will run the chain of plugins: @@ -194,9 +193,9 @@ Then, to initialize using this "Plugin Bundle" which will run the chain of plugi kubebuider init --plugins=myplugin.example/v1 ``` -- Runs init sub-command of the plugin A -- And then, runs init sub-command of the plugin B -- And then, runs init sub-command of the plugin C +- Runs init `sub-command` of the plugin A +- And then, runs init `sub-command` of the plugin B +- And then, runs init `sub-command` of the plugin C [project-file-config]: ../reference/project-config.md [plugin-interface]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Plugin @@ -210,4 +209,4 @@ kubebuider init --plugins=myplugin.example/v1 [deprecate-plugin-doc]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Deprecated [plugin-update-meta]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#UpdatesMetadata [cli]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/cli -[plugin-version-type]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Version \ No newline at end of file +[plugin-version-type]: https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin#Version diff --git a/docs/book/src/plugins/go-v2-plugin.md b/docs/book/src/plugins/go-v2-plugin.md index aea3b38db13..3c2d3f18a23 100644 --- a/docs/book/src/plugins/go-v2-plugin.md +++ b/docs/book/src/plugins/go-v2-plugin.md @@ -3,22 +3,22 @@ -The `go/v2` plugin has the purpose to scaffold Golang projects to help users -to build projects with [controllers][controller-runtime] and keep the backwards compatibility +The `go/v2` plugin has the purpose to scaffold Golang projects to help users +to build projects with [controllers][controller-runtime] and keep the backwards compatibility with the default scaffold made using Kubebuilder CLI `2.x.z` releases. - - [Extending the CLI and Scaffolds](extending-cli.md) - - [Creating your own plugins](creating-plugins.md) +- [Extending the CLI and Scaffolds](extending-cli.md) +- [Creating your own plugins](creating-plugins.md) +- [Testing your plugins](testing-plugins.md) - [plugins-phase1-design-doc]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-1.md - [plugins-phase1-design-doc-1.5]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md - [extending-cli]: extending-cli.md - - - [section-future-vision-plugins]: https://book.kubebuilder.io/plugins/creating-plugins.html#future-vision-for-kubebuilder-plugins +[plugins-phase1-design-doc]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-1.md +[plugins-phase1-design-doc-1.5]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/extensible-cli-and-scaffolding-plugins-phase-1-5.md +[extending-cli]: extending-cli.md +[section-future-vision-plugins]: https://book.kubebuilder.io/plugins/creating-plugins.html#future-vision-for-kubebuilder-plugins diff --git a/docs/book/src/plugins/testing-plugins.md b/docs/book/src/plugins/testing-plugins.md new file mode 100644 index 00000000000..904039e9859 --- /dev/null +++ b/docs/book/src/plugins/testing-plugins.md @@ -0,0 +1,84 @@ +# Test Your Plugins + +You can test your plugin in two dimension: + +1. Validate your plugin behavior through E2E tests +2. Generate sample projects based on your plugin that can be placed in `./testdata/` + +## Write E2E Tests + +You can check [Kubebuilder/v3/test/e2e/utils](https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/test/e2e/utils) package that offers `TestContext` of rich methods: + +- [NewTestContext](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L51) helps define: + - Temporary folder for testing projects + - Temporary controller-manager image + - [Kubectl execution method](https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/test/e2e/utils#Kubectl) + - The cli executable (`kubebuilder`, `operator-sdk`, OR your extended-cli) + +Once defined, you can use `TestContext` to: + +1. Setup testing environment, e.g: + - Clean up the environment, create temp dir. See [Prepare](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L97) + - Install prerequisites CRDs: See [InstallCertManager](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L138), [InstallPrometheusManager](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.6.0/test/e2e/utils/test_context.go#L171) +2. Validate the plugin behavior, e.g: + - Trigger the plugin's bound subcommands. See [Init](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L213), [CreateAPI](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.6.0/test/e2e/utils/test_context.go#L222) + - Use [PluginUtil](https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/pkg/plugin/util) to verify the scaffolded outputs. See [InsertCode](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/pkg/plugin/util/util.go#L67), [ReplaceInFile](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.6.0/pkg/plugin/util/util.go#L196), [UncommendCode](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.6.0/pkg/plugin/util/util.go#L86) +3. Further make sure the scaffolded output works, e.g: + - Execute commands in your `Makefile`. See [Make](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L240) + - Temporary load image of the testing controller. See [LoadImageToKindCluster](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L283) + - Call Kubectl to validate running resources. See [utils.Kubectl](https://pkg.go.dev/sigs.k8s.io/kubebuilder/v3/test/e2e/utils#Kubectl) +4. Delete temporary resources after testing exited, e.g: + - Uninstall prerequisites CRDs: See [UninstallPrometheusOperManager](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L183) + - Delete temp dir. See [Destroy](https://github.com/kubernetes-sigs/kubebuilder/blob/v3.7.0/test/e2e/utils/test_context.go#L255) + +**References:** [operator-sdk e2e tests](https://github.com/operator-framework/operator-sdk/tree/master/test/e2e/go), [kubebuiler e2e tests](https://github.com/kubernetes-sigs/kubebuilder/tree/master/test/e2e/v3) + +## Generate Test Samples + +It can be straightforward to view content of sample projects generated by your plugin. + +For example, Kubebuilder generate [sample projects](https://github.com/kubernetes-sigs/kubebuilder/tree/v3.7.0/testdata) based on different plugins to validate the layouts. + +Simply, you can also use `TextContext` to generate folders of scaffolded projects from your plugin. +The commands are very similar as mentioned in [creating-plugins](creating-plugins.md#write-e2e-tests). + +Following is a general workflow to create a sample by the plugin `go/v3`: (`kbc` is an instance of `TextContext`) + +- To initialized a project: + ```go + By("initializing a project") + err = kbc.Init( + "--plugins", "go/v3", + "--project-version", "3", + "--domain", kbc.Domain, + "--fetch-deps=false", + "--component-config=true", + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + ``` +- To define API: + ```go + By("creating API definition") + err = kbc.CreateAPI( + "--group", kbc.Group, + "--version", kbc.Version, + "--kind", kbc.Kind, + "--namespaced", + "--resource", + "--controller", + "--make=false", + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + ``` +- To scaffold webhook configurations: + ```go + By("scaffolding mutating and validating webhooks") + err = kbc.CreateWebhook( + "--group", kbc.Group, + "--version", kbc.Version, + "--kind", kbc.Kind, + "--defaulting", + "--programmatic-validation", + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + ``` diff --git a/docs/book/src/plugins/to-add-optional-features.md b/docs/book/src/plugins/to-add-optional-features.md new file mode 100644 index 00000000000..085b11fda94 --- /dev/null +++ b/docs/book/src/plugins/to-add-optional-features.md @@ -0,0 +1,9 @@ +## To add optional features + +The following plugins are useful to generate code and take advantage of optional features + +| Plugin | Key | Description | +| ---------------------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [declarative.go.kubebuilder.io/v1](declarative-v1.md) | `declarative/v1` | Optional plugin used to scaffold APIs/controllers using the [kubebuilder-declarative-pattern][kubebuilder-declarative-pattern] project. | +| [grafana.kubebuilder.io/v1-alpha](grafana-v1-alpha.md) | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. | +| [deploy-image.go.kubebuilder.io/v1-alpha](deploy-image-plugin-v1-alpha) | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). | diff --git a/docs/book/src/plugins/to-be-extended.md b/docs/book/src/plugins/to-be-extended.md new file mode 100644 index 00000000000..e6137bdad28 --- /dev/null +++ b/docs/book/src/plugins/to-be-extended.md @@ -0,0 +1,28 @@ +## To help projects using Kubebuilder as Lib to composite new solutions and plugins + + + +Then, see that you can use the kustomize plugin, which is responsible for to scaffold the kustomize files under `config/`, as +the base language plugins which are responsible for to scaffold the Golang files to create your own plugins to work with +another languages (i.e. [Operator-SDK][sdk] does to allow users work with Ansible/Helm) or to add +helpers on top, such as [Operator-SDK][sdk] does to add their features to integrate the projects with [OLM][olm]. + +| Plugin | Key | Description | +| ---------------------------------------------------------------------------------- |-----------------------------| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [kustomize.common.kubebuilder.io/v1](https://github.com/kubernetes-sigs/kubebuilder/pull/3235/kustomize-v1.md) | kustomize/v1 (Deprecated) | Responsible for scaffolding all manifests to configure projects with [kustomize(v3)][kustomize]. (create and update the `config/` directory). This plugin is used in the composition to create the plugin (`go/v3`). | +| [kustomize.common.kubebuilder.io/v2](kustomize-v2.md) | `kustomize/v2` | It has the same purpose of `kustomize/v1`. However, it works with [kustomize][kustomize] version `v4` and addresses the required changes for future kustomize configurations. It will probably be used with the future `go/v4-alpha` plugin. | +| `base.go.kubebuilder.io/v3` | `base/v3` | Responsible for scaffolding all files that specifically require Golang. This plugin is used in composition to create the plugin (`go/v3`) | +| `base.go.kubebuilder.io/v4` | `base/v4` | Responsible for scaffolding all files which specifically requires Golang. This plugin is used in the composition to create the plugin (`go/v4`) | + +[create-plugins]: creating-plugins.md +[kubebuilder-declarative-pattern]: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern +[kustomize]: https://kustomize.io/ +[sdk]: https://github.com/operator-framework/operator-sdk +[olm]: https://olm.operatorframework.io/ + diff --git a/docs/book/src/plugins/to-scaffold-project.md b/docs/book/src/plugins/to-scaffold-project.md new file mode 100644 index 00000000000..cb29f9cb534 --- /dev/null +++ b/docs/book/src/plugins/to-scaffold-project.md @@ -0,0 +1,9 @@ +## To scaffold the projects + +The following plugins are useful to scaffold the whole project with the tool. + +| Plugin | Key | Description | +| ---------------------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [go.kubebuilder.io/v2 - (Deprecated)](go-v2-plugin.md) | `go/v2` | Golang plugin responsible for scaffolding the legacy layout provided with Kubebuilder CLI >= `2.0.0` and < `3.0.0`. | +| [go.kubebuilder.io/v3 - (Default scaffold with Kubebuilder init)](go-v3-plugin.md) | `go/v3` | Default scaffold used for creating a project when no plugin(s) are provided. Responsible for scaffolding Golang projects and its configurations. | +| [go.kubebuilder.io/v4-alpha - (Add Apple Sillicom Support)](go-v4-plugin.md) | `go/v4` | Scaffold composite by `base.go.kubebuilder.io/v3` and [kustomize.common.kubebuilder.io/v2](kustomize-v2.md). Responsible for scaffolding Golang projects and its configurations. | diff --git a/docs/book/src/quick-start.md b/docs/book/src/quick-start.md index 5d9040e67e3..ff35aed97a0 100644 --- a/docs/book/src/quick-start.md +++ b/docs/book/src/quick-start.md @@ -9,7 +9,7 @@ This Quick Start guide will cover: ## Prerequisites -- [go](https://golang.org/dl/) version v1.19.0+ +- [go](https://golang.org/dl/) version v1.20.0+ - [docker](https://docs.docker.com/install/) version 17.03+. - [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) version v1.11.3+. - Access to a Kubernetes v1.11.3+ cluster. @@ -31,7 +31,7 @@ Install [kubebuilder](https://sigs.k8s.io/kubebuilder): ```bash # download kubebuilder and install locally. -curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH) +curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)" chmod +x kubebuilder && mv kubebuilder /usr/local/bin/ ``` @@ -45,7 +45,7 @@ You can work with a master snapshot by installing from `https://go.kubebuilder.i @@ -53,20 +53,6 @@ Kubebuilder provides autocompletion support for Bash and Zsh via the command `ku Create a directory, and then run the init command inside of it to initialize a new project. Follows an example. - - ```bash mkdir -p ~/projects/guestbook cd ~/projects/guestbook @@ -96,7 +82,7 @@ kubebuilder create api --group webapp --version v1 --kind Guestbook

Press Options

If you press `y` for Create Resource [y/n] and for Create Controller [y/n] then this will create the files `api/v1/guestbook_types.go` where the API is defined -and the `controllers/guestbook_controller.go` where the reconciliation business logic is implemented for this Kind(CRD). +and the `internal/controllers/guestbook_controller.go` where the reconciliation business logic is implemented for this Kind(CRD). @@ -110,7 +96,7 @@ If you are editing the API definitions, generate the manifests such as Custom Re make manifests ``` -
Click here to see an example. `(api/v1/guestbook_types.go)` +
Click here to see an example. (api/v1/guestbook_types.go)

```go @@ -262,4 +248,4 @@ complexities of achieving this goal while allowing users to customize the genera [go-modules-blogpost]: https://blog.golang.org/using-go-modules [envtest]: https://book.kubebuilder.io/reference/testing/envtest.html [architecture-concept-diagram]: architecture.md -[kustomize]: https://github.com/kubernetes-sigs/kustomize \ No newline at end of file +[kustomize]: https://github.com/kubernetes-sigs/kustomize diff --git a/docs/book/src/reference/completion.md b/docs/book/src/reference/completion.md index a30635c7e0e..9a838ad05a0 100644 --- a/docs/book/src/reference/completion.md +++ b/docs/book/src/reference/completion.md @@ -1,5 +1,5 @@ # Enabling shell autocompletion -The Kubebuilder completion script can be generated with the command `kubebuilder completion [bash|zsh|powershell]`. +The Kubebuilder completion script can be generated with the command `kubebuilder completion [bash|fish|powershell|zsh]`. Note that sourcing the completion script in your shell enables Kubebuilder autocompletion.