Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cli/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ require (
github.com/rubenv/sql-migrate v1.8.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cast v1.7.0 // indirect
Expand Down
10 changes: 8 additions & 2 deletions cli/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
Expand Down Expand Up @@ -281,8 +284,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
Expand All @@ -298,6 +301,7 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
Expand Down Expand Up @@ -423,12 +427,14 @@ google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3i
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
37 changes: 19 additions & 18 deletions cli/pkg/help/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,33 @@ limitations under the License.
package help

import (
"io"
"regexp"
"fmt"
"strings"
"unicode"

"github.com/MakeNowJust/heredoc"
"github.com/muesli/reflow/wordwrap"
"github.com/spf13/cobra"
"k8s.io/component-base/term"
"github.com/muesli/reflow/indent"
)

var reEmptyLine = regexp.MustCompile(`(?m)([\w[:punct:]])[ ]*\n([\w[:punct:]])`)

func Doc(s string) string {
s = heredoc.Doc(s)
s = reEmptyLine.ReplaceAllString(s, "$1 $2")
return RemoveIndentation(s)
}

func Examples(s string) string {
s = RemoveIndentation(s)

// apply a consistent, nice-looking indentation
s = indent.String(s, 2)

return s
}

func FitTerminal(out io.Writer) {
cols, _, err := term.TerminalSize(out)
if err != nil {
cols = 80
}
func Examplesf(s string, args ...any) string {
return Examples(fmt.Sprintf(s, args...))
}

cobra.AddTemplateFunc("trimTrailingWhitespaces", func(s string) string {
return strings.TrimRightFunc(wordwrap.String(s, cols), unicode.IsSpace)
})
func RemoveIndentation(s string) string {
s = strings.TrimSpace(s)
s = heredoc.Doc(s)

return s
}
3 changes: 2 additions & 1 deletion cli/pkg/kubectl/bind-apiservice/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
logsv1 "k8s.io/component-base/logs/api/v1"

"github.com/kube-bind/kube-bind/cli/pkg/help"
"github.com/kube-bind/kube-bind/cli/pkg/kubectl/bind-apiservice/plugin"

_ "k8s.io/client-go/plugin/pkg/client/auth/exec"
Expand All @@ -45,7 +46,7 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
cmd := &cobra.Command{
Use: "apiservice https://<url-to-a-APIServiceExportRequest>|-f <file-to-a-APIBindingRequest>",
Short: "Bind to a remote API service",
Example: fmt.Sprintf(bindAPIServiceExampleUses, "kubectl bind"),
Example: help.Examplesf(bindAPIServiceExampleUses, "kubectl bind"),
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
if err := logsv1.ValidateAndApply(opts.Logs, nil); err != nil {
Expand Down
19 changes: 11 additions & 8 deletions cli/pkg/kubectl/bind-collections/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
logsv1 "k8s.io/component-base/logs/api/v1"

"github.com/kube-bind/kube-bind/cli/pkg/help"
"github.com/kube-bind/kube-bind/cli/pkg/kubectl/bind-collections/plugin"
)

var (
CollectionsExampleUses = `
collectionsExampleUses = `
# List collections from currently authenticated server
%[1]s collections

Expand All @@ -46,15 +47,17 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
cmd := &cobra.Command{
Use: "collections [server-url]",
Short: "List available collections from a kube-bind server",
Long: `List all available collections from a kube-bind server.
Long: help.Doc(`
List all available collections from a kube-bind server.

This command connects to a kube-bind server and displays all the collections
that are available. By default, it uses the current authenticated
server from your configuration.
This command connects to a kube-bind server and displays all the
collections that are available. By default, it uses the current
authenticated server from your configuration.

If you haven't authenticated to any server yet, you must provide a server URL
argument or use 'kubectl bind-login <server>' first.`,
Example: fmt.Sprintf(CollectionsExampleUses, "kubectl"),
If you haven't authenticated to any server yet, you must provide
a server URL argument or use 'kubectl bind-login <server>' first.
`),
Example: help.Examplesf(collectionsExampleUses, "kubectl"),
SilenceUsage: true,
Args: func(cmd *cobra.Command, args []string) error {
for _, arg := range args {
Expand Down
12 changes: 5 additions & 7 deletions cli/pkg/kubectl/bind-login/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ limitations under the License.
package cmd

import (
"fmt"

"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
logsv1 "k8s.io/component-base/logs/api/v1"
Expand All @@ -28,7 +26,7 @@ import (
)

var (
LoginExampleUses = `
loginExampleUses = `
# Login to a kube-bind server
%[1]s login https://my-kube-bind-server.example.com

Expand All @@ -47,15 +45,15 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
Short: "Login to a kube-bind server and store authentication credentials",
Long: help.Doc(`
Login to a kube-bind server using OAuth2 authentication flow.

The command will open your browser to complete the OAuth2 flow and
store the resulting JWT token in ~/.kube-bind/config for use by
subsequent commands.

The SERVER_URL should point to the root of your kube-bind server,
e.g. https://my-server.example.com
`),
Example: fmt.Sprintf(LoginExampleUses, "kubectl bind"),
`),
Example: help.Examplesf(loginExampleUses, "kubectl bind"),
SilenceUsage: true,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
6 changes: 3 additions & 3 deletions cli/pkg/kubectl/bind/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var (
BindExampleUses = `
# %[1]s bind login --server https://my-kube-bind-server.com

# Open kube-bind UI for current server context
# Open kube-bind UI for current server context
%[1]s bind

# List available templates (CLI mode)
Expand All @@ -61,8 +61,8 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
By default, 'kubectl bind' opens the kube-bind web UI in your browser.

For more information, see: https://docs.kube-bind.io
`),
Example: fmt.Sprintf(BindExampleUses, "kubectl"),
`),
Example: help.Examplesf(BindExampleUses, "kubectl"),
SilenceUsage: true,
Args: func(cmd *cobra.Command, args []string) error {
// Allow 0 or 1 arguments
Expand Down
42 changes: 21 additions & 21 deletions cli/pkg/kubectl/dev/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ limitations under the License.
package cmd

import (
"fmt"

"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
logsv1 "k8s.io/component-base/logs/api/v1"
Expand All @@ -28,21 +26,21 @@ import (
)

var (
DevCreateExampleUses = `
devCreateExampleUses = `
# Create a development environment with kind cluster and default OCI chart
%[1]s dev create
%[1]s create

# Create a development environment with custom provider cluster name
%[1]s dev create --provider-cluster-name my-provider
%[1]s create --provider-cluster-name my-provider

# Create with custom chart path (local development)
%[1]s dev create --chart-path ../deploy/charts/backend
%[1]s create --chart-path ../deploy/charts/backend

# Create with specific chart version
%[1]s dev create --chart-version 0.1.0
%[1]s create --chart-version 0.1.0

# Create with custom OCI chart
%[1]s dev create --chart-path oci://registry.example.com/charts/backend --chart-version 1.0.0
%[1]s create --chart-path oci://registry.example.com/charts/backend --chart-version 1.0.0
`
)

Expand All @@ -52,19 +50,19 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
Short: "Manage development environment for kube-bind",
Long: help.Doc(`
Manage a development environment for kube-bind using kind clusters.

This command provides subcommands to initialize and manage kind clusters
configured for kube-bind development.
`),
`),
SilenceUsage: true,
}

// Add init subcommand
initCmd, err := newInitCommand(streams)
// Add create subcommand
createCmd, err := newCreateCommand(streams)
if err != nil {
return nil, err
}
cmd.AddCommand(initCmd)
cmd.AddCommand(createCmd)

// Add delete subcommand
deleteCmd, err := newDeleteCommand(streams)
Expand All @@ -83,26 +81,28 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
return cmd, nil
}

func newInitCommand(streams genericclioptions.IOStreams) (*cobra.Command, error) {
func newCreateCommand(streams genericclioptions.IOStreams) (*cobra.Command, error) {
opts := plugin.NewDevOptions(streams)
cmd := &cobra.Command{
Use: "create",
Short: "Create development environment with kind cluster and kube-bind backend",
Long: help.Doc(`
Create a complete development environment for kube-bind using kind clusters.

This command will:

- Create a kind cluster configured for kube-bind development
- Add kube-bind.dev.local to /etc/hosts (with sudo prompts if needed)
- Install kube-bind backend helm chart (default: OCI chart from ghcr.io)
- Configure necessary port mappings (8443, 15021)

The backend chart can be sourced from:

- OCI registry (default): oci://ghcr.io/kube-bind/charts/backend
- Local filesystem: --chart-path ./deploy/charts/backend
- Custom OCI registry: --chart-path oci://custom.registry/charts/backend
`),
Example: fmt.Sprintf(DevCreateExampleUses, "kubectl bind dev"),
`),
Example: help.Examplesf(devCreateExampleUses, "kubectl bind dev"),
SilenceUsage: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -133,9 +133,9 @@ func newDeleteCommand(streams genericclioptions.IOStreams) (*cobra.Command, erro
Short: "Delete development environment",
Long: help.Doc(`
Delete the development environment for kube-bind.

This command will delete the kind cluster created for kube-bind development.
`),
`),
SilenceUsage: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -166,7 +166,7 @@ func newExampleCommand(streams genericclioptions.IOStreams) (*cobra.Command, err
Short: "Get example manifest for MangoDB",
Long: help.Doc(`
This will print example CRD you can use for development environment testing.
`),
`),
SilenceUsage: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
4 changes: 2 additions & 2 deletions contrib/kcp/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/cli-doc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ replace (
require (
github.com/kcp-dev/kcp v0.28.2
github.com/kube-bind/kube-bind/cli v0.0.0-20250515145715-d9f20e7c840d
github.com/spf13/cobra v1.10.1
)

require (
Expand Down Expand Up @@ -111,7 +112,6 @@ require (
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/cobra v1.10.1 // indirect
github.com/spf13/pflag v1.0.9 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions docs/generators/cli-doc/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
Expand Down
Loading