Skip to content

Commit 7ff188e

Browse files
committed
add poor-man exampleto kickstart
1 parent a04e80c commit 7ff188e

5 files changed

Lines changed: 196 additions & 50 deletions

File tree

cli/pkg/kubectl/dev/cmd/cmd.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
7373
}
7474
cmd.AddCommand(deleteCmd)
7575

76+
exampleCmd, err := newExampleCommand(streams)
77+
if err != nil {
78+
return nil, err
79+
}
80+
81+
cmd.AddCommand(exampleCmd)
82+
7683
return cmd, nil
7784
}
7885

@@ -151,3 +158,34 @@ func newDeleteCommand(streams genericclioptions.IOStreams) (*cobra.Command, erro
151158

152159
return cmd, nil
153160
}
161+
162+
func newExampleCommand(streams genericclioptions.IOStreams) (*cobra.Command, error) {
163+
opts := plugin.NewDevOptions(streams)
164+
cmd := &cobra.Command{
165+
Use: "example",
166+
Short: "Get example manifest for MangoDB",
167+
Long: help.Doc(`
168+
This will print example CRD you can use for development environment testing.
169+
`),
170+
SilenceUsage: true,
171+
Args: cobra.NoArgs,
172+
RunE: func(cmd *cobra.Command, args []string) error {
173+
if err := logsv1.ValidateAndApply(opts.Logs, nil); err != nil {
174+
return err
175+
}
176+
177+
if err := opts.Complete(args); err != nil {
178+
return err
179+
}
180+
181+
if err := opts.Validate(); err != nil {
182+
return err
183+
}
184+
185+
return opts.RunPrintExample(cmd.Context())
186+
},
187+
}
188+
opts.AddCmdFlags(cmd)
189+
190+
return cmd, nil
191+
}
Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ func (o *DevOptions) Run(ctx context.Context) error {
154154
" 1. Run login to authenticate to the provider cluster:\n\n"+
155155
"kubectl bind login http://kube-bind.dev.local:8080\n\n"+
156156
" 2. Run bind to bind an API service from the provider to the consumer cluster:\n\n"+
157-
"kubectl bind --konnector-host-alias "+providerIP+":kube-bind.dev.local\n")
157+
"KUBECONFIG="+o.ConsumerClusterName+".kubeconfig kubectl bind --konnector-host-alias "+providerIP+":kube-bind.dev.local\n")
158158
return nil
159159
}
160160

@@ -231,52 +231,6 @@ func (o *DevOptions) createCluster(ctx context.Context, clusterName, clusterConf
231231
return nil
232232
}
233233

234-
func (o *DevOptions) RunDelete(ctx context.Context) error {
235-
if err := o.deleteCluster(ctx, o.ProviderClusterName); err != nil {
236-
return err
237-
}
238-
239-
if err := o.deleteCluster(ctx, o.ConsumerClusterName); err != nil {
240-
return err
241-
}
242-
243-
return o.cleanupHostEntries(ctx)
244-
}
245-
246-
func (o *DevOptions) deleteCluster(ctx context.Context, clusterName string) error {
247-
fmt.Fprintf(o.Streams.ErrOut, "Deleting kind cluster %s\n", clusterName)
248-
provider := cluster.NewProvider()
249-
250-
err := provider.Delete(clusterName, "")
251-
if err != nil {
252-
return err
253-
}
254-
255-
kubeconfigPath := fmt.Sprintf("%s.kubeconfig", clusterName)
256-
if err := os.Remove(kubeconfigPath); err != nil && !os.IsNotExist(err) {
257-
fmt.Fprintf(o.Streams.ErrOut, "Failed to remove kubeconfig file %s: %v\n", kubeconfigPath, err)
258-
} else {
259-
fmt.Fprintf(o.Streams.ErrOut, "Removed kubeconfig file %s\n", kubeconfigPath)
260-
}
261-
262-
return nil
263-
}
264-
265-
func (o *DevOptions) cleanupHostEntries(ctx context.Context) error {
266-
if err := removeHostEntry("kube-bind.dev.local"); err != nil {
267-
fmt.Fprintf(o.Streams.ErrOut, "Failed to remove host entry: %v\n", err)
268-
fmt.Fprintf(o.Streams.ErrOut, "Warning: Could not automatically remove host entry. Please run:\n")
269-
if runtime.GOOS == "windows" {
270-
fmt.Fprintf(o.Streams.ErrOut, " Remove '127.0.0.1 kube-bind.dev.local' line from C:\\Windows\\System32\\drivers\\etc\\hosts\n")
271-
} else {
272-
fmt.Fprintf(o.Streams.ErrOut, " sudo sed -i '/127.0.0.1 kube-bind.dev.local/d' /etc/hosts\n")
273-
}
274-
} else {
275-
fmt.Fprintf(o.Streams.ErrOut, "Removed host entry kube-bind.dev.local\n")
276-
}
277-
return nil
278-
}
279-
280234
func (o *DevOptions) getClusterIPAddress(ctx context.Context, clusterName, networkName string) (string, error) {
281235
dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
282236
if err != nil {
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Copyright 2025 The Kube Bind Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package plugin
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"os"
23+
"runtime"
24+
25+
"sigs.k8s.io/kind/pkg/cluster"
26+
)
27+
28+
func (o *DevOptions) RunDelete(ctx context.Context) error {
29+
if err := o.deleteCluster(ctx, o.ProviderClusterName); err != nil {
30+
return err
31+
}
32+
33+
if err := o.deleteCluster(ctx, o.ConsumerClusterName); err != nil {
34+
return err
35+
}
36+
37+
return o.cleanupHostEntries(ctx)
38+
}
39+
40+
func (o *DevOptions) deleteCluster(ctx context.Context, clusterName string) error {
41+
fmt.Fprintf(o.Streams.ErrOut, "Deleting kind cluster %s\n", clusterName)
42+
provider := cluster.NewProvider()
43+
44+
err := provider.Delete(clusterName, "")
45+
if err != nil {
46+
return err
47+
}
48+
49+
kubeconfigPath := fmt.Sprintf("%s.kubeconfig", clusterName)
50+
if err := os.Remove(kubeconfigPath); err != nil && !os.IsNotExist(err) {
51+
fmt.Fprintf(o.Streams.ErrOut, "Failed to remove kubeconfig file %s: %v\n", kubeconfigPath, err)
52+
} else {
53+
fmt.Fprintf(o.Streams.ErrOut, "Removed kubeconfig file %s\n", kubeconfigPath)
54+
}
55+
56+
return nil
57+
}
58+
59+
func (o *DevOptions) cleanupHostEntries(ctx context.Context) error {
60+
if err := removeHostEntry("kube-bind.dev.local"); err != nil {
61+
fmt.Fprintf(o.Streams.ErrOut, "Failed to remove host entry: %v\n", err)
62+
fmt.Fprintf(o.Streams.ErrOut, "Warning: Could not automatically remove host entry. Please run:\n")
63+
if runtime.GOOS == "windows" {
64+
fmt.Fprintf(o.Streams.ErrOut, " Remove '127.0.0.1 kube-bind.dev.local' line from C:\\Windows\\System32\\drivers\\etc\\hosts\n")
65+
} else {
66+
fmt.Fprintf(o.Streams.ErrOut, " sudo sed -i '/127.0.0.1 kube-bind.dev.local/d' /etc/hosts\n")
67+
}
68+
} else {
69+
fmt.Fprintf(o.Streams.ErrOut, "Removed host entry kube-bind.dev.local\n")
70+
}
71+
return nil
72+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
Copyright 2025 The Kube Bind Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package plugin
18+
19+
import (
20+
"context"
21+
"fmt"
22+
)
23+
24+
var example = `apiVersion: mangodb.com/v1alpha1
25+
kind: MangoDB
26+
metadata:
27+
name: my-first-mangodb-instance
28+
namespace: default
29+
spec:
30+
tier: Dedicated`
31+
32+
func (o *DevOptions) RunPrintExample(ctx context.Context) error {
33+
fmt.Fprintf(o.Streams.Out, "%s", example)
34+
return nil
35+
}

docs/content/setup/quickstart.md

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,60 @@ description: >
1212

1313
## Start with kube-bind
1414

15-
### Deploy a kube-bind Backend
15+
### Quick Development Setup
1616

17-
You can deploy a kube-bind backend using helm (recommended):
17+
**Note:** This setup requires Docker as it uses advanced network configuration to minimize external DNS dependencies and enable inter-cluster connectivity.
18+
19+
For a quick development environment with local Kind clusters, use the `kubectl bind dev` command:
20+
21+
```bash
22+
kubectl bind dev create
23+
```
24+
25+
This command will:
26+
- Create two Kind clusters: `kind-provider` (API provider) and `kind-consumer` (API consumer)
27+
- Deploy the kube-bind backend to the provider cluster
28+
- Generate kubeconfig files for both clusters
29+
- Set up local DNS entries for `kube-bind.dev.local`
30+
- Start the kube-bind server at `http://kube-bind.dev.local:8080`
31+
32+
After the development environment is ready, you can:
33+
34+
1. **Authenticate to the provider cluster:**
35+
```bash
36+
kubectl bind login http://kube-bind.dev.local:8080
37+
```
38+
This will open a browser for authentication and save the configuration.
39+
40+
2. **Bind API services from provider to consumer:**
41+
```bash
42+
KUBECONFIG=kind-consumer.kubeconfig kubectl bind --konnector-host-alias <docker-internal-ip-address>:kube-bind.dev.local
43+
```
44+
This opens the kube-bind web UI where you can select and bind API services.
45+
46+
3. **Verify bound resources:**
47+
```bash
48+
KUBECONFIG=kind-consumer.kubeconfig kubectl get crd
49+
KUBECONFIG=kind-consumer.kubeconfig kubectl get apiservicebindings -n kube-bind
50+
```
51+
52+
4. **Create example resource**
53+
```bash
54+
kubectl bind dev example | KUBECONFIG=kind-consumer.kubeconfig kubectl create -f -
55+
```
56+
57+
5. **Check resource synced to provider**
58+
```bash
59+
KUBECONFIG=kind-provider.kubeconfig kubectl get mangodbs.mangodb.com -A
60+
```
61+
62+
### Production Deployment
63+
64+
For production deployments, you can deploy a kube-bind backend using helm:
1865

1966
- **[Using Helm Chart](helm.md)** - Recommended for production deployments
2067

21-
## Once you have a kube-bind backend running, you can connect to it using the `kubectl bind` plugin.
68+
Once you have a kube-bind backend running (either development or production), you can connect to it:
2269

2370
### Connect to kube-bind Server
2471

0 commit comments

Comments
 (0)