diff --git a/control/api/handler.js b/control/api/handler.js index 7cc8e5c..8d9ed2b 100644 --- a/control/api/handler.js +++ b/control/api/handler.js @@ -1,7 +1,5 @@ 'use strict'; -const AWS = require('aws-sdk'); - const { CONTROL_API_TOKEN, GITHUB_TOKEN, @@ -51,31 +49,6 @@ async function dispatchWorkflow(inputs) { } } -async function listInstances() { - const ec2 = new AWS.EC2(); - const resp = await ec2 - .describeInstances({ - Filters: [{ Name: 'tag:app', Values: ['clawdinator'] }], - }) - .promise(); - - const instances = []; - for (const reservation of resp.Reservations || []) { - for (const instance of reservation.Instances || []) { - const tags = instance.Tags || []; - const nameTag = tags.find((tag) => tag.Key === 'Name'); - instances.push({ - name: nameTag ? nameTag.Value : 'unknown', - id: instance.InstanceId, - state: instance.State ? instance.State.Name : 'unknown', - ami: instance.ImageId, - ip: instance.PublicIpAddress || 'n/a', - }); - } - } - - return instances; -} exports.handler = async (event) => { if (!CONTROL_API_TOKEN) { @@ -115,12 +88,7 @@ exports.handler = async (event) => { } if (action === 'status') { - try { - const instances = await listInstances(); - return json(200, { ok: true, instances }); - } catch (err) { - return json(500, { ok: false, error: err.message }); - } + return json(400, { ok: false, error: 'status not supported via api' }); } if (action !== 'deploy') { diff --git a/docs/CONTROL_PLANE.md b/docs/CONTROL_PLANE.md index 6cbe498..d99e3f7 100644 --- a/docs/CONTROL_PLANE.md +++ b/docs/CONTROL_PLANE.md @@ -21,10 +21,11 @@ Goal: manage CLAWDINATOR host lifecycle (create/recreate/replace) from **CLAWDIN - Infra state must be out‑of‑band and locked. ## Control Plane Components (KISS) -- **Control API (AWS Lambda Function URL)** - - Authenticated by a shared bearer token. - - Dispatches GitHub Actions workflows. - - Handles `/fleet status` via AWS DescribeInstances. +- **Control API (AWS Lambda)** + - Authenticated by a shared control token. + - Dispatches GitHub Actions workflows (deploy only). +- **Fleet status** + - Fetched locally via AWS CLI using control invoker credentials. - **Fleet Control Skill** (runs inside CLAWDINATOR) - Calls the Control API via `scripts/fleet-control.sh` (AWS IAM invoke). - Enforces policy (no self‑deploy) before calling. @@ -82,7 +83,7 @@ Example: - Also creates new instances if present in desired state. ### `/fleet status` -- Returns live fleet status (EC2 describe by tag). +- Returns live fleet status via AWS CLI (EC2 describe by tag). ## Access Control (Policy) - Shared control token authorizes calls to the Control API. diff --git a/scripts/fleet-control.sh b/scripts/fleet-control.sh index d82eb40..c8ef6f9 100755 --- a/scripts/fleet-control.sh +++ b/scripts/fleet-control.sh @@ -32,6 +32,16 @@ fi control_token="$(cat "${token_file}")" caller="$(cat "${caller_file}")" +region="${AWS_REGION:-eu-central-1}" +export AWS_ACCESS_KEY_ID="$(cat "${access_key_file}")" +export AWS_SECRET_ACCESS_KEY="$(cat "${secret_key_file}")" +export AWS_REGION="${region}" + +if [ "${action}" = "status" ]; then + /var/lib/clawd/repos/clawdinators/scripts/fleet-status.sh + exit 0 +fi + if [ "${action}" = "deploy" ]; then if [ -z "${target}" ]; then echo "Target required. Usage: fleet-control.sh deploy " >&2 @@ -52,10 +62,6 @@ payload="$(jq -n \ --arg control_token "${control_token}" \ '{action: $action, target: $target, caller: $caller, ami_override: $ami_override, control_token: $control_token}')" -region="${AWS_REGION:-eu-central-1}" -export AWS_ACCESS_KEY_ID="$(cat "${access_key_file}")" -export AWS_SECRET_ACCESS_KEY="$(cat "${secret_key_file}")" - response_file="$(mktemp)" aws lambda invoke \ --function-name "clawdinator-control-api" \ @@ -67,15 +73,4 @@ aws lambda invoke \ response="$(cat "${response_file}")" rm -f "${response_file}" -if [ "${action}" = "status" ]; then - ok="$(printf '%s' "${response}" | jq -r '.ok')" - if [ "${ok}" != "true" ]; then - echo "${response}" >&2 - exit 1 - fi - echo "Name | InstanceId | State | AMI | Public IP" - printf '%s' "${response}" | jq -r '.instances[] | "\(.name) | \(.id) | \(.state) | \(.ami) | \(.ip)"' - exit 0 -fi - echo "${response}"