From 6ee9ca80a0ead593041fc82cc7adb6d30660a27f Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Fri, 22 May 2026 16:58:23 -0600 Subject: [PATCH 1/2] generate-docs: Clean up maturity level notes Format our maturity level banners using markdown so that they look better in rendered help and generated docs. Omit the feature enablement notice in the top-level help when we generate docs, since it's not interesting on the docs website. Signed-off-by: Adam Wolfe Gordon --- cmd/crossplane/docs.go | 12 ++++++++++++ internal/maturity/maturity.go | 13 +++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/cmd/crossplane/docs.go b/cmd/crossplane/docs.go index 2ab4591..ee35bef 100644 --- a/cmd/crossplane/docs.go +++ b/cmd/crossplane/docs.go @@ -200,6 +200,13 @@ func normalizeDetail(detail string, headingLevel int) string { bqRE := regexp.MustCompile(`^> \*\*(\w+):\*\* `) bqMatch := bqRE.FindStringSubmatch(line) if bqMatch != nil { + // Omit the feature enablement message from the top-level command + // detail, since it's not useful in the generated docs. It's a + // little gross that we're hard-coding this, but it's good enough. + if strings.Contains(line, "Alpha and beta features are enabled.") { + continue + } + bq = true fmt.Fprintf(&sb, "{{}}\n", strings.ToLower(bqMatch[1])) line = strings.TrimPrefix(line, bqMatch[0]) @@ -227,6 +234,11 @@ func normalizeDetail(detail string, headingLevel int) string { sb.WriteString(line + "\n") } + // Close the "hint" box if it appeared at the very end of the detail. + if bq { + sb.WriteString("{{< /hint >}}\n") + } + return strings.TrimSpace(sb.String()) } diff --git a/internal/maturity/maturity.go b/internal/maturity/maturity.go index 09d8198..d7efea9 100644 --- a/internal/maturity/maturity.go +++ b/internal/maturity/maturity.go @@ -73,13 +73,13 @@ func Apply(app *kong.Application, enabled map[Level]bool) { switch { case enabled[LevelBeta] && enabled[LevelAlpha]: - detailStr = "Alpha and beta features are enabled. Manage enabled features with \"crossplane config set\"." + detailStr = "> **Note:** Alpha and beta features are enabled. Manage enabled features with \"crossplane config set\"." case enabled[LevelBeta]: - detailStr = "Beta features are enabled. Manage enabled features with \"crossplane config set\"." + detailStr = "> **Note:** Beta features are enabled. Manage enabled features with \"crossplane config set\"." case enabled[LevelAlpha]: - detailStr = "Alpha features are enabled. Manage enabled features with \"crossplane config set\"." + detailStr = "> **Note:** Alpha features are enabled. Manage enabled features with \"crossplane config set\"." default: - detailStr = "Alpha and beta features are disabled. To enable them use \"crossplane config set\"." + detailStr = "> **Note:** Alpha and beta features are disabled. To enable them use \"crossplane config set\"." } app.Detail += "\n\n" + detailStr @@ -100,9 +100,10 @@ func effectiveLevel(n *kong.Node) Level { } func detailForLevel(l Level, detail string) string { + // Detail is markdown-formatted, so format our banners as blockquotes. banners := map[Level]string{ - LevelAlpha: "NOTE: Alpha features are experimental and may be changed or removed in a future release.", - LevelBeta: "NOTE: Beta features may be changed in a future release.", + LevelAlpha: "> **Note:** Alpha features are experimental and may change or disappear in a future release.", + LevelBeta: "> **Note:** Beta features may change in a future release.", } if b := banners[l]; b != "" { From 890c04b72507826d5767d859a30bf88b2f6cd458 Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Fri, 22 May 2026 16:59:33 -0600 Subject: [PATCH 2/2] Fix vale errors in help The crossplane/docs repository uses the vale tool to lint prose. It's a little overzealous sometimes, but overall helpful, and currently complains about a ton of issues in our help text. Fix as many issues as possible. Use a special spell check (to be introduced in the docs repo) to avoid complaints about lower-case `crossplane`, since it's the command name. The remaining issues we can't fix are: - The abbreviation `config` in the `crossplane config` command. - The abbreviation `k8s` in the flag help for `crossplane dependency add`. - The abbreviation `admin` in `cluster-admin` in the help for `crossplane project run`. Signed-off-by: Adam Wolfe Gordon --- cmd/crossplane/composition/generate.go | 12 +++--- cmd/crossplane/composition/help/generate.md | 6 +-- cmd/crossplane/config/config.go | 4 +- cmd/crossplane/config/help/config.md | 4 +- cmd/crossplane/config/set.go | 2 +- .../convert/compositionenvironment/cmd.go | 6 +-- .../help/composition-environment.md | 6 +-- cmd/crossplane/convert/help/convert.md | 2 +- cmd/crossplane/dependency/add.go | 8 ++-- cmd/crossplane/dependency/help/add.md | 13 +++--- .../dependency/help/update-cache.md | 8 ++-- .../docs-templates/command-reference.md.tmpl | 8 ++++ cmd/crossplane/function/help/generate.md | 6 +-- cmd/crossplane/main.go | 4 +- cmd/crossplane/project/help/build.md | 25 ++++++------ cmd/crossplane/project/help/init.md | 4 +- cmd/crossplane/project/help/push.md | 12 +++--- cmd/crossplane/project/help/run.md | 8 ++-- cmd/crossplane/project/help/stop.md | 13 +++--- cmd/crossplane/project/push.go | 6 +-- cmd/crossplane/project/run.go | 2 +- cmd/crossplane/render/engine.go | 6 +-- cmd/crossplane/render/op/cmd.go | 6 +-- cmd/crossplane/render/op/help/render.md | 22 +++++----- cmd/crossplane/render/xr/cmd.go | 8 ++-- cmd/crossplane/render/xr/help/render.md | 36 ++++++++--------- cmd/crossplane/top/help/top.md | 14 +++---- cmd/crossplane/trace/help/trace.md | 40 +++++++++---------- cmd/crossplane/trace/trace.go | 20 +++++----- cmd/crossplane/validate/cmd.go | 8 ++-- cmd/crossplane/validate/help/validate.md | 40 ++++++++++--------- cmd/crossplane/xpkg/batch.go | 38 +++++++++--------- cmd/crossplane/xpkg/build.go | 12 +++--- cmd/crossplane/xpkg/extract.go | 8 ++-- cmd/crossplane/xpkg/help/build.md | 25 ++++++------ cmd/crossplane/xpkg/help/init.md | 17 ++++---- cmd/crossplane/xpkg/help/install.md | 9 +++-- cmd/crossplane/xpkg/help/push.md | 13 +++--- cmd/crossplane/xpkg/help/update.md | 5 ++- cmd/crossplane/xpkg/help/xpkg.md | 14 +++---- cmd/crossplane/xpkg/init.go | 6 +-- cmd/crossplane/xpkg/install.go | 8 ++-- cmd/crossplane/xpkg/update.go | 3 +- cmd/crossplane/xrd/convert.go | 36 ++++------------- cmd/crossplane/xrd/generate.go | 10 ++--- cmd/crossplane/xrd/help/convert.md | 38 ++++++++++++++++++ cmd/crossplane/xrd/help/generate.md | 9 ++--- 47 files changed, 316 insertions(+), 294 deletions(-) create mode 100644 cmd/crossplane/xrd/help/convert.md diff --git a/cmd/crossplane/composition/generate.go b/cmd/crossplane/composition/generate.go index 150f3e9..7d5cc73 100644 --- a/cmd/crossplane/composition/generate.go +++ b/cmd/crossplane/composition/generate.go @@ -53,12 +53,12 @@ const ( ) type generateCmd struct { - XRD string `arg:"" help:"Path to the CompositeResourceDefinition (XRD) file."` - Name string `help:"Name prefix for the composition." optional:""` - Plural string `help:"Custom plural for the CompositeTypeRef.Kind." optional:""` - Path string `help:"Output file path override." optional:""` - ProjectFile string `default:"crossplane-project.yaml" help:"Path to project definition file." short:"f"` - CacheDir string `env:"CROSSPLANE_XPKG_CACHE" help:"Directory for cached xpkg package contents." name:"cache-dir"` + XRD string `arg:"" help:"Path to the CompositeResourceDefinition (XRD) file."` + Name string `help:"Name prefix for the composition." optional:""` + Plural string `help:"Custom plural for the referenced kind." optional:""` + Path string `help:"Output file." optional:""` + ProjectFile string `default:"crossplane-project.yaml" help:"Path to project definition file." short:"f"` + CacheDir string `env:"CROSSPLANE_XPKG_CACHE" help:"Directory for cached xpkg package contents." name:"cache-dir"` projFS afero.Fs apisFS afero.Fs diff --git a/cmd/crossplane/composition/help/generate.md b/cmd/crossplane/composition/help/generate.md index 00486a2..66455be 100644 --- a/cmd/crossplane/composition/help/generate.md +++ b/cmd/crossplane/composition/help/generate.md @@ -1,5 +1,5 @@ The `composition generate` command creates a Composition for a -CompositeResourceDefinition (XRD). The Composition is scaffolded with a single +CompositeResourceDefinition (XRD). The generated Composition contains a single pipeline step that runs `function-auto-ready`, which is automatically added to the project's dependencies if it isn't already present. @@ -19,13 +19,13 @@ crossplane composition generate examples/network/network-aws.yaml --name aws ``` Generate a Composition with a custom plural form, useful when automatic -pluralization is wrong (e.g., "postgres"): +pluralization is wrong (for example, "postgres"): ```shell crossplane composition generate examples/database/database.yaml --plural postgreses ``` -Write the generated Composition to a specific path within the project: +Write the generated Composition to a specific path: ```shell crossplane composition generate apis/network/definition.yaml --path apis/network/composition.yaml diff --git a/cmd/crossplane/config/config.go b/cmd/crossplane/config/config.go index d73b969..fb2570d 100644 --- a/cmd/crossplane/config/config.go +++ b/cmd/crossplane/config/config.go @@ -30,8 +30,8 @@ type ConfigPath string //nolint:revive // The "Config" stutter is intentional; t // Cmd groups subcommands for inspecting and modifying the CLI config file. type Cmd struct { // Keep subcommands sorted alphabetically. - Set setCmd `cmd:"" help:"Set a config value and write it to the config file."` - View viewCmd `cmd:"" help:"Print the current effective config as YAML."` + Set setCmd `cmd:"" help:"Set a value and write it to the configuration file."` + View viewCmd `cmd:"" help:"Print the current effective configuration as YAML."` } // Help returns the extended help for the config command. diff --git a/cmd/crossplane/config/help/config.md b/cmd/crossplane/config/help/config.md index 91f2e07..8803afb 100644 --- a/cmd/crossplane/config/help/config.md +++ b/cmd/crossplane/config/help/config.md @@ -1,5 +1,5 @@ The `config` command manages the configuration file for the `crossplane` -CLI. The config file location is, in priority order: +CLI. The configuration file location is, in priority order: 1. The `--config` flag. 2. The `CROSSPLANE_CONFIG` environment variable. @@ -7,7 +7,7 @@ CLI. The config file location is, in priority order: ## Examples -Show the current effective config: +Show the current effective configuration: ```shell crossplane config view diff --git a/cmd/crossplane/config/set.go b/cmd/crossplane/config/set.go index c1b8cfd..b85fc5c 100644 --- a/cmd/crossplane/config/set.go +++ b/cmd/crossplane/config/set.go @@ -29,7 +29,7 @@ import ( ) type setCmd struct { - Key string `arg:"" help:"Config key to set (e.g. features.enableAlpha)."` + Key string `arg:"" help:"Key to set (for example, features.enableAlpha)."` Value string `arg:"" help:"Value to assign."` fs afero.Fs diff --git a/cmd/crossplane/convert/compositionenvironment/cmd.go b/cmd/crossplane/convert/compositionenvironment/cmd.go index 82a38cb..5a50180 100644 --- a/cmd/crossplane/convert/compositionenvironment/cmd.go +++ b/cmd/crossplane/convert/compositionenvironment/cmd.go @@ -41,12 +41,12 @@ var helpDetail string // Cmd arguments and flags for converting a Composition to use function-environment-configs. type Cmd struct { // Arguments. - InputFile string `arg:"" default:"-" help:"The Composition file to be converted. If not specified or '-', stdin will be used." optional:"" predictor:"file" type:"path"` + InputFile string `arg:"" default:"-" help:"The Composition file to convert or '-' for stdin." optional:"" predictor:"file" type:"path"` // Flags. - OutputFile string `help:"The file to write the generated Composition to. If not specified, stdout will be used." placeholder:"PATH" predictor:"file" short:"o" type:"path"` + OutputFile string `help:"The file to write the generated Composition to; omit for stdout." placeholder:"PATH" predictor:"file" short:"o" type:"path"` - FunctionEnvironmentConfigRef string `default:"function-environment-configs" help:"Name of the existing function-environment-configs Function, to be used to reference it." name:"function-environment-configs-ref"` + FunctionEnvironmentConfigRef string `default:"function-environment-configs" help:"Name of the installed function-environment-configs Function." name:"function-environment-configs-ref"` fs afero.Fs } diff --git a/cmd/crossplane/convert/compositionenvironment/help/composition-environment.md b/cmd/crossplane/convert/compositionenvironment/help/composition-environment.md index 8e0a206..c3365cc 100644 --- a/cmd/crossplane/convert/compositionenvironment/help/composition-environment.md +++ b/cmd/crossplane/convert/compositionenvironment/help/composition-environment.md @@ -1,11 +1,11 @@ The `composition convert composition-environment` command converts a Crossplane Composition to use `function-environment-configs` in place of native Composition -Environments, which were removed in Crossplane v1.18. +Environments (removed in Crossplane 1.18). It adds a function pipeline step using `crossplane-contrib/function-environment-configs` if needed. By default the -function is referenced as `function-environment-configs`, but this can be -overridden with `--function-environment-configs-ref`. +function name is `function-environment-configs`, but this can be overridden with +`--function-environment-configs-ref`. ## Examples diff --git a/cmd/crossplane/convert/help/convert.md b/cmd/crossplane/convert/help/convert.md index 6cd5f5e..13651d9 100644 --- a/cmd/crossplane/convert/help/convert.md +++ b/cmd/crossplane/convert/help/convert.md @@ -1,6 +1,6 @@ The `composition convert` command converts a Crossplane composition to use a different version or migrate away from features that are no longer supported. -The currently supported conversions are: +The supported conversions are: - Native Composition Environment → `function-environment-configs` diff --git a/cmd/crossplane/dependency/add.go b/cmd/crossplane/dependency/add.go index b7c8095..13bb8bd 100644 --- a/cmd/crossplane/dependency/add.go +++ b/cmd/crossplane/dependency/add.go @@ -41,14 +41,14 @@ var addHelp string // addCmd adds a dependency to the current project. type addCmd struct { - Package string `arg:"" help:"Package to be added (e.g. xpkg.crossplane.io/crossplane-contrib/provider-nop:v0.5.0, k8s:v1.33.0, a git repo URL, or an HTTP URL)."` - ProjectFile string `default:"crossplane-project.yaml" help:"Path to project definition file." short:"f"` - CacheDir string `env:"CROSSPLANE_XPKG_CACHE" help:"Directory for cached xpkg package contents." name:"cache-dir"` + Package string `arg:"" help:"Package to add (xpkg OCI reference, k8s:, git repository URL, or HTTP(S) URL)."` + ProjectFile string `default:"crossplane-project.yaml" help:"Path to project definition file." short:"f"` + CacheDir string `env:"CROSSPLANE_XPKG_CACHE" help:"Directory for cached xpkg package contents." name:"cache-dir"` // Flags for specific dependency types. APIOnly bool `help:"Mark an xpkg dependency as API-only (not a runtime dependency)." name:"api-only"` GitRef string `help:"Git ref for CRD dependencies (branch, tag, or commit SHA)." name:"git-ref"` - GitPath string `help:"Path within the git repository for CRD dependencies." name:"git-path"` + GitPath string `help:"Path to CRDs in the git repository." name:"git-path"` } func (c *addCmd) Help() string { diff --git a/cmd/crossplane/dependency/help/add.md b/cmd/crossplane/dependency/help/add.md index b6c19e9..df9a1bf 100644 --- a/cmd/crossplane/dependency/help/add.md +++ b/cmd/crossplane/dependency/help/add.md @@ -1,6 +1,6 @@ -The `dependency add` command adds a dependency to a Crossplane Project. The -dependency is added to the project's metadata file and language bindings -(schemas) are generated its CRDs when applicable. +The `dependency add` command adds a dependency to a Crossplane Project metadata +file and generates language bindings (schemas) for the dependency package's +CRDs. ## Dependency types @@ -13,10 +13,9 @@ Projects support three kinds of dependencies: An xpkg dependency may be either a runtime dependency (the default) or a build-time dependency. Runtime dependencies become dependencies of the Configuration produced by `crossplane project build` or `crossplane project run` -and thus get installed into a cluster when the Configuration is -installed. Build-time dependencies, on the other hand, are used only for schema -generation and do not become Configuration dependencies. Use the `--api-only` -flag to indicate that an xpkg dependency should be build-time only. +and are thus installed into a cluster with the Configuration. Build-time +dependencies have schemas generated but don't become Configuration +dependencies. Use the `--api-only` flag to add a build-time xpkg dependency. Non-xpkg dependencies are always build-time dependencies. diff --git a/cmd/crossplane/dependency/help/update-cache.md b/cmd/crossplane/dependency/help/update-cache.md index 098022e..b016009 100644 --- a/cmd/crossplane/dependency/help/update-cache.md +++ b/cmd/crossplane/dependency/help/update-cache.md @@ -1,6 +1,4 @@ The `dependency update-cache` command updates the local dependency cache for the -current project. It caches all dependencies listed in the -`crossplane-project.yaml` file and re-generates language bindings (schemas) for -them if needed. Any dependency whose version is expressed as a semantic version -constraint will have the constraint re-resolved to a specific version (i.e., -schemas will be updated if a newer version is available). +current project. It re-resolves semantic version constraints to specific +versions (fetching newer versions if available), caches all dependencies, and +re-generates language bindings (schemas) for them if needed. diff --git a/cmd/crossplane/docs-templates/command-reference.md.tmpl b/cmd/crossplane/docs-templates/command-reference.md.tmpl index b1ff98c..72518e3 100644 --- a/cmd/crossplane/docs-templates/command-reference.md.tmpl +++ b/cmd/crossplane/docs-templates/command-reference.md.tmpl @@ -6,6 +6,11 @@ description: "Command reference for the Crossplane CLI" + + + + This documentation is for the `crossplane` CLI [[ .Version ]]. [[ range .Commands ]] @@ -43,3 +48,6 @@ crossplane [[ .Summary ]] [[ end ]]{{< /table >}} [[ end ]] [[ end ]] + + + diff --git a/cmd/crossplane/function/help/generate.md b/cmd/crossplane/function/help/generate.md index 7bc2f79..10901d7 100644 --- a/cmd/crossplane/function/help/generate.md +++ b/cmd/crossplane/function/help/generate.md @@ -1,7 +1,7 @@ The `function generate` command creates an embedded function in the specified -language under the project's `functions/` directory. If a path to a Composition -file is supplied, the new function is also idempotently added as a step to the -end of the Composition's pipeline. +language under the project's `functions/` directory. It optionally idempotently +adds the new function to end of a Composition's pipeline when given a +Composition path. ## Supported languages diff --git a/cmd/crossplane/main.go b/cmd/crossplane/main.go index c8a0a4e..574df37 100644 --- a/cmd/crossplane/main.go +++ b/cmd/crossplane/main.go @@ -75,7 +75,7 @@ type cli struct { // Subcommands. Cluster cluster.Cmd `cmd:"" help:"Inspect a Crossplane cluster." maturity:"beta"` Composition composition.Cmd `cmd:"" help:"Work with Crossplane Compositions."` - Config configcmd.Cmd `cmd:"" help:"View and modify the crossplane CLI config file."` + Config configcmd.Cmd `cmd:"" help:"View and update the crossplane CLI configuration file."` Dependency dependency.Cmd `cmd:"" help:"Manage dependencies of control plane Projects." maturity:"beta"` Function function.Cmd `cmd:"" help:"Work with functions in control plane Projects." maturity:"beta"` Operation operation.Cmd `cmd:"" help:"Work with Crossplane Operations." maturity:"alpha"` @@ -92,7 +92,7 @@ type cli struct { GenerateDocs docsCmd `cmd:"" help:"Generate command-reference docs in markdown format." hidden:""` // Flags. - ConfigPath string `env:"CROSSPLANE_CONFIG" help:"Path to the crossplane CLI config file." name:"config" placeholder:"PATH"` + ConfigPath string `env:"CROSSPLANE_CONFIG" help:"Path to the crossplane CLI configuration file." name:"config" placeholder:"PATH"` Verbose verboseFlag `help:"Print verbose logging statements." name:"verbose"` // Completion diff --git a/cmd/crossplane/project/help/build.md b/cmd/crossplane/project/help/build.md index 53dfa82..2ffab23 100644 --- a/cmd/crossplane/project/help/build.md +++ b/cmd/crossplane/project/help/build.md @@ -1,16 +1,17 @@ -The `project build` command builds a Crossplane Project into a set of xpkgs. It +The `project build` command builds a Crossplane Project into a set of xpkgs. It builds each embedded function in the project and a Configuration package that -ties everything together. A special `.xpkg` file containing all the built -packages is written to the project's output directory (`_output/` by -default). This file can be consumed by the `project push` command to push the -packages to an OCI registry. - -The repository for the built Configuration is taken from `spec.repository` in -`crossplane-project.yaml`. Override it for a single build with `--repository`. - -> **Important:** The repository is used to construct the function names used for -> embedded function references in compositions. The same repository must be -> specified when building and pushing a project. +ties everything together. The output of the build is a special `.xpkg` file +containing all the built packages, placed in the project's output directory +(`_output/` by default). The `project push` command can consume packges from the +output file and push them to an OCI registry. + +The `build `command constructs the repository for the built Configuration from +`spec.repository` in `crossplane-project.yaml`. Override it for a single build +with `--repository`. + +> **Important:** The repository influences the function names used for embedded +> function references in compositions. You must specify the same repository when +> building and pushing a project. The build reuses the dependency cache populated by `crossplane dependency add` and `crossplane dependency update-cache`. Override the cache location with diff --git a/cmd/crossplane/project/help/init.md b/cmd/crossplane/project/help/init.md index 4d571ac..27d2fbd 100644 --- a/cmd/crossplane/project/help/init.md +++ b/cmd/crossplane/project/help/init.md @@ -3,8 +3,8 @@ creates a target directory containing a minimal `crossplane-project.yaml` along with the standard sub-directories used by the DevEx tooling: `apis`, `functions`, `examples`, `tests`, and `operations`. -The project name must be a valid DNS-1035 label. By default the project is -created in a new directory named after the project; use `--directory` (`-d`) to +The project name must be a valid DNS-1035 label. By default, the `init` command +creates a new directory named after the project; use `--directory` (`-d`) to choose a different target directory. ## Examples diff --git a/cmd/crossplane/project/help/push.md b/cmd/crossplane/project/help/push.md index 2414a1b..de23b2b 100644 --- a/cmd/crossplane/project/help/push.md +++ b/cmd/crossplane/project/help/push.md @@ -1,17 +1,17 @@ The `project push` command pushes the xpkgs produced by `crossplane project build` to an OCI registry. It pushes both the Configuration package and any -embedded function packages built from the project. Credentials for the registry -are taken from the local `docker` configuration; pushing to a private registry -may require a prior `docker login`. +embedded function packages built from the project. The `push` command uses +registry credentials from the local `docker` configuration; pushing to a private +registry may require a prior `docker login`. By default the command pushes to the repository specified in `crossplane-project.yaml` and uses a tag generated from the package contents. Override either with `--repository` and `--tag` (`-t`). To push a specific package file instead of the project's default output, use `--package-file`. -> **Important:** The repository is used to construct the function names used for -> embedded function references in compositions. The same repository must be -> specified when building and pushing a project. +> **Important:** The repository influences the function names used for embedded +> function references in compositions. You must specify the same repository when +> building and pushing a project. ## Examples diff --git a/cmd/crossplane/project/help/run.md b/cmd/crossplane/project/help/run.md index cbca5d6..4c68d10 100644 --- a/cmd/crossplane/project/help/run.md +++ b/cmd/crossplane/project/help/run.md @@ -10,14 +10,14 @@ This command: - Installs the project's Configuration on the control plane. - Updates kubeconfig so `kubectl` points at the development control plane. -By default the control plane is named after the project. Use +By default, `run` names the control plane after the project. Use `--control-plane-name` to choose a different name, which is useful when running multiple projects side-by-side. -The Crossplane version installed in the dev control plane can be pinned with -`--crossplane-version`; otherwise the latest stable version is used. +You can use a Crossplane version other than the latest stable version by +specifying the `--crossplane-version` flag. -Resources can be applied around the project install: +You can provide resources to apply around the project install: - `--init-resources` applies one or more files *before* installing the Configuration (useful for things like `ImageConfig`). diff --git a/cmd/crossplane/project/help/stop.md b/cmd/crossplane/project/help/stop.md index 38cf5e1..8b33a89 100644 --- a/cmd/crossplane/project/help/stop.md +++ b/cmd/crossplane/project/help/stop.md @@ -1,11 +1,12 @@ The `project stop` command tears down the local development control plane -previously created by `crossplane project run`. The KIND cluster and the local -OCI registry are both removed. +created by `crossplane project run`. It removes both the KIND cluster and the +local OCI registry. -When run from a project directory the control plane name is derived from the -project name. When run outside a project directory, pass `--control-plane-name` -to identify the control plane to tear down. Pass `--registry-dir` to point at -the local registry directory used by `project run` if it was overridden there. +When run from a project directory, the `stop` command tears down the control +plane whose name matches the project name. When run outside a project directory, +pass `--control-plane-name` to identify the control plane to tear down. If you +passed `--registry-dir` to `up project run`, pass it to `up project stop` as +well to clean up the registry data. ## Examples diff --git a/cmd/crossplane/project/push.go b/cmd/crossplane/project/push.go index 4e16d74..da30836 100644 --- a/cmd/crossplane/project/push.go +++ b/cmd/crossplane/project/push.go @@ -46,11 +46,11 @@ var pushHelp string // pushCmd pushes a built project to an OCI registry. type pushCmd struct { - ProjectFile string `default:"crossplane-project.yaml" help:"Path to project definition." short:"f"` + ProjectFile string `default:"crossplane-project.yaml" help:"Path to project definition." short:"f"` Repository string `help:"Override the repository in the project file." optional:""` - Tag string `default:"" help:"Tag for the pushed package. If not provided, a semver tag will be generated." short:"t"` + Tag string `default:"" help:"Tag for the pushed package. Defaults to a time-based semver-like tag." short:"t"` PackageFile string `help:"Package file to push. Defaults to /.xpkg." optional:""` - OutputDir string `default:"_output" help:"Directory containing built packages." short:"o"` + OutputDir string `default:"_output" help:"Directory containing built packages." short:"o"` MaxConcurrency uint `default:"8" help:"Max concurrent function pushes."` InsecureSkipTLSVerify bool `help:"[INSECURE] Skip verifying TLS certificates."` diff --git a/cmd/crossplane/project/run.go b/cmd/crossplane/project/run.go index e005ac6..2bf2728 100644 --- a/cmd/crossplane/project/run.go +++ b/cmd/crossplane/project/run.go @@ -68,7 +68,7 @@ type runCmd struct { ControlPlaneName string `help:"Name of the dev control plane. Defaults to project name."` CrossplaneVersion string `help:"Version of Crossplane to install."` RegistryDir string `help:"Directory for local registry images."` - ClusterAdmin bool `default:"true" help:"Allow Crossplane cluster admin." negatable:""` + ClusterAdmin bool `default:"true" help:"Grant Crossplane the cluster-admin role." negatable:""` Timeout time.Duration `default:"5m" help:"Max wait for project readiness."` InitResources []string `help:"Resources to apply before installing." type:"path"` ExtraResources []string `help:"Resources to apply after installing." type:"path"` diff --git a/cmd/crossplane/render/engine.go b/cmd/crossplane/render/engine.go index 5095da4..22aeea6 100644 --- a/cmd/crossplane/render/engine.go +++ b/cmd/crossplane/render/engine.go @@ -50,9 +50,9 @@ type Engine interface { // EngineFlags contains flags for configuring the render engine. It is embedded // by render command structs to provide shared engine configuration. type EngineFlags struct { - CrossplaneVersion string `help:"Version of the Crossplane image to use for rendering (e.g. v2.3.0). Defaults to the latest stable version." placeholder:"VERSION" xor:"crossplane-selector"` - CrossplaneImage string `help:"Override the full Crossplane Docker image reference for rendering." placeholder:"IMAGE" xor:"crossplane-selector"` - CrossplaneBinary string `help:"Path to a local crossplane binary to use instead of Docker." placeholder:"PATH" type:"existingfile" xor:"crossplane-selector"` + CrossplaneVersion string `help:"Version of the Crossplane image to use for rendering. Defaults to the latest stable version." placeholder:"VERSION" xor:"crossplane-selector"` + CrossplaneImage string `help:"Override the full Crossplane Docker image reference for rendering." placeholder:"IMAGE" xor:"crossplane-selector"` + CrossplaneBinary string `help:"Path to a local crossplane binary to use instead of Docker." placeholder:"PATH" type:"existingfile" xor:"crossplane-selector"` } // NewEngineFromFlags creates an Engine from the flag configuration. If a binary diff --git a/cmd/crossplane/render/op/cmd.go b/cmd/crossplane/render/op/cmd.go index 70d8715..36bb60b 100644 --- a/cmd/crossplane/render/op/cmd.go +++ b/cmd/crossplane/render/op/cmd.go @@ -61,14 +61,14 @@ type Cmd struct { render.EngineFlags `prefix:""` // Arguments. - Operation string `arg:"" help:"A YAML file specifying the Operation to render." predictor:"yaml_file" type:"existingfile"` - Functions string `arg:"" help:"A YAML file or directory of YAML files specifying the operation functions to use to render the Operation. May be omitted when running in a project." optional:"" predictor:"yaml_file_or_directory" type:"path"` + Operation string `arg:"" help:"A YAML file specifying the Operation to render." predictor:"yaml_file" type:"existingfile"` + Functions string `arg:"" help:"A YAML file or directory of YAML files specifying the Composition Functions to use to render the XR. Optional when running in a project." optional:"" predictor:"yaml_file_or_directory" type:"path"` // Flags. Keep them in alphabetical order. ContextFiles map[string]string `help:"Comma-separated context key-value pairs to pass to the function pipeline. Values must be files containing JSON." mapsep:"" predictor:"file"` ContextValues map[string]string `help:"Comma-separated context key-value pairs to pass to the function pipeline. Values must be JSON. Keys take precedence over --context-files." mapsep:""` FunctionCredentials string `help:"A YAML file or directory of YAML files specifying credentials to use for functions." placeholder:"PATH" predictor:"yaml_file_or_directory" type:"path"` - FunctionAnnotations []string `help:"Override function annotations for all functions. Can be repeated." placeholder:"KEY=VALUE" short:"a"` + FunctionAnnotations []string `help:"Override function annotations for all functions. Provide multiple annotations by repeating the argument." placeholder:"KEY=VALUE" short:"a"` IncludeContext bool `help:"Include the context in the rendered output as a resource of kind: Context." short:"c"` IncludeFullOperation bool `help:"Include a direct copy of the input Operation's spec and metadata fields in the rendered output." short:"o"` IncludeFunctionResults bool `help:"Include informational and warning messages from functions in the rendered output as resources of kind: Result." short:"r"` diff --git a/cmd/crossplane/render/op/help/render.md b/cmd/crossplane/render/op/help/render.md index cdb3e83..39ab9e5 100644 --- a/cmd/crossplane/render/op/help/render.md +++ b/cmd/crossplane/render/op/help/render.md @@ -11,32 +11,32 @@ would produce. ## Function runtime configuration -Operation Functions are pulled and run using Docker by default. You can add the -following annotations to each Function to change how they're run: +By default, the `render` command pulls and runs Operation Functions using +Docker. You can add the following annotations to each Function to change how +they're run: | Annotation | Purpose | | ---------- | ------- | -| `render.crossplane.io/runtime: "Development"` | Connect to a Function that is already running, instead of using Docker. This is useful to develop and debug new Functions. The Function must be listening at `localhost:9443` and running with the `--insecure` flag. | -| `render.crossplane.io/runtime-development-target: "dns:///example.org:7443"` | Connect to a Function running somewhere other than `localhost:9443`. The target uses gRPC target syntax (e.g., `dns:///example.org:7443` or simply `example.org:7443`). | +| `render.crossplane.io/runtime: "Development"` | Connect to a Function running locally, instead of using Docker, for example when developing or debugging a new Function. The Function must be listening at `localhost:9443` and running with the `--insecure` flag. | +| `render.crossplane.io/runtime-development-target: "dns:///example.org:7443"` | Connect to a Function running somewhere other than `localhost:9443`. The target uses gRPC target syntax (for example, `dns:///example.org:7443` or `example.org:7443`). | | `render.crossplane.io/runtime-docker-cleanup: "Orphan"` | Don't stop the Function's Docker container after rendering. | -| `render.crossplane.io/runtime-docker-name: ""` | Create a container with that name and reuse it as long as it is running or can be restarted. | +| `render.crossplane.io/runtime-docker-name: ""` | Create or reuse a container with the given name. Restart the container if needed. | | `render.crossplane.io/runtime-docker-pull-policy: "Always"` | Always pull the Function's package, even if it already exists locally. Other supported values are `Never` or `IfNotPresent`. | | `render.crossplane.io/runtime-docker-publish-address: "0.0.0.0"` | Host address that Docker should publish the Function's container port to. Defaults to `127.0.0.1` (localhost only). Use `0.0.0.0` to publish to all host network interfaces, enabling access from remote machines. | | `render.crossplane.io/runtime-docker-target: "docker-host"` | Address that the render CLI should use to connect to the Function's Docker container. If not specified, uses the publish address. | Use the standard `DOCKER_HOST`, `DOCKER_API_VERSION`, `DOCKER_CERT_PATH`, and `DOCKER_TLS_VERIFY` environment variables to configure how this command connects -to the Docker daemon. See the [Docker environment -variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) +to the Docker daemon. See the +[Docker environment variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) reference. ## Project support When running `render` in a Crossplane Project (any directory containing a -`crossplane-project.yaml` project metadata file), it is optional to provide the -functions file as an argument. If the functions file is omitted, function -dependencies defined in the project metadata will be used. Embedded functions -from the project will also be built and run by render. +`crossplane-project.yaml` project metadata file), you may omit the functions +file argument in favor of using function dependencies defined in the project +metadata and embedded functions from the project. ## Examples diff --git a/cmd/crossplane/render/xr/cmd.go b/cmd/crossplane/render/xr/cmd.go index e2074b2..5f4a317 100644 --- a/cmd/crossplane/render/xr/cmd.go +++ b/cmd/crossplane/render/xr/cmd.go @@ -64,9 +64,9 @@ type Cmd struct { render.EngineFlags `prefix:""` // Arguments. - CompositeResource string `arg:"" help:"A YAML file specifying the composite resource (XR) to render." predictor:"yaml_file" type:"existingfile"` - Composition string `arg:"" help:"A YAML file specifying the Composition to use to render the XR. Must be mode: Pipeline." predictor:"yaml_file" type:"existingfile"` - Functions string `arg:"" help:"A YAML file or directory of YAML files specifying the Composition Functions to use to render the XR. May be omitted when running in a project." optional:"" predictor:"yaml_file_or_directory" type:"path"` + CompositeResource string `arg:"" help:"A YAML file specifying the composite resource (XR) to render." predictor:"yaml_file" type:"existingfile"` + Composition string `arg:"" help:"A YAML file specifying the Composition to use to render the XR. Must be mode: Pipeline." predictor:"yaml_file" type:"existingfile"` + Functions string `arg:"" help:"A YAML file or directory of YAML files specifying the Composition Functions to use to render the XR. Optional when running in a project." optional:"" predictor:"yaml_file_or_directory" type:"path"` // Flags. Keep them in alphabetical order. ContextFiles map[string]string `help:"Comma-separated context key-value pairs to pass to the Function pipeline. Values must be files containing JSON/YAML." mapsep:"" predictor:"file"` @@ -79,7 +79,7 @@ type Cmd struct { RequiredSchemas string `help:"A directory of JSON files specifying OpenAPI v3 schemas (from kubectl get --raw /openapi/v3/)." placeholder:"DIR" predictor:"directory" short:"s" type:"path"` IncludeContext bool `help:"Include the context in the rendered output as a resource of kind: Context." short:"c"` FunctionCredentials string `help:"A YAML file or directory of YAML files specifying credentials to use for Functions to render the XR." placeholder:"PATH" predictor:"yaml_file_or_directory" type:"path"` - FunctionAnnotations []string `help:"Override function annotations for all functions. Can be repeated." placeholder:"KEY=VALUE" short:"a"` + FunctionAnnotations []string `help:"Override function annotations for all functions. Provide multiple annotations by repeating the argument." placeholder:"KEY=VALUE" short:"a"` CacheDir string `env:"CROSSPLANE_XPKG_CACHE" help:"Directory for cached xpkg package contents." name:"cache-dir"` MaxConcurrency uint `default:"8" help:"Maximum concurrency for building embedded functions."` diff --git a/cmd/crossplane/render/xr/help/render.md b/cmd/crossplane/render/xr/help/render.md index 682921b..fef823f 100644 --- a/cmd/crossplane/render/xr/help/render.md +++ b/cmd/crossplane/render/xr/help/render.md @@ -1,13 +1,11 @@ The `composition render` command shows you what resources a Composition would create or mutate by running the composition locally and printing its results. It -also prints any changes that would be made to the status of the XR. It runs the -Crossplane render engine (either in a Docker container or via a local binary) to -produce high-fidelity output that matches what the real reconciler would -produce. +also prints any changes to the status of the XR. It runs the Crossplane render +engine (either in a Docker container or via a local binary) to produce +high-fidelity output that matches what the real reconciler would produce. -By default, only the `status` field and `metadata.name` of the XR are -printed. Use `--include-full-xr` (`-x`) to include the full XR `spec` and -`metadata`. +By default, `render` prints only the `status` and `metadata.name` of the XR. Use +`--include-full-xr` (`-x`) to include the full XR `spec` and `metadata`. > **Important:** This command runs composition functions and the Crossplane > render engine using Docker by default, requiring a working Docker @@ -16,32 +14,32 @@ printed. Use `--include-full-xr` (`-x`) to include the full XR `spec` and ## Function runtime configuration -Composition Functions are pulled and run using Docker by default. You can add -the following annotations to each Function to change how they're run: +By default, the `render` command pulls and runs Composition Functions using +Docker. You can add the following annotations to each Function to change how +they're run: | Annotation | Purpose | | ---------- | ------- | -| `render.crossplane.io/runtime: "Development"` | Connect to a Function that is already running, instead of using Docker. This is useful to develop and debug new Functions. The Function must be listening at `localhost:9443` and running with the `--insecure` flag. | -| `render.crossplane.io/runtime-development-target: "dns:///example.org:7443"` | Connect to a Function running somewhere other than `localhost:9443`. The target uses gRPC target syntax (e.g., `dns:///example.org:7443` or simply `example.org:7443`). | +| `render.crossplane.io/runtime: "Development"` | Connect to a Function running locally, instead of using Docker, for example when developing or debugging a new Function. The Function must be listening at `localhost:9443` and running with the `--insecure` flag. | +| `render.crossplane.io/runtime-development-target: "dns:///example.org:7443"` | Connect to a Function running somewhere other than `localhost:9443`. The target uses gRPC target syntax (for example, `dns:///example.org:7443` or `example.org:7443`). | | `render.crossplane.io/runtime-docker-cleanup: "Orphan"` | Don't stop the Function's Docker container after rendering. | -| `render.crossplane.io/runtime-docker-name: ""` | Create a container with that name and reuse it as long as it is running or can be restarted. | +| `render.crossplane.io/runtime-docker-name: ""` | Create or reuse a container with the given name. Restart the container if needed. | | `render.crossplane.io/runtime-docker-pull-policy: "Always"` | Always pull the Function's package, even if it already exists locally. Other supported values are `Never` or `IfNotPresent`. | | `render.crossplane.io/runtime-docker-publish-address: "0.0.0.0"` | Host address that Docker should publish the Function's container port to. Defaults to `127.0.0.1` (localhost only). Use `0.0.0.0` to publish to all host network interfaces, enabling access from remote machines. | | `render.crossplane.io/runtime-docker-target: "docker-host"` | Address that the render CLI should use to connect to the Function's Docker container. If not specified, uses the publish address. | Use the standard `DOCKER_HOST`, `DOCKER_API_VERSION`, `DOCKER_CERT_PATH`, and `DOCKER_TLS_VERIFY` environment variables to configure how this command connects -to the Docker daemon. See the [Docker environment -variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) +to the Docker daemon. See the +[Docker environment variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) reference. ## Project support When running `render` in a Crossplane Project (any directory containing a -`crossplane-project.yaml` project metadata file), it is optional to provide the -functions file as an argument. If the functions file is omitted, function -dependencies defined in the project metadata will be used. Embedded functions -from the project will also be built and run by render. +`crossplane-project.yaml` project metadata file), you may omit the functions +file argument in favor of using function dependencies defined in the project +metadata and embedded functions from the project. ## Function context @@ -79,7 +77,7 @@ spec: Required resources let a Composition request Crossplane objects on the cluster that aren't part of the Composition. Pass them with `--required-resources` -(`-e`) — a YAML file or directory of YAML files of resources to mock. Use this +(`-e`), a YAML file or directory of YAML files of resources to mock. Use this with a Function like [function-extra-resources](https://github.com/crossplane-contrib/function-extra-resources) or the built-in support in diff --git a/cmd/crossplane/top/help/top.md b/cmd/crossplane/top/help/top.md index cfcb2fd..1ae67b6 100644 --- a/cmd/crossplane/top/help/top.md +++ b/cmd/crossplane/top/help/top.md @@ -1,25 +1,23 @@ -The `cluster top` command returns current resource utilization (CPU and memory) -by Crossplane pods. Similar to `kubectl top pods`, it requires the [Metrics -Server](https://kubernetes-sigs.github.io/metrics-server/) to be correctly -configured and working on the server. +The `cluster top` command returns current resource usage (CPU and memory) by +Crossplane pods. Like `kubectl top pods`, it requires the +[Metrics Server](https://kubernetes-sigs.github.io/metrics-server/). ## Examples -Show resource utilization for all Crossplane pods in the `crossplane-system` +Show resource usage for all Crossplane pods in the `crossplane-system` namespace: ```shell crossplane cluster top ``` -Show resource utilization for all Crossplane pods in the `default` namespace: +Show resource usage for all Crossplane pods in the `default` namespace: ```shell crossplane cluster top -n default ``` -Add a summary of resource utilization for all Crossplane pods on top of the -results: +Add a summary of resource usage for all Crossplane pods on top of the results: ```shell crossplane cluster top -s diff --git a/cmd/crossplane/trace/help/trace.md b/cmd/crossplane/trace/help/trace.md index cd97412..d7958f4 100644 --- a/cmd/crossplane/trace/help/trace.md +++ b/cmd/crossplane/trace/help/trace.md @@ -1,6 +1,6 @@ The `resource trace` command traces a Crossplane resource (Claim, Composite, or -Managed Resource) to give a detailed view of its relationships — helpful for -troubleshooting. +Managed Resource) to give a detailed view of its relationships and help +troubleshoot compositions. The command requires a resource type and a resource name: @@ -8,12 +8,11 @@ The command requires a resource type and a resource name: crossplane resource trace ``` -Kubernetes-style `/` input works too — for example, `crossplane +Kubernetes-style `/` input works too: for example, `crossplane resource trace example.crossplane.io/my-xr`. -If needed the resource kind can be specified further as -`TYPE[.VERSION][.GROUP]`, for example `mykind.example.org` or -`mykind.v1alpha1.example.org`. +You can further specify the kind as `TYPE[.VERSION][.GROUP]` if needed; for +example, `mykind.example.org` or `mykind.v1alpha1.example.org`. By default, `crossplane resource trace` uses the Kubernetes configuration at `~/.kube/config`. Override with the `KUBECONFIG` environment variable. @@ -29,14 +28,13 @@ a [Graphviz](https://graphviz.org/docs/layouts/dot/) graph). ### Wide output Use `--output=wide` to print the full `Ready` and `Status` messages even when -they exceed 64 characters, and additional per-kind columns (for example, -composed resource names for composite resources, or image used for packages). +they exceed 64 characters, and other kind-specific printer columns. ### Graphviz dot output -Use `--output=dot` to print a textual [Graphviz -dot](https://graphviz.org/docs/layouts/dot/) graph. Pipe to `dot` to render an -image: +Use `--output=dot` to print a textual +[Graphviz dot](https://graphviz.org/docs/layouts/dot/) graph.Pipe to `dot` to +render an image: ```shell crossplane resource trace cluster.aws.platformref.upbound.io platform-ref-aws -o dot | dot -Tpng -o graph.png @@ -50,20 +48,20 @@ name and namespace. ## Print package dependencies -The `--show-package-dependencies` flag controls how package dependencies are -displayed: +The `--show-package-dependencies` flag controls how the display of package +dependencies: -- `unique` (default) — include each required package only once. -- `all` — show every package that requires the same dependency. -- `none` — hide all package dependencies. +- `unique` (default): include each required package only once. +- `all`: show every package that requires the same dependency. +- `none`: hide all package dependencies. ## Print package revisions -The `--show-package-revisions` flag controls which package revisions are shown: +The `--show-package-revisions` flag controls the display of package revisions: -- `active` (default) — show only the active revisions. -- `all` — show all revisions, including inactive ones. -- `none` — hide all revisions. +- `active` (default): show only the active revisions. +- `all`: show all revisions, including inactive ones. +- `none`: hide all revisions. ## Examples @@ -109,7 +107,7 @@ Output debug logs to stderr while piping a dot graph to dot: crossplane resource trace mykind my-res -n my-ns -o dot --verbose | dot -Tpng -o output.png ``` -Watch a resource continuously until it is deleted: +Watch a resource continuously until its deletion: ```shell crossplane resource trace mykind my-res -n my-ns --watch diff --git a/cmd/crossplane/trace/trace.go b/cmd/crossplane/trace/trace.go index 313052b..df9b412 100644 --- a/cmd/crossplane/trace/trace.go +++ b/cmd/crossplane/trace/trace.go @@ -67,18 +67,18 @@ const ( // Cmd builds the trace tree for a Crossplane resource. type Cmd struct { Resource string `arg:"" help:"Kind of the Crossplane resource, accepts the 'TYPE[.VERSION][.GROUP][/NAME]' format." predictor:"k8s_resource"` - Name string `arg:"" help:"Name of the Crossplane resource, can be passed as part of the resource too." optional:"" predictor:"k8s_resource_name"` + Name string `arg:"" help:"Name of the Crossplane resource, if not passed as part of the resource." optional:"" predictor:"k8s_resource_name"` // TODO(phisco): add support for all the usual kubectl flags; configFlags := genericclioptions.NewConfigFlags(true).AddFlags(...) - Context string `default:"" help:"Kubernetes context." name:"context" predictor:"context" short:"c"` - Namespace string `default:"" help:"Namespace of the resource." name:"namespace" predictor:"namespace" short:"n"` - Output string `default:"default" enum:"default,wide,json,dot,yaml" help:"Output format. One of: default, wide, json, dot, yaml." name:"output" short:"o"` - ShowConnectionSecrets bool `help:"Show connection secrets in the output." name:"show-connection-secrets" short:"s"` - ShowPackageDependencies string `default:"unique" enum:"unique,all,none" help:"Show package dependencies in the output. One of: unique, all, none." name:"show-package-dependencies"` - ShowPackageRevisions string `default:"active" enum:"active,all,none" help:"Show package revisions in the output. One of: active, all, none." name:"show-package-revisions"` - ShowPackageRuntimeConfigs bool `default:"false" help:"Show package runtime configs in the output." name:"show-package-runtime-configs"` - Concurrency int `default:"5" help:"load concurrency" name:"concurrency"` - Watch bool `default:"false" help:"Watch for changes until the resource is deleted" name:"watch" short:"w"` + Context string `default:"" help:"Kubernetes context." name:"context" predictor:"context" short:"c"` + Namespace string `default:"" help:"Namespace of the resource." name:"namespace" predictor:"namespace" short:"n"` + Output string `default:"default" enum:"default,wide,json,dot,yaml" help:"Output format. One of: default, wide, json, dot, yaml." name:"output" short:"o"` + ShowConnectionSecrets bool `help:"Show connection secrets in the output." name:"show-connection-secrets" short:"s"` + ShowPackageDependencies string `default:"unique" enum:"unique,all,none" help:"Show package dependencies in the output. One of: unique, all, none." name:"show-package-dependencies"` + ShowPackageRevisions string `default:"active" enum:"active,all,none" help:"Show package revisions in the output. One of: active, all, none." name:"show-package-revisions"` + ShowPackageRuntimeConfigs bool `default:"false" help:"Show package runtime configs in the output." name:"show-package-runtime-configs"` + Concurrency int `default:"5" help:"load concurrency" name:"concurrency"` + Watch bool `default:"false" help:"Watch for changes until resource deletion." name:"watch" short:"w"` } // Help returns help message for the trace command. diff --git a/cmd/crossplane/validate/cmd.go b/cmd/crossplane/validate/cmd.go index 1220bbb..f8cbb03 100644 --- a/cmd/crossplane/validate/cmd.go +++ b/cmd/crossplane/validate/cmd.go @@ -46,12 +46,12 @@ type Cmd struct { Resources string `arg:"" help:"Resource sources as a comma-separated list of files, directories, or '-' for standard input."` // Flags. Keep them in alphabetical order. - CacheDir string `default:"~/.crossplane/cache" help:"Absolute path to the cache directory where downloaded schemas are stored." predictor:"directory"` + CacheDir string `default:"~/.crossplane/cache" help:"Absolute path to the cache directory for downloaded schemas." predictor:"directory"` CleanCache bool `help:"Clean the cache directory before downloading package schemas."` - CrossplaneImage string `help:"Specify the Crossplane image to be used for validating the built-in schemas."` - ErrorOnMissingSchemas bool `default:"false" help:"Return non zero exit code if not all schemas are provided."` + CrossplaneImage string `help:"Specify the Crossplane image for validating built-in schemas."` + ErrorOnMissingSchemas bool `default:"false" help:"Return non zero exit code if missing schemas."` SkipSuccessResults bool `help:"Skip printing success results."` - UpdateCache bool `default:"false" help:"Update cached schemas by downloading the latest version that satisfies a constraint. May be useful if you are using semantic version constraints and want to get the latest version, but this will slow down the cache lookup due to the required network calls."` + UpdateCache bool `default:"false" help:"Update cached schemas by downloading the latest version that satisfies a constraint. May be useful if you are using semantic version constraints and want to get the latest version, but this slows down the cache lookup due to the required network calls."` fs afero.Fs } diff --git a/cmd/crossplane/validate/help/validate.md b/cmd/crossplane/validate/help/validate.md index 739eef5..5760886 100644 --- a/cmd/crossplane/validate/help/validate.md +++ b/cmd/crossplane/validate/help/validate.md @@ -1,30 +1,30 @@ The `resource validate` command validates the provided Crossplane resources against the schemas of the provided extensions (XRDs, CRDs, Providers, Functions, and Configurations). It uses the Kubernetes API server's validation -library plus additional checks (such as unknown-field detection, a common source -of difficult-to-debug Crossplane issues). +library plus other checks such as unknown-field detection, a common source of +difficult-to-debug Crossplane issues. -If Providers or Configurations are provided as extensions, they are downloaded -and loaded as CRDs before validation. If `--cache-dir` is not set, it defaults -to `~/.crossplane/cache`. Clean the cache before downloading schemas with -`--clean-cache`. +The `validate` command downloads any Providers or Configurations provided as +extensions, and loads their CRDs before validation. If `--cache-dir` isn't set, +it defaults to `~/.crossplane/cache`. Clean the cache before downloading schemas +with `--clean-cache`. -All validation is performed offline using the Kubernetes API server's validation -library — no Crossplane instance or control plane is required. +All validation happens offline using the Kubernetes API server's validation +library, without requiring a Crossplane instance or control plane. `crossplane resource validate` supports validating: - A managed or composite resource against a Provider or XRD schema. - The output of `crossplane composition render`. -- An XRD's [Common Expression - Language](https://kubernetes.io/docs/reference/using-api/cel/) (CEL) rules. +- An XRD's [Common Expression Language](https://kubernetes.io/docs/reference/using-api/cel/) + (CEL) rules. - Resources against a directory of schemas. ## Validate resources against a schema When validating against a Provider, the command downloads the Provider package -to `--cache-dir`. Access to a Kubernetes cluster or Crossplane pod is not -required — only the ability to download the Provider package. +to `--cache-dir`. Access to a Kubernetes cluster or Crossplane pod isn't +required as `validate` downloads the Provider extracts it locally. Create a Provider manifest: @@ -60,7 +60,7 @@ crossplane resource validate provider.yaml managedResource.yaml ## Validate render output -Pipe the output of `crossplane composition render` to `validate` to check +Pipe the output of `crossplane composition render` to `validate` to validate complete Crossplane resource pipelines, including XRs, Compositions, and Functions. Use `--include-full-xr` on `render`, and `-` (read stdin) on `validate`: @@ -70,10 +70,12 @@ crossplane composition render xr.yaml composition.yaml func.yaml --include-full- crossplane resource validate schemas.yaml - ``` -## Validate CEL rules + +## Validate Common Expression Language rules + -XRDs can define [validation -rules](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules) +XRDs can define +[validation rules](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules) in CEL via `x-kubernetes-validations`. `validate` evaluates them: ```yaml @@ -91,10 +93,10 @@ spec: ## Validate against a directory of schemas -`validate` can also take a directory of schema YAML files. Only `.yaml` and -`.yml` files are processed; other files are ignored. +`validate` can also take a directory of schema YAML files to use for +validation. It ignores any files with extensions other than `.yml` or `.yaml`. -```text +```plaintext schemas/ ├── platform-ref-aws.yaml ├── providers/ diff --git a/cmd/crossplane/xpkg/batch.go b/cmd/crossplane/xpkg/batch.go index bfad3a6..4aec261 100644 --- a/cmd/crossplane/xpkg/batch.go +++ b/cmd/crossplane/xpkg/batch.go @@ -83,32 +83,32 @@ func (c *batchCmd) AfterApply() error { type batchCmd struct { fs afero.Fs - FamilyBaseImage string `help:"Family image used as the base for the smaller provider packages." required:""` - ProviderName string `help:"Provider name, such as provider-aws to be used while formatting smaller provider package repositories." required:""` - FamilyPackageURLFormat string `help:"Family package URL format to be used for the smaller provider packages. Must be a valid OCI image URL with the format specifier \"%s\", which will be substituted with -." required:""` - SmallerProviders []string `default:"monolith" help:"Smaller provider names to build and push, such as ec2, eks or config."` - Concurrency uint `default:"0" help:"Maximum number of packages to process concurrently. Setting it to 0 puts no limit on the concurrency, i.e., all packages are processed in parallel."` - PushRetry uint `default:"3" help:"Number of retries when pushing a provider package fails."` - - Platform []string `default:"linux_amd64,linux_arm64" help:"Platforms to build the packages for. Each platform should use the _ syntax. An example is: linux_arm64."` - ProviderBinRoot string `help:"Provider binary paths root. Smaller provider binaries should reside under the platform directories in this folder." short:"p" type:"existingdir"` - OutputDir string `help:"Path of the package output directory." optional:"" short:"o"` - StorePackages []string `help:"Smaller provider names whose provider package should be stored under the package output directory specified with the --output-dir option." optional:""` - - PackageMetadataTemplate string `default:"./package/crossplane.yaml.tmpl" help:"Smaller provider metadata template. The template variables {{ .Service }} and {{ .Name }} are always set; optional variables may be supplied via --service-metadata and --template-var (the latter overrides on key conflicts)." type:"path"` - TemplateVar map[string]string `help:"Smaller provider metadata template variables to be used for the specified template."` - ServiceMetadataFile string `help:"Optional YAML file of per smaller-provider template variables. Top-level keys are smaller provider names (e.g. ec2, elb). Each entry is a map of variable names to scalars or lists; values are merged into the package metadata template as-is. Templates may use generic helpers toYAML and indent (YAML via gopkg.in/yaml.v3). Merged before --template-var." name:"service-metadata" optional:"" type:"path"` + FamilyBaseImage string `help:"Family image used as the base for the smaller provider packages." required:""` + ProviderName string `help:"Provider name prefix, such as provider-aws, for smaller provider package repositories." required:""` + FamilyPackageURLFormat string `help:"Family package URL format for the smaller provider packages. Must be a valid OCI image URL containing the format specifier '%s', substituted with -." required:""` + SmallerProviders []string `default:"monolith" help:"Smaller provider names to build and push, such as ec2, eks, or s3."` + Concurrency uint `default:"0" help:"Maximum number of packages to process concurrently. 0 puts no limit on the concurrency, processing all packages in parallel."` + PushRetry uint `default:"3" help:"Number of retries when pushing a provider package fails."` + + Platform []string `default:"linux_amd64,linux_arm64" help:"Platforms to build the packages for. Each platform must use the _ syntax. An example is: linux_arm64."` + ProviderBinRoot string `help:"Provider binary paths root. Smaller provider binaries must be under the platform directories in this folder." short:"p" type:"existingdir"` + OutputDir string `help:"Path of the package output directory." optional:"" short:"o"` + StorePackages []string `help:"Smaller provider names whose provider package must be under the package output directory specified with the --output-dir option." optional:""` + + PackageMetadataTemplate string `default:"./package/crossplane.yaml.tmpl" help:"Smaller provider metadata template. The template variables {{ .Service }} and {{ .Name }} are always set; you may supply optional variables via --service-metadata and --template-var (the latter overrides on key conflicts)." type:"path"` + TemplateVar map[string]string `help:"Smaller provider metadata template variables for the specified template."` + ServiceMetadataFile string `help:"Optional YAML file of per smaller-provider template variables. Top-level keys are smaller provider names (such as ec2, elb). Each entry is a map of variable names to scalars or lists; values get merged into the package metadata template as-is. Templates may use generic helpers toYAML and indent (YAML via gopkg.in/yaml.v3). Merged before --template-var." name:"service-metadata" optional:"" type:"path"` ExamplesGroupOverride map[string]string `help:"Overrides for the location of the example manifests folder of a smaller provider." optional:""` CRDGroupOverride map[string]string `help:"Overrides for the locations of the CRD folders of the smaller providers." optional:""` PackageRepoOverride map[string]string `help:"Overrides for the package repository names of the smaller providers." optional:""` - ExamplesRoot string `default:"./examples" help:"Path to package examples directory." short:"e" type:"path"` - CRDRoot string `default:"./package/crds" help:"Path to package CRDs directory." type:"path"` + ExamplesRoot string `default:"./examples" help:"Path to package examples directory." short:"e" type:"path"` + CRDRoot string `default:"./package/crds" help:"Path to package CRDs directory." type:"path"` Ignore []string `help:"Paths to exclude from the smaller provider packages."` - BuildOnly bool `default:"false" help:"Only build the smaller provider packages and do not attempt to push them to a package repository."` + BuildOnly bool `default:"false" help:"Only build the smaller provider packages and don't push them to a package repository."` - ProviderNameSuffixForPush string `env:"PROVIDER_NAME_SUFFIX_FOR_PUSH" help:"Suffix for provider name during pushing the packages. This suffix is added to the end of the provider name. If there is a service name for the corresponded provider, then the suffix will be added to the base provider name and the service-scoped name will be after this suffix. Examples: provider-family-aws-suffix, provider-aws-suffix-s3" optional:""` + ProviderNameSuffixForPush string `env:"PROVIDER_NAME_SUFFIX_FOR_PUSH" help:"Suffix for provider name when pushing the packages, to add to the service name for the corresponding provider before the service-scoped name. Examples: provider-family-aws-suffix, provider-aws-suffix-s3" optional:""` perServiceTemplateVars map[string]map[string]any // loaded from ServiceMetadataFile in Run } diff --git a/cmd/crossplane/xpkg/build.go b/cmd/crossplane/xpkg/build.go index 1e33556..83c209a 100644 --- a/cmd/crossplane/xpkg/build.go +++ b/cmd/crossplane/xpkg/build.go @@ -99,12 +99,12 @@ func (c *buildCmd) AfterApply() error { // buildCmd builds a crossplane package. type buildCmd struct { // Flags. Keep sorted alphabetically. - EmbedRuntimeImage string `help:"An OCI image to embed in the package as its runtime." placeholder:"NAME" xor:"runtime-image"` - EmbedRuntimeImageTarball string `help:"An OCI image tarball to embed in the package as its runtime." placeholder:"PATH" predictor:"file" type:"existingfile" xor:"runtime-image"` - ExamplesRoot string `default:"./examples" help:"A directory of example YAML files to include in the package." predictor:"directory" short:"e" type:"path"` - Ignore []string `help:"Comma-separated file paths, specified relative to --package-root, to exclude from the package. Wildcards are supported. Directories cannot be excluded." placeholder:"PATH"` - PackageFile string `help:"The file to write the package to. Defaults to a generated filename in --package-root." placeholder:"PATH" predictor:"xpkg_file" short:"o" type:"path"` - PackageRoot string `default:"." help:"The directory that contains the package's crossplane.yaml file." predictor:"directory" short:"f" type:"existingdir"` + EmbedRuntimeImage string `help:"An OCI image to embed in the package as its runtime." placeholder:"NAME" xor:"runtime-image"` + EmbedRuntimeImageTarball string `help:"An OCI image tarball to embed in the package as its runtime." placeholder:"PATH" predictor:"file" type:"existingfile" xor:"runtime-image"` + ExamplesRoot string `default:"./examples" help:"A directory of example YAML files to include in the package." predictor:"directory" short:"e" type:"path"` + Ignore []string `help:"comma-separated list of globs specifying files to exclude from the build, relative to --package-root." placeholder:"PATH"` + PackageFile string `help:"The file to write the package to. Defaults to a generated filename in --package-root." placeholder:"PATH" predictor:"xpkg_file" short:"o" type:"path"` + PackageRoot string `default:"." help:"The directory that contains the package's crossplane.yaml file." predictor:"directory" short:"f" type:"existingdir"` // Internal state. These aren't part of the user-exposed CLI structure. fs afero.Fs diff --git a/cmd/crossplane/xpkg/extract.go b/cmd/crossplane/xpkg/extract.go index aad0d90..53b3d49 100644 --- a/cmd/crossplane/xpkg/extract.go +++ b/cmd/crossplane/xpkg/extract.go @@ -128,10 +128,10 @@ type extractCmd struct { name name.Reference fetch fetchFn - Package string `arg:"" help:"Name of the package to extract. Must be a valid and fully qualified OCI image tag or a path if using --from-xpkg." optional:"" placeholder:"REGISTRY/REPOSITORY:TAG or PATH"` - FromDaemon bool `help:"Indicates that the image should be fetched from the Docker daemon."` - FromXpkg bool `help:"Indicates that the image should be fetched from a local xpkg. If package is not specified and only one exists in current directory it will be used."` - Output string `default:"out.gz" help:"Package output file path. Extension must be .gz or will be replaced." short:"o"` + Package string `arg:"" help:"Name of the package to extract. Must be a valid and fully qualified OCI image tag or a path if using --from-xpkg." optional:"" placeholder:"REGISTRY/REPOSITORY:TAG or PATH"` + FromDaemon bool `help:"Fetch the image from the Docker daemon."` + FromXpkg bool `help:"Extract a local xpkg file. If package isn't specified, implies the only one in the current directory."` + Output string `default:"out.gz" help:"Package output file. Extension must be .gz." short:"o"` } // Run runs the xpkg extract cmd. diff --git a/cmd/crossplane/xpkg/help/build.md b/cmd/crossplane/xpkg/help/build.md index e0abe57..1c48b05 100644 --- a/cmd/crossplane/xpkg/help/build.md +++ b/cmd/crossplane/xpkg/help/build.md @@ -1,8 +1,8 @@ The `xpkg build` command builds a package file from a local directory of -files. The CLI combines a directory of YAML files and packages them as an [OCI -container image](https://opencontainers.org/), applying the annotations and -values required by the [Crossplane XPKG -specification](https://github.com/crossplane/crossplane/blob/main/contributing/specifications/xpkg.md). +files. The CLI combines a directory of YAML files and packages them as an +[OCI container image](https://opencontainers.org/), applying the annotations and +values required by the +[Crossplane XPKG specification](https://github.com/crossplane/crossplane/blob/main/contributing/specifications/xpkg.md). `crossplane xpkg build` supports building Configuration, Function, and Provider package types. @@ -14,9 +14,8 @@ fields. ## Ignore files -Use `--ignore` to provide a comma-separated list of files and directories -(relative to `--package-root`) to skip. Wildcards are supported. Directories -themselves cannot be excluded. +Use `--ignore` to provide a comma-separated list of globs specifying files to +exclude from the build, relative to `--package-root`. ```shell crossplane xpkg build --ignore="./test/*,kind-config.yaml" @@ -24,9 +23,10 @@ crossplane xpkg build --ignore="./test/*,kind-config.yaml" ## Set the package name -By default the package is named from a combination of `metadata.name` and a hash -of the package contents, and written to `--package-root`. Override the location -and filename with `--package-file` (`-o`): +By default, the `build` command constructs the package filename using a +combination of `metadata.name` and a hash of the package contents, and writes it +to `--package-root`. Override the location and filename with `--package-file` +(`-o`): ```shell crossplane xpkg build -o /home/crossplane/example.xpkg @@ -39,9 +39,8 @@ Include YAML files demonstrating how to use the package with `--examples-root` ## Include a runtime image -Function and Provider packages can embed a controller container image so that -the package can also be used to run the controller. Embedding is supported for -those package kinds only. +Function and Provider packages embed a controller container image. Configuration +packages don't have a runtime image. > **Note:** Images referenced with `--embed-runtime-image` must be in the local > Docker cache. Use `docker pull` to download a missing image. diff --git a/cmd/crossplane/xpkg/help/init.md b/cmd/crossplane/xpkg/help/init.md index 2a4a31b..027f33f 100644 --- a/cmd/crossplane/xpkg/help/init.md +++ b/cmd/crossplane/xpkg/help/init.md @@ -2,21 +2,20 @@ The `xpkg init` command initializes a directory that you can use to build a package. It uses a template to initialize the directory, and can use any Git repository as a template. -Specify either a full Git URL or a well-known name as the template. The -following well-known template names are supported: +Specify either a full Git URL or one of the following names as the template: %s -## NOTES.txt +## `NOTES.txt` -If the template contains a `NOTES.txt` file in its root, its contents are -printed to stdout after the directory is initialized. Useful for instructions on -how to use the template. +The `init` command prints the contents of any `NOTES.txt` file in the template +root after initializing the directory. Useful for instructions on how to use the +template. -## init.sh +## `init.sh` -If the template contains an `init.sh` file in its root, you are prompted to view -and/or run it. Useful for scripts that personalize the template. Pass `-r` +The `init` command executes any `init.sh` file in the template root (after user +confirmation). Useful for scripts that personalize the template. Pass `-r` (`--run-init-script`) to run the script without prompting. ## Examples diff --git a/cmd/crossplane/xpkg/help/install.md b/cmd/crossplane/xpkg/help/install.md index 292e753..ceba51b 100644 --- a/cmd/crossplane/xpkg/help/install.md +++ b/cmd/crossplane/xpkg/help/install.md @@ -2,7 +2,7 @@ The `xpkg install` command installs a package in a Crossplane control plane. It uses `~/.kube/config` to connect to the control plane; override the path with the `KUBECONFIG` environment variable. -Specify the package kind, fully-qualified package OCI reference, and optionally +Specify the package kind, fully qualified package OCI reference, and optionally a name for the package inside Crossplane: ```shell @@ -12,12 +12,13 @@ crossplane xpkg install [] The `` is one of `configuration`, `function`, or `provider`. > **Important:** The package reference must be fully qualified, including the -> registry, repository, and tag (e.g., registry.example.com/package:v1.0.0). +> registry, repository, and tag (for example, +> registry.example.com/package:v1.0.0). ## Wait for package install By default the command returns as soon as Crossplane accepts the package. It -does not wait for the download or install to complete. To inspect download or +doesn't wait for the download or install to complete. To inspect download or installation problems, run `kubectl describe `. Use `--wait` (`-w`) to make the command wait for the package to become `HEALTHY` @@ -52,7 +53,7 @@ Wait 1 minute for the package to finish installing before returning: crossplane xpkg install provider xpkg.crossplane.io/crossplane-contrib/provider-aws-eks:v0.41.0 --wait=1m ``` -Install a Function named function-eg using a custom runtime config: +Install a Function named function-eg using a custom `DeploymentRuntimeConfig`: ```shell crossplane xpkg install function xpkg.crossplane.io/crossplane/function-example:v0.1.4 function-eg \ diff --git a/cmd/crossplane/xpkg/help/push.md b/cmd/crossplane/xpkg/help/push.md index 0e04cc5..2fd3efc 100644 --- a/cmd/crossplane/xpkg/help/push.md +++ b/cmd/crossplane/xpkg/help/push.md @@ -1,14 +1,15 @@ The `xpkg push` command pushes a Crossplane package file to any OCI registry. A -package's OCI tag must be a semantic version. Credentials for the registry are -retrieved from `docker` configuration; pushing to a private registry may require -a prior `docker login`. +package's OCI tag must be a semantic version. The `push` command uses registry +credentials from the local `docker` configuration; pushing to a private registry +may require a prior `docker login`. By default the command looks in the current directory for a single `.xpkg` file -to push. To push multiple files (e.g. a multi-platform package) or a specific -`.xpkg` file, use `-f` (`--package-files`). +to push. To push multiple files (for example, a multi-platform package) or a +specific `.xpkg` file, use `-f` (`--package-files`). > **Important:** The destination must be fully qualified, including the -> registry, repository, and tag (e.g., registry.example.com/package:v1.0.0). +> registry, repository, and tag (for example, +> registry.example.com/package:v1.0.0). ## Examples diff --git a/cmd/crossplane/xpkg/help/update.md b/cmd/crossplane/xpkg/help/update.md index 6a9b060..84daab9 100644 --- a/cmd/crossplane/xpkg/help/update.md +++ b/cmd/crossplane/xpkg/help/update.md @@ -2,7 +2,7 @@ The `xpkg update` command updates a package in a Crossplane control plane. It uses `~/.kube/config` to connect to the control plane; override the path with the `KUBECONFIG` environment variable. -Specify the package kind, a new fully-qualified package OCI reference, and +Specify the package kind, a new fully qualified package OCI reference, and optionally the name of the package already installed in Crossplane: ```shell @@ -10,7 +10,8 @@ crossplane xpkg update [] ``` > **Important:** The package reference must be fully qualified, including the -> registry, repository, and tag (e.g., registry.example.com/package:v1.0.0). +> registry, repository, and tag (for example, +> registry.example.com/package:v1.0.0). ## Examples diff --git a/cmd/crossplane/xpkg/help/xpkg.md b/cmd/crossplane/xpkg/help/xpkg.md index b71f436..324ab91 100644 --- a/cmd/crossplane/xpkg/help/xpkg.md +++ b/cmd/crossplane/xpkg/help/xpkg.md @@ -1,11 +1,11 @@ -Crossplane can be extended using packages. Crossplane packages are called -*xpkgs*. Crossplane supports Configuration, Provider, and Function packages. +Crossplane packages, called *xpkgs*, allow you to add capabilities to your +Crossplane installation. Crossplane supports Configuration, Provider, and +Function packages. A package is an opinionated OCI image that contains everything needed to extend -a Crossplane control plane with new functionality. For example, installing a +a Crossplane control plane with new capabilities. For example, installing a Provider package extends Crossplane with support for new kinds of managed -resource (MR). +resource (MRs). -See [the Crossplane packages -documentation](https://docs.crossplane.io/latest/concepts/packages) for more -information. +See [the Crossplane packages documentation](https://docs.crossplane.io/latest/packages) +for more information. diff --git a/cmd/crossplane/xpkg/init.go b/cmd/crossplane/xpkg/init.go index d2ca280..0c00fb4 100644 --- a/cmd/crossplane/xpkg/init.go +++ b/cmd/crossplane/xpkg/init.go @@ -62,9 +62,9 @@ type initCmd struct { Name string `arg:"" help:"The name of the new package to initialize."` Template string `arg:"" help:"The template name or URL to use to initialize the new package."` - Directory string `default:"." help:"The directory to initialize. It must be empty. It will be created if it doesn't exist." predictor:"directory" short:"d" type:"path"` - RunInitScript bool `help:"Runs the init.sh script if it exists without prompting" name:"run-init-script" short:"r"` - RefName string `help:"The branch or tag to clone from the template repository." name:"ref-name" short:"b"` + Directory string `default:"." help:"The directory to initialize. It must be empty if it exists." predictor:"directory" short:"d" type:"path"` + RunInitScript bool `help:"Runs the init.sh script if it exists without prompting" name:"run-init-script" short:"r"` + RefName string `help:"The branch or tag to clone from the template repository." name:"ref-name" short:"b"` } func (c *initCmd) Help() string { diff --git a/cmd/crossplane/xpkg/install.go b/cmd/crossplane/xpkg/install.go index dcced16..a9fcc68 100644 --- a/cmd/crossplane/xpkg/install.go +++ b/cmd/crossplane/xpkg/install.go @@ -57,16 +57,16 @@ const ( // installCmd installs a package. type installCmd struct { // Arguments. - Kind string `arg:"" enum:"provider,configuration,function" help:"The kind of package to install. One of \"provider\", \"configuration\", or \"function\"."` - Package string `arg:"" help:"The package to install, must be fully qualified, including the registry, repository, and tag." placeholder:"REGISTRY/REPOSITORY:TAG"` + Kind string `arg:"" enum:"provider,configuration,function" help:"The kind of package to install. One of 'provider', 'configuration', or 'function'."` + Package string `arg:"" help:"The package to install, must be fully qualified, including the registry, repository, and tag." placeholder:"REGISTRY/REPOSITORY:TAG"` Name string `arg:"" help:"The name of the new package in the Crossplane API. Derived from the package repository and tag by default." optional:""` // Flags. Keep sorted alphabetically. RuntimeConfig string `help:"Install the package with a runtime configuration (for example a DeploymentRuntimeConfig)." placeholder:"NAME"` ManualActivation bool `help:"Require the new package's first revision to be manually activated." short:"m"` PackagePullSecrets []string `help:"A comma-separated list of secrets the package manager should use to pull the package from the registry." placeholder:"NAME"` - RevisionHistoryLimit int64 `help:"How many package revisions may exist before the oldest revisions are deleted." placeholder:"LIMIT" short:"r"` - Wait time.Duration `default:"0s" help:"How long to wait for the package to install before returning. The command does not wait by default. Returns an error if the timeout is exceeded." short:"w"` + RevisionHistoryLimit int64 `help:"Number of package revisions that can exist before garbage collection." placeholder:"LIMIT" short:"r"` + Wait time.Duration `default:"0s" help:"How long to wait for the package to install before returning. The command doesn't wait by default." short:"w"` } func (c *installCmd) Help() string { diff --git a/cmd/crossplane/xpkg/update.go b/cmd/crossplane/xpkg/update.go index 25356a3..0a382fd 100644 --- a/cmd/crossplane/xpkg/update.go +++ b/cmd/crossplane/xpkg/update.go @@ -37,6 +37,7 @@ import ( "github.com/crossplane/crossplane/apis/v2/pkg/v1beta1" _ "embed" + _ "k8s.io/client-go/plugin/pkg/client/auth" // Load all the auth plugins for the cloud providers. ) @@ -46,7 +47,7 @@ var helpUpdate string // updateCmd updates a package. type updateCmd struct { // Arguments. - Kind string `arg:"" enum:"provider,configuration,function" help:"The kind of package to update. One of \"provider\", \"configuration\", or \"function\"."` + Kind string `arg:"" enum:"provider,configuration,function" help:"The kind of package to update. One of 'provider', 'configuration', or 'function'."` Package string `arg:"" help:"The package to update to. Must be fully qualified, including the registry, repository, and tag." placeholder:"REGISTRY/REPOSITORY:TAG"` Name string `arg:"" help:"The name of the package to update in the Crossplane API. Derived from the package repository and tag by default." optional:""` } diff --git a/cmd/crossplane/xrd/convert.go b/cmd/crossplane/xrd/convert.go index 397be6d..ffe080a 100644 --- a/cmd/crossplane/xrd/convert.go +++ b/cmd/crossplane/xrd/convert.go @@ -31,48 +31,28 @@ import ( apiextensionsv1 "github.com/crossplane/crossplane/apis/v2/apiextensions/v1" commonIO "github.com/crossplane/cli/v2/cmd/crossplane/convert/io" + + _ "embed" ) +//go:embed help/convert.md +var convertHelp string + type convertCmd struct { // Arguments. - InputFile string `arg:"" default:"-" help:"The XRD YAML file to be converted. If not specified or '-', stdin will be used." optional:"" predictor:"file" type:"path"` + InputFile string `arg:"" default:"-" help:"The XRD YAML file to convert, or '-' for stdin." optional:"" predictor:"file" type:"path"` // Output flags. OutputFile and OutputDir are mutually exclusive; when // neither is set the converted CRDs are emitted on stdout as a multi-doc // YAML stream. OutputFile string `help:"The file to write the generated CRD YAML to. Legacy XRDs produce a multi-doc YAML stream (XR CRD + Claim CRD)." placeholder:"PATH" predictor:"file" short:"o" type:"path" xor:"output"` - OutputDir string `help:"A directory to write the generated CRDs to. Each CRD is written to a separate file named .yaml." placeholder:"DIR" predictor:"directory" type:"path" xor:"output"` + OutputDir string `help:"A directory to write the generated CRDs to. Each CRD gets a separate file named after the CRD." placeholder:"DIR" predictor:"directory" type:"path" xor:"output"` fs afero.Fs } func (c *convertCmd) Help() string { - return ` -Convert a CompositeResourceDefinition (XRD) into the CustomResourceDefinition(s) -that Crossplane derives from it internally. - -Useful for inspecting the generated CRD shape, feeding it into kubectl-based -tooling that doesn't understand XRDs, or debugging composition behavior. - -Output depends on the XRD type, detected automatically: - * Namespaced or Cluster-scoped XRD -> 1 CRD for the XR - * Legacy XRD without claimNames -> 1 CRD for the XR - * Legacy XRD with claimNames -> 2 CRDs: one for the XR and one for the Claim - -Examples: - - # Convert an XRD file and print the CRD(s) to stdout (multi-doc YAML for legacy XRDs). - crossplane xrd convert xrd.yaml - - # Convert and write to a single file (multi-doc YAML for legacy XRDs). - crossplane xrd convert xrd.yaml -o crds.yaml - - # Split per-CRD files into a directory (each named .yaml). - crossplane xrd convert xrd.yaml --output-dir ./crds/ - - # Read the XRD from stdin. - cat xrd.yaml | crossplane xrd convert - -` + return convertHelp } // AfterApply implements kong.AfterApply. diff --git a/cmd/crossplane/xrd/generate.go b/cmd/crossplane/xrd/generate.go index c9ef3f5..8bbca63 100644 --- a/cmd/crossplane/xrd/generate.go +++ b/cmd/crossplane/xrd/generate.go @@ -48,11 +48,11 @@ import ( var generateHelp string type generateCmd struct { - File string `arg:"" help:"Path to the XR or XRC YAML file."` - From string `default:"xr" enum:"xr,simpleschema" help:"Input format: xr or simpleschema."` - Path string `help:"Output path within the APIs directory." optional:""` - Plural string `help:"Custom plural form for the XRD." optional:""` - ProjectFile string `default:"crossplane-project.yaml" help:"Path to project definition." short:"f"` + File string `arg:"" help:"Path to the XR or XRC YAML file."` + From string `default:"xr" enum:"xr,simpleschema" help:"Input format: xr or simpleschema."` + Path string `help:"Output path." optional:""` + Plural string `help:"Custom plural form for the XRD." optional:""` + ProjectFile string `default:"crossplane-project.yaml" help:"Path to project definition." short:"f"` projFS afero.Fs apisFS afero.Fs diff --git a/cmd/crossplane/xrd/help/convert.md b/cmd/crossplane/xrd/help/convert.md new file mode 100644 index 0000000..eb2bad8 --- /dev/null +++ b/cmd/crossplane/xrd/help/convert.md @@ -0,0 +1,38 @@ +The `xrd convert` command converts a CompositeResourceDefinition (XRD) into one +or more CustomResourceDefinitions that Crossplane derives from it internally. + +Useful for inspecting the generated CRD shape, feeding it into kubectl-based +tooling that doesn't understand XRDs, or debugging composition behavior. + +Output depends on the XRD type, detected automatically: + +* Namespaced or Cluster-scoped XRD: 1 CRD for the XR +* Legacy XRD without `claimNames`: 1 CRD for the XR +* Legacy XRD with `claimNames`: 2 CRDs: one for the XR and one for the Claim + +## Examples + +Convert an XRD file and print the CRDs to stdout (multi-doc YAML for legacy +XRDs): + +```shell +crossplane xrd convert xrd.yaml +``` + +Convert and write to a single file (multi-doc YAML for legacy XRDs): + +```shell +crossplane xrd convert xrd.yaml -o crds.yaml +``` + +Split per-CRD files into a directory (each named `.yaml`): + +```shell +crossplane xrd convert xrd.yaml --output-dir ./crds/ +``` + +Read the XRD from stdin: + +```shell +cat xrd.yaml | crossplane xrd convert - +``` diff --git a/cmd/crossplane/xrd/help/generate.md b/cmd/crossplane/xrd/help/generate.md index ffaf7f3..210a637 100644 --- a/cmd/crossplane/xrd/help/generate.md +++ b/cmd/crossplane/xrd/help/generate.md @@ -2,8 +2,8 @@ The `xrd generate` command creates a CompositeResourceDefinition (XRD) from either an example Composite Resource (XR) or a SimpleSchema document, and writes it into the project's APIs directory. -By default the input is treated as an XR; pass `--from simpleschema` to generate -an XRD from a SimpleSchema definition instead. +XR is the default input format; pass `--from simpleschema` to generate an XRD +from a SimpleSchema definition instead. ## Examples @@ -15,14 +15,13 @@ crossplane xrd generate examples/cluster/example.yaml ``` Generate an XRD with a specific plural form, useful when automatic pluralization -is wrong (e.g., "postgres"): +is wrong (for example, "postgres"): ```shell crossplane xrd generate examples/postgres/example.yaml --plural postgreses ``` -Generate an XRD and save it to a custom path within the project's APIs -directory: +Generate an XRD and save it to a custom path: ```shell crossplane xrd generate examples/postgres/example.yaml --path database/definition.yaml