Skip to content
Open
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
42 changes: 42 additions & 0 deletions .github/workflows/cli.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: CLI

# Release the bind CLI on FINAL tags via goreleaser (archives, checksums,
# GitHub release), then let krew-release-bot render .krew.yaml and PR
# krew-index for the "bind" plugin (name kept from v1; archive binary is
# kubectl-bind).
#
# Release candidates (v*-rc*, any v*-* prerelease) do NOT release the CLI:
# users' binaries and the krew plugin only move forward on final versions.
# (Images still publish on every v* tag — see image.yaml — so RCs stay
# testable in-cluster.)
on:
push:
tags:
- 'v*'
- '!v*-*'

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: v1.26.2

# goreleaser run via `go run` (version-pinned) — no third-party action.
- name: Run goreleaser
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: go run github.com/goreleaser/goreleaser/v2@v2.5.0 release --clean

# Renders .krew.yaml against this release and PRs krew-index. Pinned by
# tag (upstream publishes no SHA-stable releases); it only needs the
# public release artifacts, no repo secrets.
- name: Update krew-index
uses: rajatjindal/krew-release-bot@v0.0.47
43 changes: 17 additions & 26 deletions .github/workflows/image.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Image

# Build and push the konnector image. Pushes only on tags:
# - tags v* -> ghcr.io/<owner>/konnector:<version>
# Build and push the konnector + backend images. Pushes only on tags:
# - tags v* -> ghcr.io/<owner>/konnector:<version>, ghcr.io/<owner>/backend:<version>
# No :latest or :<sha> tags — the image repo is shared with v1/main images.
on:
push:
Expand All @@ -18,17 +18,6 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Compute image tags
id: meta
run: |
owner="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')"
image="ghcr.io/${owner}/konnector"
tags="${image}:${GITHUB_REF_NAME}"
{
echo "image=${image}"
echo "tags=${tags}"
} >> "$GITHUB_OUTPUT"

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

Expand All @@ -43,16 +32,18 @@ jobs:
# BUILDPLATFORM), so no QEMU is required.
- name: Build and push
run: |
tag_args=""
for t in ${{ steps.meta.outputs.tags }}; do tag_args="${tag_args} --tag ${t}"; done
docker buildx build \
--platform linux/amd64,linux/arm64 \
${tag_args} \
--label "org.opencontainers.image.source=https://github.com/${{ github.repository }}" \
--label "org.opencontainers.image.revision=${{ github.sha }}" \
--label "org.opencontainers.image.title=konnector" \
--cache-from type=gha \
--cache-to type=gha,mode=max \
--provenance=false \
--push \
.
owner="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')"
for target in konnector backend; do
docker buildx build \
--platform linux/amd64,linux/arm64 \
--target "${target}" \
--tag "ghcr.io/${owner}/${target}:${GITHUB_REF_NAME}" \
--label "org.opencontainers.image.source=https://github.com/${{ github.repository }}" \
--label "org.opencontainers.image.revision=${{ github.sha }}" \
--label "org.opencontainers.image.title=${target}" \
--cache-from type=gha \
--cache-to type=gha,mode=max \
--provenance=false \
--push \
.
done
50 changes: 50 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# goreleaser config for the bind CLI (pinned to goreleaser v2.5.x in CI).
# Archives carry the binary as kubectl-bind for the krew "bind" plugin;
# krew-release-bot (not goreleaser's krews) PRs upstream krew-index.
version: 2

project_name: bind

builds:
- id: bind
main: ./cmd/bind
binary: kubectl-bind
env:
- CGO_ENABLED=0
- GOWORK=off
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
ignore:
- goos: windows
goarch: arm64
ldflags:
- -s -w -X github.com/kbind/kbind/cli/cmd.Version={{ .Tag }}

archives:
- id: bind
format: tar.gz
name_template: 'kubectl-bind_{{ .Tag }}_{{ .Os }}_{{ .Arch }}'
files:
- LICENSE

checksum:
name_template: checksums.txt

release:
# Attach to the tag's release; notes come from GitHub's generator.
mode: replace
# Belt and braces: the workflow already skips prerelease tags, but if
# goreleaser is ever run on one by hand, mark the GitHub release as a
# prerelease so it never becomes "latest".
prerelease: auto

snapshot:
version_template: '{{ .Tag }}-snapshot'

changelog:
use: github-native
54 changes: 54 additions & 0 deletions .krew.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# krew-release-bot template for the "bind" plugin (name kept from v1 — the
# CLI binary is kbind, installed via krew as `kubectl bind`). The bot renders
# this on every GitHub release and opens the krew-index PR.
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: bind
spec:
version: {{ .TagName }}
homepage: https://github.com/kbind-dev/kbind
shortDescription: Bind a service provider's APIs into your cluster
description: |
bind binds APIs exported by a provider cluster into your cluster:
log in to a provider's gateway, browse its catalog, and bind a service —
the result is a one-apply bundle (Secret + Connection + ClusterBinding)
consumed by the konnector, the only component that runs on your side.
Everything the CLI does is reproducible by hand with curl + kubectl.
caveats: |
Typical flow:
kubectl bind login https://provider.example.com
kubectl bind connect # install the konnector
kubectl bind catalog
kubectl bind export <name> # or: export <name> -o yaml (GitOps)
platforms:
- selector:
matchLabels:
os: darwin
arch: amd64
{{addURIAndSha "https://github.com/kbind-dev/kbind/releases/download/{{ .TagName }}/kubectl-bind_{{ .TagName }}_darwin_amd64.tar.gz" .TagName }}
bin: kubectl-bind
- selector:
matchLabels:
os: darwin
arch: arm64
{{addURIAndSha "https://github.com/kbind-dev/kbind/releases/download/{{ .TagName }}/kubectl-bind_{{ .TagName }}_darwin_arm64.tar.gz" .TagName }}
bin: kubectl-bind
- selector:
matchLabels:
os: linux
arch: amd64
{{addURIAndSha "https://github.com/kbind-dev/kbind/releases/download/{{ .TagName }}/kubectl-bind_{{ .TagName }}_linux_amd64.tar.gz" .TagName }}
bin: kubectl-bind
- selector:
matchLabels:
os: linux
arch: arm64
{{addURIAndSha "https://github.com/kbind-dev/kbind/releases/download/{{ .TagName }}/kubectl-bind_{{ .TagName }}_linux_arm64.tar.gz" .TagName }}
bin: kubectl-bind
- selector:
matchLabels:
os: windows
arch: amd64
{{addURIAndSha "https://github.com/kbind-dev/kbind/releases/download/{{ .TagName }}/kubectl-bind_{{ .TagName }}_windows_amd64.tar.gz" .TagName }}
bin: kubectl-bind.exe
26 changes: 19 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2026 The Kube Bind Authors.
# Copyright 2026 The Kbind Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,11 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# konnector image. Build context is the repo root; the root module is the
# konnector and pulls in the sibling sdk module via
# `replace github.com/kbind/kbind/sdk => ./sdk`:
# kbind images. Build context is the repo root; the root module pulls in the
# sibling sdk module via `replace github.com/kbind/kbind/sdk => ./sdk`:
#
# docker build -t kbind/konnector:dev .
# docker build -t kbind/konnector:dev . # default target
# docker build --target backend -t kbind/backend:dev .
#
# Pin the builder to the build host's native platform and cross-compile via
# GOARCH/GOOS (CGO disabled), so multi-arch builds need no QEMU emulation.
Expand All @@ -36,9 +36,21 @@ RUN go mod download

COPY cmd/ cmd/
COPY engine/ engine/
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="${LDFLAGS}" -o /bin/konnector ./cmd/konnector
COPY backend/ backend/
COPY cli/ cli/
COPY pkg/ pkg/
COPY web/ web/
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="${LDFLAGS}" -o /bin/konnector ./cmd/konnector && \
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="${LDFLAGS}" -o /bin/backend ./cmd/backend

FROM gcr.io/distroless/static:nonroot
# The provider-side service layer (gateway + issuer + reaper), module-flagged.
FROM gcr.io/distroless/static:nonroot AS backend
COPY --from=builder /bin/backend /bin/backend
USER 65532:65532
ENTRYPOINT ["/bin/backend"]

# The konnector — last stage, so a target-less build keeps producing it.
FROM gcr.io/distroless/static:nonroot AS konnector
COPY --from=builder /bin/konnector /bin/konnector
USER 65532:65532
ENTRYPOINT ["/bin/konnector"]
54 changes: 50 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2026 The Kube Bind Authors.
# Copyright 2026 The Kbind Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -20,6 +20,7 @@ GOLANGCI_LINT ?= golangci-lint
ENVTEST_K8S_VERSION ?= 1.34.1
SETUP_ENVTEST ?= go run sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.21
CHART ?= deploy/charts/konnector
BACKEND_CHART ?= deploy/charts/backend
IMAGE ?= ghcr.io/kbind/konnector:dev

.PHONY: all
Expand All @@ -34,29 +35,53 @@ build:
konnector:
go build -o bin/konnector ./cmd/konnector

# Container image. Build context is the repo root (see Dockerfile).
.PHONY: backend
backend:
go build -o bin/backend ./cmd/backend

.PHONY: bind
bind:
go build -o bin/bind ./cmd/bind

# CLI release archives for all platforms via goreleaser (kubectl-bind inside,
# for the krew "bind" plugin). Local dry-run; CI runs `release` on tags.
.PHONY: cli-snapshot
cli-snapshot:
goreleaser release --snapshot --clean

# Container images. Build context is the repo root (see Dockerfile).
.PHONY: image
image:
docker build -t $(IMAGE) .

BACKEND_IMAGE ?= ghcr.io/kbind/backend:dev
.PHONY: image-backend
image-backend:
docker build --target backend -t $(BACKEND_IMAGE) .

.PHONY: helm-lint
helm-lint:
helm lint $(CHART)
helm lint $(BACKEND_CHART) --set oidc.mock=true

# Render the chart to stdout for review (extra flags via HELM_ARGS=...).
# Render the charts to stdout for review (extra flags via HELM_ARGS=...).
.PHONY: helm-template
helm-template:
helm template konnector $(CHART) -n kbind $(HELM_ARGS)
helm template backend $(BACKEND_CHART) -n kbind --set oidc.mock=true $(HELM_ARGS)

# Refresh the chart's bundled CRDs from the generated sdk CRDs.
# Refresh the charts' bundled CRDs from the generated sdk CRDs.
.PHONY: helm-sync-crds
helm-sync-crds: codegen
cp sdk/config/crd/core.kbind.io_*.yaml $(CHART)/files/crds/
cp sdk/config/crd/catalog.kbind.io_*.yaml sdk/config/crd/iam.kbind.io_*.yaml $(BACKEND_CHART)/files/crds/

.PHONY: codegen
codegen:
cd sdk && $(CONTROLLER_GEN) object paths=./apis/...
cd sdk && $(CONTROLLER_GEN) crd paths=./apis/... output:crd:dir=./config/crd
cp sdk/config/crd/core.kbind.io_*.yaml pkg/konnectorinstall/manifests/crds/
cp sdk/config/crd/catalog.kbind.io_*.yaml sdk/config/crd/iam.kbind.io_*.yaml pkg/servicecrds/crds/

# Unit tests only. The envtest-based e2e (which needs KUBEBUILDER_ASSETS) is a
# separate target so `make test` runs with no external setup.
Expand Down Expand Up @@ -104,3 +129,24 @@ verify: vet verify-boilerplate
.PHONY: demo
demo:
./hack/demo.sh

# Tilt dev loop: two kind clusters (provider backend + consumer konnector),
# seeded catalog, rebuild-on-change — one command.
.PHONY: tilt
tilt:
./hack/tilt/kind.sh
# --stream: no interactive HUD (make provides no TTY); the web UI is on
# http://localhost:10350 regardless.
cd hack/tilt && tilt up --stream

# One-shot variant: deploy everything, wait until healthy, exit (CI-style).
.PHONY: tilt-ci
tilt-ci:
./hack/tilt/kind.sh
cd hack/tilt && tilt ci

# Tear the dev loop down: delete both kind clusters.
.PHONY: tilt-down
tilt-down:
kind delete cluster --name kbind-provider || true
kind delete cluster --name kbind-consumer || true
Loading