Skip to content

Testing babyctl API Server with kubectl

This guide shows how to use the babyctl API server with kubectl.

Prerequisites

  • kubectl installed
  • babyctl built and installed
  • Example API definitions installed at ~/.babyctl/apis

Setup

  1. Install the example API definitions (they mirror what the integration tests use in examples/api-definitions/apis):

    mkdir -p ~/.babyctl
    cp -r examples/api-definitions/apis ~/.babyctl/
    

  2. Start the API server (the --api-path flag can point to any directory that contains the same layout):

    babyctl api-server --port 8080
    

The server will start and listen on port 8080, serving API definitions from ~/.babyctl/apis.

  1. (Optional) Run the smoke test script to make sure discovery works end-to-end:
    ./test-api-server.sh
    
    The script starts the server in the background, runs kubectl api-resources, and tears the process down automatically.

If you want to mirror the CRUD portion of the test suite manually, apply the sample Widget manifest the script exercises:

cat <<'EOF' | kubectl --server=http://localhost:8080 apply -f -
apiVersion: babyctl.dev/v1alpha1
kind: Widget
metadata:
  name: smoke-test
spec:
  color: blue
  size: small
EOF

You can then kubectl get widgets or kubectl delete widget smoke-test to finish the lifecycle.

Using with kubectl

Test API Discovery

# List all API groups
kubectl --server=http://localhost:8080 api-resources

# List all API versions
kubectl --server=http://localhost:8080 api-versions

Validate raw discovery responses

When debugging it is often useful to inspect the JSON payloads directly:

# Core group
kubectl --server=http://localhost:8080 get --raw /api | jq

# All named groups
kubectl --server=http://localhost:8080 get --raw /apis | jq

# One specific group/version
kubectl --server=http://localhost:8080 get --raw /apis/apps/v1 | jq

Try the sample Widgets resource

The bundled babyctl.dev/v1alpha1 group now ships with a Widget resource driven by bash controllers that store JSON files under examples/api-definitions/state/widgets. You can exercise all CRUD verbs straight from kubectl:

cat <<'EOF' > widget.yaml
apiVersion: babyctl.dev/v1alpha1
kind: Widget
metadata:
  name: demo
spec:
  color: blue
  size: small
EOF

kubectl --server=http://localhost:8080 apply -f widget.yaml
kubectl --server=http://localhost:8080 get widgets
kubectl --server=http://localhost:8080 get widget demo -o yaml
kubectl --server=http://localhost:8080 delete widget demo

Expected Output

When you run kubectl --server=http://localhost:8080 api-resources, you should see output similar to:

NAME                APIVERSION                          NAMESPACED   KIND
deployments         apps/v1                             true         Deployment
statefulsets        apps/v1                             true         StatefulSet
daemonsets          apps/v1                             true         DaemonSet
replicasets         apps/v1                             true         ReplicaSet
repositories        terraformer.github/v0.8.30          false        Repository
teams               terraformer.github/v0.8.30          false        Team
members             terraformer.github/v0.8.30          false        Member
organization        terraformer.github/v0.8.30          false        Organization
instances           terraformer.aws/v0.8.30             false        Instance
buckets             terraformer.aws/v0.8.30             false        Bucket
vpcs                terraformer.aws/v0.8.30             false        VPC
securitygroups      terraformer.aws/v0.8.30             false        SecurityGroup

Testing with curl

You can also test the API directly with curl:

# Get core API
curl http://localhost:8080/api

# Get all API groups
curl http://localhost:8080/apis

# Get resources in a specific group/version
curl http://localhost:8080/apis/apps/v1
curl http://localhost:8080/apis/terraformer.github/v0.8.30

Creating Custom API Definitions

You can create your own API definitions by adding YAML files to ~/.babyctl/apis:

  1. Create a directory structure:

    mkdir -p ~/.babyctl/apis/mygroup/v1
    

  2. Create a resources.yaml file:

    kind: APIResourceList
    apiVersion: v1
    groupVersion: mygroup/v1
    resources:
      - name: myresources
        singularName: myresource
        namespaced: true
        kind: MyResource
        verbs:
          - get
          - list
          - create
          - update
          - delete
        shortNames:
          - mr
        categories:
          - all
    

  3. Restart the API server to pick up the new definition

  4. Test with kubectl:

    kubectl --server=http://localhost:8080 api-resources | grep myresources
    

Using babyctl Commands

You can also use babyctl commands while pointing at the API server:

# Note: This will use the API server endpoints for discovery
babyctl --server=http://localhost:8080 api-resources
babyctl --server=http://localhost:8080 api-versions

Integration with kubeconfig

For easier use, you can add the API server to your kubeconfig:

kubectl config set-cluster babyctl-api --server=http://localhost:8080
kubectl config set-context babyctl-api --cluster=babyctl-api
kubectl config use-context babyctl-api

Then you can use kubectl without specifying the server each time:

kubectl api-resources
kubectl api-versions

Notes

  • The API server only implements the discovery endpoints (GET /api, GET /apis, GET /apis//)
  • It does not handle actual resource CRUD operations (get, create, update, delete)
  • This is designed for API discovery and metadata purposes, not for managing actual resources
  • For resource management, continue to use kubectl against a real Kubernetes cluster or babyctl for terraform resources

Troubleshooting

  • Empty discovery output – check that the server logged “API definitions loaded from …” without errors and that ~/.babyctl/apis contains at least one resources.yaml file. Missing directories cause the CLI to print a warning at startup and kubectl will return no resources.
  • kubectl refuses HTTP – by default kubectl prefers HTTPS. Supplying --server=http://localhost:8080 (as shown above) forces it to use HTTP. If you want a kubeconfig entry instead, ensure server: http://localhost:8080 is set for the context you activate.
  • Port already in use – pass --port <number> when launching babyctl api-server to bind to a different TCP port, and update your kubectl commands accordingly.