-
Notifications
You must be signed in to change notification settings - Fork 11
feat: airbox #181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
bernielomax
wants to merge
18
commits into
main
Choose a base branch
from
bernielomax/feat/dataplane-management
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
feat: airbox #181
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
8cea760
chore: Go mod update for Airbox command
bernielomax ef96b67
feat: add terminal UI package with bubbletea components
bernielomax b0854fb
feat: enhance HTTP client with improved error handling and testing
bernielomax e0111fe
refactor: refactor auth package with OAuth2/OIDC provider architecture
bernielomax c1d1ca8
feat: add organizations and regions API support
bernielomax fb2a608
feat: add dataplane Helm chart management
bernielomax 61bd359
feat: add airbox configuration and authentication system
bernielomax 2d91619
feat: add output formatting utility for commands
bernielomax 166bb8c
feat: add k8s factory pattern for cluster management
bernielomax 4b36401
feat: add airbox config init command
bernielomax 0da7edb
feat: add airbox authentication commands
bernielomax 2b50e0a
feat: add airbox dataplane installation command
bernielomax 9bba10f
feat: add airbox get commands for dataplanes
bernielomax 8e782e9
feat: add airbox delete commands for dataplanes
bernielomax c60c9b8
feat: add airbox CLI main command structure
bernielomax 711468e
docs: add airbox CLI documentation
bernielomax 5c60fad
chore: add airbox mock generation to Makefile
bernielomax bac3176
chore: fix action
bernielomax File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 }} |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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: | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` | ||
|
||
## 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) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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 mimicabctl
more in theabctl local install
order of operations.