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
29 changes: 19 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -409,33 +409,42 @@ build-web:
PLATFORMS ?= linux/$(ARCH)
.PHONY: image-local
image-local:
@echo "Building multi-arch images locally with tag $(REV) for platforms: $(PLATFORMS)"
@echo "Building images locally with tag $(REV) for platforms: $(PLATFORMS)"
@command -v docker >/dev/null 2>&1 || { echo "docker not found. Please install Docker"; exit 1; }
@docker buildx version >/dev/null 2>&1 || { echo "docker buildx not found. Please enable buildx in Docker"; exit 1; }

@# Create buildx builder if it doesn't exist
@docker buildx create --name kube-bind-builder --use 2>/dev/null || docker buildx use kube-bind-builder 2>/dev/null || true
@docker buildx inspect --bootstrap >/dev/null 2>&1

@echo "Building konnector multi-arch image locally..."
@# Check if building for multiple platforms
@if [[ "$(PLATFORMS)" == *","* ]]; then \
echo "Multi-platform build detected. Images will be pushed to registry instead of loaded locally."; \
LOAD_FLAG="--push"; \
else \
echo "Single platform build. Images will be loaded to local Docker daemon."; \
LOAD_FLAG="--load"; \
fi && \
\
echo "Building konnector image..." && \
docker buildx build \
--platform $(PLATFORMS) \
--build-arg LDFLAGS="$(LDFLAGS)" \
-t $(IMAGE_REPO)/konnector:$(REV) \
-f Dockerfile.konnector \
--load .

@echo "Building backend multi-arch image locally..."
$$LOAD_FLAG . && \
\
echo "Building backend image..." && \
docker buildx build \
--platform $(PLATFORMS) \
--build-arg LDFLAGS="$(LDFLAGS)" \
-t $(IMAGE_REPO)/backend:$(REV) \
-f Dockerfile \
--load .

@echo "Successfully built multi-arch local images:"
@echo " $(IMAGE_REPO)/konnector:$(REV) ($(PLATFORMS))"
@echo " $(IMAGE_REPO)/backend:$(REV) ($(PLATFORMS))"
$$LOAD_FLAG . && \
\
echo "Successfully built images:" && \
echo " $(IMAGE_REPO)/konnector:$(REV) ($(PLATFORMS))" && \
echo " $(IMAGE_REPO)/backend:$(REV) ($(PLATFORMS))"

# Kind cluster configuration
KIND_CLUSTER ?= kube-bind
Expand Down
7 changes: 2 additions & 5 deletions cli/pkg/kubectl/bind-apiservice/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,8 @@ var (
# bind to a remote API service. Use kubectl bind to create the APIServiceExportRequest interactively.
%[1]s apiservice --remote-kubeconfig file -f apiservice-export-request.yaml

# bind to a remote API service via a request manifest from a https URL.
%[1]s apiservice --remote-kubeconfig file https://some-url.com/apiservice-export-requests.yaml

# bind to a API service directly without any remote agent or service provider.
%[1]s apiservice --remote-kubeconfig file -n remote-namespace resources.group/v1
# bind to a remote API using template name
%[1]s apiservice --name my-api --template-name database-service
`
)

Expand Down
4 changes: 2 additions & 2 deletions cli/pkg/kubectl/bind-apiservice/plugin/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,9 @@ func (b *BindAPIServiceOptions) bindTemplate(ctx context.Context) (*bindTemplate
return nil, err
}
if created {
fmt.Fprintf(b.Options.IOStreams.ErrOut, "Created secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
fmt.Fprintf(b.Options.IOStreams.ErrOut, "🔒 Created secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
} else {
fmt.Fprintf(b.Options.IOStreams.ErrOut, "Updated secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
fmt.Fprintf(b.Options.IOStreams.ErrOut, "🔒 Updated secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
}
return &bindTemplateResult{
response: bindResponse,
Expand Down
19 changes: 15 additions & 4 deletions cli/pkg/kubectl/bind-apiservice/plugin/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ func NewBinder(config *rest.Config, opts *BinderOptions) *Binder {
// https://github.com/kube-bind/kube-bind/issues/360

func (b *Binder) BindFromFile(ctx context.Context) ([]*kubebindv1alpha2.APIServiceBinding, error) {
// Generate the kubectl command that would be equivalent
remoteFlags := ""
if b.opts.RemoteKubeconfigFile != "" {
remoteFlags = fmt.Sprintf("--remote-kubeconfig %s", b.opts.RemoteKubeconfigFile)
} else if b.opts.RemoteKubeconfigNamespace != "" && b.opts.RemoteKubeconfigName != "" {
remoteFlags = fmt.Sprintf("--remote-kubeconfig-namespace %s --remote-kubeconfig-name %s", b.opts.RemoteKubeconfigNamespace, b.opts.RemoteKubeconfigName)
}
fmt.Fprintf(b.opts.IOStreams.ErrOut, "🚀 Executing: kubectl bind apiservice %s -f -\n", remoteFlags)
fmt.Fprintf(b.opts.IOStreams.ErrOut, "✨ Use \"-o yaml\" and \"--dry-run\" to get the APIServiceExportRequest.\n")
fmt.Fprintf(b.opts.IOStreams.ErrOut, " and pass it to \"kubectl bind apiservice\" directly. Great for automation.\n")

// Ensure client side namespace exists
err := b.ensureClientSideNamespaceExists(ctx)
if err != nil {
Expand Down Expand Up @@ -99,9 +110,9 @@ func (b *Binder) BindFromFile(ctx context.Context) ([]*kubebindv1alpha2.APIServi
}

if created {
fmt.Fprintf(b.opts.IOStreams.ErrOut, "Created secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
fmt.Fprintf(b.opts.IOStreams.ErrOut, "🔒 Created secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
} else {
fmt.Fprintf(b.opts.IOStreams.ErrOut, "Updated secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
fmt.Fprintf(b.opts.IOStreams.ErrOut, "🔒 Updated secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
}

if b.opts.DryRun {
Expand Down Expand Up @@ -184,9 +195,9 @@ func (b *Binder) BindFromResponse(ctx context.Context, response *kubebindv1alpha
}

if created {
fmt.Fprintf(b.opts.IOStreams.ErrOut, "Created secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
fmt.Fprintf(b.opts.IOStreams.ErrOut, "🔒 Created secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
} else {
fmt.Fprintf(b.opts.IOStreams.ErrOut, "Updated secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
fmt.Fprintf(b.opts.IOStreams.ErrOut, "🔒 Updated secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
}

if b.opts.DryRun {
Expand Down
4 changes: 2 additions & 2 deletions cli/pkg/kubectl/bind-apiservice/plugin/konnector.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (b *BindAPIServiceOptions) deployKonnector(ctx context.Context, config *res
}

if b.KonnectorImageOverride != "" {
fmt.Fprintf(b.Options.ErrOut, "Deploying konnector %s to namespace kube-bind with custom image %q.\n", bindVersion, b.KonnectorImageOverride)
fmt.Fprintf(b.Options.ErrOut, "🚀 Deploying konnector %s to namespace kube-bind with custom image %q.\n", bindVersion, b.KonnectorImageOverride)
if err := konnector.Bootstrap(ctx, discoveryClient, dynamicClient, b.KonnectorImageOverride); err != nil {
return err
}
Expand Down Expand Up @@ -103,7 +103,7 @@ func (b *BindAPIServiceOptions) deployKonnector(ctx context.Context, config *res
}
}
} else {
fmt.Fprintf(b.Options.ErrOut, "Deploying konnector %s to namespace kube-bind.\n", bindVersion)
fmt.Fprintf(b.Options.ErrOut, "🚀 Deploying konnector %s to namespace kube-bind.\n", bindVersion)
if err := konnector.Bootstrap(ctx, discoveryClient, dynamicClient, konnectorImage); err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cli/pkg/kubectl/bind-apiservice/plugin/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ func (b *BindAPIServiceOptions) ensureKubeconfigSecretWithLogging(ctx context.Co

if b.remoteKubeconfigFile != "" {
if created {
fmt.Fprintf(b.Options.ErrOut, "Created secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
fmt.Fprintf(b.Options.ErrOut, "🔒 Created secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
} else {
fmt.Fprintf(b.Options.ErrOut, "Updated secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
fmt.Fprintf(b.Options.ErrOut, "🔒 Updated secret %s/%s for host %s, namespace %s\n", "kube-bind", secret.Name, remoteHost, remoteNamespace)
}
}

Expand Down
2 changes: 1 addition & 1 deletion cli/pkg/kubectl/bind-apiservice/plugin/servicebindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,6 @@ func (b *BindAPIServiceOptions) createAPIServiceBindings(ctx context.Context, co
return nil, err
}

fmt.Fprintf(b.Options.IOStreams.ErrOut, "Created APIServiceBinding %s for %d resources\n", bindingName, len(request.Spec.Resources))
fmt.Fprintf(b.Options.IOStreams.ErrOut, "Created APIServiceBinding %s for %d resources\n", bindingName, len(request.Spec.Resources))
return []*kubebindv1alpha2.APIServiceBinding{created}, nil
}
6 changes: 2 additions & 4 deletions cli/pkg/kubectl/bind-collections/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@ var (
# List collections from currently authenticated server
%[1]s collections

# List collections from specific server
%[1]s collections https://mangodb.com

# List collections using --server flag to override current server
%[1]s collections --server https://mangodb.com

# List collections with JSON output
# List collections with JSON/YAML output
%[1]s collections -o json
%[1]s collections -o yaml
`
)

Expand Down
6 changes: 3 additions & 3 deletions cli/pkg/kubectl/bind-login/plugin/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,10 @@ func (o *LoginOptions) Run(ctx context.Context, authURLCh chan<- string) error {
}

if token.Cluster != "" {
fmt.Fprintf(o.Streams.ErrOut, "Successfully authenticated to %s (cluster: %s)\n", serverHost.Host, token.Cluster)
fmt.Fprintf(o.Streams.ErrOut, " Server key: %s\n", fmt.Sprintf("%s@%s", serverURL, token.Cluster))
fmt.Fprintf(o.Streams.ErrOut, "🔑 Successfully authenticated to %s (cluster: %s)\n", serverHost.Host, token.Cluster)
fmt.Fprintf(o.Streams.ErrOut, " Server key: %s\n", fmt.Sprintf("%s@%s", serverURL, token.Cluster))
} else {
fmt.Fprintf(o.Streams.ErrOut, "Successfully authenticated to %s\n", serverHost.Host)
fmt.Fprintf(o.Streams.ErrOut, "🔑 Successfully authenticated to %s\n", serverHost.Host)
}

if o.ShowToken {
Expand Down
5 changes: 3 additions & 2 deletions cli/pkg/kubectl/bind-templates/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ var (
%[1]s templates

# List templates from specific server
%[1]s templates https://mangodb.com
%[1]s templates

# List templates using --server flag to override current server
%[1]s templates --server https://mangodb.com

# List templates with JSON output
# List templates with JSON/YAML output
%[1]s templates -o json
%[1]s templates -o yaml
`
)

Expand Down
23 changes: 7 additions & 16 deletions cli/pkg/kubectl/bind/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"fmt"
"strings"

"github.com/fatih/color"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
logsv1 "k8s.io/component-base/logs/api/v1"
Expand All @@ -34,23 +33,19 @@ import (

var (
BindExampleUses = `
# Open kube-bind UI for current server context
%[1]s bind
# %[1]s bind login --server https://my-kube-bind-server.com

# Open kube-bind UI for specific server
%[1]s bind https://mangodb.com
# Open kube-bind UI for current server context
%[1]s bind

# List available templates (CLI mode)
%[1]s bind --dry-run
%[1]s bind templates

# Bind specific template (CLI mode)
%[1]s bind --template my-app

# Bind template with server override
%[1]s bind https://mangodb.com --template my-app
%[1]s bind apiservice --name my-api --template-name database-service

# View template details without binding
%[1]s bind --template my-app --dry-run
%[1]s bind apiservice --name my-api --template-name database-service --dry-run
`
)

Expand All @@ -64,9 +59,8 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
a web UI or command-line interface.

By default, 'kubectl bind' opens the kube-bind web UI in your browser.
Use the --template flag to bind specific templates via CLI.

For more information, see: https://kube-bind.io
For more information, see: https://docs.kube-bind.io
`),
Example: fmt.Sprintf(BindExampleUses, "kubectl"),
SilenceUsage: true,
Expand All @@ -89,9 +83,6 @@ func New(streams genericclioptions.IOStreams) (*cobra.Command, error) {
return err
}

yellow := color.New(color.BgRed, color.FgBlack).SprintFunc()
fmt.Fprintf(streams.ErrOut, "%s\n\n", yellow("DISCLAIMER: This is a prototype. It will change in incompatible ways at any time."))

if err := opts.Complete(args); err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions contrib/kcp/deploy/resources/apiexport-kube-bind.io.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ spec:
crd: {}
- group: kube-bind.io
name: apiserviceexporttemplates
schema: v251029-fadb9ed.apiserviceexporttemplates.kube-bind.io
schema: v251106-640871f.apiserviceexporttemplates.kube-bind.io
storage:
crd: {}
- group: kube-bind.io
Expand All @@ -79,7 +79,7 @@ spec:
crd: {}
- group: kube-bind.io
name: boundschemas
schema: v250918-f26732b.boundschemas.kube-bind.io
schema: v251106-640871f.boundschemas.kube-bind.io
storage:
crd: {}
- group: kube-bind.io
Expand All @@ -89,7 +89,7 @@ spec:
crd: {}
- group: kube-bind.io
name: collections
schema: v251022-ca928ec.collections.kube-bind.io
schema: v251106-640871f.collections.kube-bind.io
storage:
crd: {}
status: {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: apis.kcp.io/v1alpha1
kind: APIResourceSchema
metadata:
creationTimestamp: null
name: v251029-fadb9ed.apiserviceexporttemplates.kube-bind.io
name: v251106-640871f.apiserviceexporttemplates.kube-bind.io
spec:
group: kube-bind.io
names:
Expand All @@ -26,8 +26,10 @@ spec:
type: date
name: v1alpha2
schema:
description: APIServiceExportTemplate groups multiple CRDs with related resources
(permissionClaims) as a Service definition.
description: |-
APIServiceExportTemplate groups multiple CRDs with related resources (permissionClaims) as a Service definition.
It is used by a web UI or CLI to allow users to select a set of resources to export from provider cluster to consumer cluster.
This object is considered a static asset on the provider side and is not expected to change frequently.
properties:
apiVersion:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: apis.kcp.io/v1alpha1
kind: APIResourceSchema
metadata:
creationTimestamp: null
name: v250918-f26732b.boundschemas.kube-bind.io
name: v251106-640871f.boundschemas.kube-bind.io
spec:
conversion:
strategy: None
Expand All @@ -24,7 +24,9 @@ spec:
type: date
name: v1alpha2
schema:
description: BoundSchema
description: |-
BoundSchema defines the schema of a bound API resource. It is created on the provider side to track
CRD status on the consumer side by reflecting the CRD spec and status conditions.
properties:
apiVersion:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: apis.kcp.io/v1alpha1
kind: APIResourceSchema
metadata:
creationTimestamp: null
name: v251022-ca928ec.collections.kube-bind.io
name: v251106-640871f.collections.kube-bind.io
spec:
group: kube-bind.io
names:
Expand All @@ -26,8 +26,9 @@ spec:
type: date
name: v1alpha2
schema:
description: Collection groups multiple APIServiceExportTemplates into a logical
group. This functions as a folder in the UI.
description: |-
Collection groups multiple APIServiceExportTemplates into a logical group. This functions as a grouping mechanism
in UIs or CLIs to allow users to select a set of resources to export from provider cluster to consumer cluster.
properties:
apiVersion:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ spec:
name: v1alpha2
schema:
openAPIV3Schema:
description: APIServiceExportTemplate groups multiple CRDs with related resources
(permissionClaims) as a Service definition.
description: |-
APIServiceExportTemplate groups multiple CRDs with related resources (permissionClaims) as a Service definition.
It is used by a web UI or CLI to allow users to select a set of resources to export from provider cluster to consumer cluster.
This object is considered a static asset on the provider side and is not expected to change frequently.
properties:
apiVersion:
description: |-
Expand Down
4 changes: 3 additions & 1 deletion deploy/charts/backend/crds/kube-bind.io_boundschemas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ spec:
name: v1alpha2
schema:
openAPIV3Schema:
description: BoundSchema
description: |-
BoundSchema defines the schema of a bound API resource. It is created on the provider side to track
CRD status on the consumer side by reflecting the CRD spec and status conditions.
properties:
apiVersion:
description: |-
Expand Down
5 changes: 3 additions & 2 deletions deploy/charts/backend/crds/kube-bind.io_collections.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ spec:
name: v1alpha2
schema:
openAPIV3Schema:
description: Collection groups multiple APIServiceExportTemplates into a logical
group. This functions as a folder in the UI.
description: |-
Collection groups multiple APIServiceExportTemplates into a logical group. This functions as a grouping mechanism
in UIs or CLIs to allow users to select a set of resources to export from provider cluster to consumer cluster.
properties:
apiVersion:
description: |-
Expand Down
Loading