Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
89 changes: 56 additions & 33 deletions .github/workflows/airbox-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,61 @@ permissions:
contents: write

jobs:
create-release:
name: Build and publish airbox release
release:
runs-on: ubuntu-latest
steps:
- name: Validate tag
run: |
if [[ ! "${{ inputs.tag_name }}" =~ ^airbox-v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "tag is invalid: must be in the form 'airbox-v0.0.0'"
exit 1
fi
- name: Create tag
uses: actions/github-script@v5
with:
script: |
github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'refs/tags/${{ inputs.tag_name }}',
sha: context.sha
})
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version: 'stable'

- name: Run GoReleaser for Airbox
uses: goreleaser/goreleaser-action@v6
env:
GITHUB_TOKEN: ${{ secrets.github_token }}
with:
distribution: goreleaser
version: "~> v2"
args: release --config .goreleaser-airbox.yaml --clean
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.24'

- name: Get version from tag
id: version
run: |
TAG_NAME="${{ inputs.tag_name }}"
VERSION=${TAG_NAME#airbox-}
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "FULL_TAG=$TAG_NAME" >> $GITHUB_OUTPUT
if [[ "$VERSION" =~ (beta|rc|alpha) ]]; then
echo "PRERELEASE=true" >> $GITHUB_OUTPUT
else
echo "PRERELEASE=false" >> $GITHUB_OUTPUT
fi

- name: Build binaries
run: |
GOOS=linux GOARCH=amd64 go build -o ./dist/airbox-linux-amd64 ./cmd/airbox
GOOS=linux GOARCH=arm64 go build -o ./dist/airbox-linux-arm64 ./cmd/airbox
GOOS=darwin GOARCH=amd64 go build -o ./dist/airbox-darwin-amd64 ./cmd/airbox
GOOS=darwin GOARCH=arm64 go build -o ./dist/airbox-darwin-arm64 ./cmd/airbox
GOOS=windows GOARCH=amd64 go build -o ./dist/airbox-windows-amd64.exe ./cmd/airbox

cd ./dist
tar -czf airbox-linux-amd64.tar.gz airbox-linux-amd64
tar -czf airbox-linux-arm64.tar.gz airbox-linux-arm64
tar -czf airbox-darwin-amd64.tar.gz airbox-darwin-amd64
tar -czf airbox-darwin-arm64.tar.gz airbox-darwin-arm64
zip airbox-windows-amd64.zip airbox-windows-amd64.exe

- name: Create Tag
run: |
git config user.name github-actions
git config user.email [email protected]
git tag ${{ inputs.tag_name }}
git push origin ${{ inputs.tag_name }}

- name: Create Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ inputs.tag_name }}
name: Airbox ${{ steps.version.outputs.VERSION }}
body: Airbox ${{ steps.version.outputs.VERSION }}
files: |
dist/*.tar.gz
dist/*.zip
draft: false
prerelease: ${{ steps.version.outputs.PRERELEASE }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 changes: 0 additions & 33 deletions .goreleaser-airbox.yaml

This file was deleted.

5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ vet:
mocks:
mockgen --source $(GOPATH)/pkg/mod/github.com/mittwald/[email protected]/interface.go -destination internal/helm/mock/mock.go -package mock
mockgen --source internal/http/client.go -destination internal/http/mock/mock.go -package mock
mockgen --source internal/ui/ui.go -destination internal/ui/mock/mock.go -package mock
mockgen --source internal/airbox/config_store.go -destination internal/airbox/mock/config.go -package mock
mockgen --source internal/auth/auth.go -destination internal/auth/mocks_creds_test.go -package auth
mockgen --source internal/api/client.go -destination internal/api/mock/mock.go -package mock
mockgen --source internal/k8s/cluster.go -destination internal/k8s/mock/cluster.go -package mock

.PHONY: tools
tools:
Expand Down
245 changes: 245 additions & 0 deletions cmd/airbox/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
# Airbox CLI

Airbox is a command-line tool for managing Airbyte dataplanes on Kubernetes.

## Installation

Build from source:
```bash
go build -o airbox ./cmd/airbox
```

## Quick Start

```bash
# 1. Configure airbox with your Airbyte instance
airbox config init

# 2. Authenticate with Airbyte
airbox auth login

# 3. Install a dataplane on your Kubernetes cluster
airbox install dataplane
Comment on lines +21 to +22
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should flip this to airbox dataplane install as that would mimic abctl more in the abctl local install order of operations.

```

## Configuration

### Environment Variables

- `AIRBOXCONFIG`: Override the default config file location (default: `~/.airbyte/airbox/config`)
- `AIRBYTE_CLIENT_ID`: OAuth2 client ID for authentication
- `AIRBYTE_CLIENT_SECRET`: OAuth2 client secret for authentication

### Initialization

Initialize your airbox configuration:
```bash
airbox config init
```

This will prompt you to:
- What Airbyte control plane are you connecting to (Cloud or Enterprise)

For **Cloud**: Automatically configures cloud.airbyte.com URLs
For **Enterprise**: You'll be prompted for:
- Your Airbyte instance URL (e.g., https://airbyte.yourcompany.com)
- API host is automatically set to your URL + "/api"
- Edition is automatically set to "enterprise"
- Context name defaults to "enterprise"

Both Cloud and Enterprise use OAuth2 authentication only.

## Authentication

**OAuth2 Authentication (Both Cloud and Enterprise):**

Set your OAuth2 client credentials as environment variables:

```bash
export AIRBYTE_CLIENT_ID="your-oauth-client-id"
export AIRBYTE_CLIENT_SECRET="your-oauth-client-secret"
```

Login to authenticate with Airbyte:
```bash
airbox auth login
```

This will:
1. Use OAuth2 client credentials from environment variables
2. Authenticate via OAuth2 client credentials flow
3. Save access tokens locally in YAML format
4. Prompt you to select an organization context (if not already set)

Logout and clear stored credentials:
```bash
airbox auth logout
```

This removes your saved authentication tokens from local storage.

Switch between Airbyte organization contexts:
```bash
airbox auth switch-organization
```

## Dataplane Management

### Install Dataplane

Install a dataplane on your Kubernetes cluster:
```bash
airbox install dataplane
```

This interactive command will:
1. Prompt for organization and region selection
2. Ask for a dataplane name
3. Create a new Kind cluster (default)
4. Register the dataplane with Airbyte Cloud/Enterprise
5. Deploy the dataplane using Helm with the provided credentials
6. Configure the dataplane to connect to your Airbyte control plane

### Get Resources

List dataplanes:
```bash
airbox get dataplane
```

Get specific dataplane by ID:
```bash
airbox get dataplane <dataplane-id>
```

Output in YAML format:
```bash
airbox get dataplane -o yaml
```

### Delete Dataplane

Remove a dataplane registration:
```bash
airbox delete dataplane <dataplane-id>
```

Note: This only removes the registration from Airbyte. You must manually uninstall the Helm release from Kubernetes.

## Global Options

- `--help, -h`: Show help for any command

## Examples

Complete workflow:
```bash
# Set up authentication credentials
export AIRBYTE_CLIENT_ID="your-client-id"
export AIRBYTE_CLIENT_SECRET="your-client-secret"

# Initialize configuration
airbox config init

# Authenticate
airbox auth login

# Install the dataplane (handles both registration and deployment)
airbox install dataplane

# Verify installation
airbox get dataplane
```

## Uninstalling a Dataplane

### For Kind-based installations

Kind clusters created by airbox follow the naming pattern: `airbox-<dataplane-name>`

```bash
# List all Kind clusters to find yours
kind get clusters

# Example output:
# airbox-test-dp
# airbox-dev-dp
# airbox-demo-dp

# Delete the dataplane registration from Airbyte
airbox delete dataplane <dataplane-id>

# Delete the Kind cluster (using the full cluster name with airbox- prefix)
kind delete cluster --name airbox-test-dp
```

### For existing Kubernetes clusters

```bash
# Delete the dataplane registration from Airbyte
airbox delete dataplane <dataplane-id>

# Uninstall the Helm release
helm uninstall <dataplane-name> -n <namespace>
```

## Running Syncs

After installing a dataplane, create connections in the Airbyte web UI using the same workspace and region as your dataplane. When you trigger a sync, you'll see pods created in your Kubernetes cluster:

```bash
# Watch pods to see sync activity
watch kubectl get po

Every 2.0s: kubectl get po

NAME READY STATUS RESTARTS AGE
my-dataplane-airbyte-data-plane-567f98c6d9 1/1 Running 0 5m12s
replication-job-15-attempt-0 0/3 Completed 0 2m18s
source-postgres-discover-15-0-xyz123 0/2 Completed 0 2m45s
```

The dataplane handles all job scheduling within your cluster while reporting status to the Airbyte control plane.

## Configuration File

Airbox stores configuration in `~/.airbyte/airbox/config` (YAML format).

After running `airbox config init` and `airbox auth login`, your config file will look like this:

```yaml
current-context: cloud
credentials:
access_token: [REDACTED]
token_type: Bearer
expires_at: 2025-09-08T18:06:30.147961-07:00
contexts:
- name: cloud
context:
airbyteApiHost: https://api.airbyte.com
airbyteUrl: https://cloud.airbyte.com
organizationId: [REDACTED]
edition: cloud
auth:
clientId: [REDACTED]
clientSecret: [REDACTED]
type: oauth2
```

The config file contains:
- **current-context**: Active context name
- **credentials**: OAuth2 access tokens and expiry (added after login)
- **contexts**: Named configurations for different Airbyte instances
- **airbyteApiHost**: API endpoint URL
- **airbyteUrl**: Web UI URL
- **organizationId**: Selected organization UUID (added after login)
- **edition**: Deployment edition (cloud/enterprise/community)
- **auth**: OAuth2 client credentials

## Requirements

- Go 1.21+
- Access to Airbyte Cloud or Enterprise
- Kubernetes cluster (for dataplane installation)
- Helm 3.x (for dataplane installation)
- Kind (optional, for local development)
Loading