feat: complete MQ-only dispatcher and OSS upload flow

This commit is contained in:
2026-09-22 21:09:06 +08:00
parent 704652bd0d
commit a2fcc4aabb
265 changed files with 18689 additions and 1469 deletions
+58
View File
@@ -20,6 +20,64 @@ the Agent/Dispatcher must fail closed rather than wait, retry, delay or switch
trunks. A prior confirmation does not authorize retries or another target; stop
after a failed attempt until a new confirmation is received.
## One deployment directory
`deploys/` is the only deployment directory for local checks, physical-host
packages, Asterisk installation, configuration examples and systemd services.
There is no separate draft service set or compatibility deployment directory.
## Local and isolated checks
From the project root:
```sh
make check
make release
./dist/sip-go-agent agent --help
./dist/sip-go-agent dispatcher --help
```
`make release` creates a local-development binary, module copies, SHA-256
checksums and a manifest. A dirty-source marker is preserved; a local build is
not a signed production candidate or proof of external service acceptance.
For an isolated Dispatcher-to-Agent startup check, prepare the strict Dispatcher
JSON configuration from `config/dispatcher.json.example`, inject its referenced
credentials outside the repository, and supply the deployment-owned endpoint
inventory and mTLS files. The local acceptance script also requires a loopback
RabbitMQ URL because `dispatcher --once` must prove it can publish through the
configured broker; it fails closed when the URL is absent:
```sh
GO_SIP_LOCAL_MQ_URL=amqp://guest:guest@127.0.0.1:33252/ \
./scripts/acceptance-local.sh
```
The command below is the long-running endpoint check:
```sh
SIP_GO_AGENT_MODE=mock \
DISPATCHER_DB=./dispatcher.db \
DISPATCHER_AGENT_ENDPOINTS_FILE=./deploys/config/agent-endpoints.example.json \
MTLS_CA_FILE=/path/to/ca.pem \
MTLS_CERT_FILE=/path/to/dispatcher.pem \
MTLS_KEY_FILE=/path/to/dispatcher.key \
./dist/sip-go-agent dispatcher --config /path/to/dispatcher.json --once
```
The Dispatcher probes the configured Agent, verifies its boot identity and
activates a session before use. Tenant commands cannot select an endpoint or
certificate. Agent RPC listening uses `AGENT_GRPC_LISTEN` and deployment-provided
mTLS files; an Agent-side peer allowlist can be supplied with
`MTLS_PEER_CERT_FINGERPRINTS`. Never place credentials or private keys in this
repository.
Dispatcher owns its SQLite database; Agent owns a separate `AGENT_SPOOL` and has
no business database. These are single-node, single-Agent/Cell/tenant checks,
not multi-Cell or production acceptance. Local protocol tests do not replace
the mandatory deployment/capture diagnostics below. Mock is not authorization
for real calls or paid provider requests.
## Build an uploadable package
From the project root:
+12
View File
@@ -0,0 +1,12 @@
{
"schema_version": "1.0",
"dispatcher_id": "c046b893-8628-4589-ae50-619d049248a6",
"oss": {
"endpoint": "https://oss-cn-beijing.aliyuncs.com",
"region": "cn-beijing",
"bucket": "example-bucket",
"object_prefix": "agent-call/recordings",
"access_key_id_env": "GO_SIP_OSS_ACCESS_KEY_ID",
"access_key_secret_env": "GO_SIP_OSS_ACCESS_KEY_SECRET"
}
}
+9 -14
View File
@@ -1,24 +1,19 @@
# Production physical-host example. Inject secrets and approved paths out of band.
# Physical-host example; real deployment requires separate authorization.
# Install dispatcher.json from deploys/config/dispatcher.json.example and replace
# its example dispatcher_id with this installation's unique stable UUID v4.
SIP_GO_AGENT_MODE=real
DISPATCHER_ID=dispatcher-primary
DISPATCHER_DB=/var/lib/sip-go-agent/dispatcher/dispatcher.db
RABBITMQ_EXCHANGE=agent-call.commands.v1
DISPATCHER_TENANT_KEY=<approved-original-tenant-key>
# RABBITMQ_URL=<injected-broker-url>
DISPATCHER_AGENT_ENDPOINTS_FILE=/etc/sip-go-agent/agent-endpoints.json
MTLS_CA_FILE=/etc/sip-go-agent/pki/ca.pem
MTLS_CERT_FILE=/etc/sip-go-agent/pki/dispatcher.pem
MTLS_KEY_FILE=/etc/sip-go-agent/pki/dispatcher.key
MTLS_SERVER_NAME=dispatcher.internal
# Single Dispatcher AgentControl gRPC listener. Agent facts and upload RPCs share it; Agents receive only presigned PUT grants.
DISPATCHER_GRPC_LISTEN=127.0.0.1:19443
DISPATCHER_ALLOWED_AGENT_IDS=agent-cell-a
DISPATCHER_OSS_REGION=cn-beijing
DISPATCHER_OSS_ENDPOINT=oss-cn-beijing-internal.aliyuncs.com
DISPATCHER_OSS_BUCKET=<injected-bucket>
DISPATCHER_OSS_KEY_PREFIX=agent-call/recordings
DISPATCHER_OSS_GRANT_TTL_SECONDS=900
DISPATCHER_OSS_MAX_ASSET_BYTES=67108864
DISPATCHER_OSS_ACCESS_KEY_ID_FILE=/etc/sip-go-agent/secrets/oss-access-key-id
DISPATCHER_OSS_ACCESS_KEY_SECRET_FILE=/etc/sip-go-agent/secrets/oss-access-key-secret
# DISPATCHER_CONTROL_LISTEN=127.0.0.1:18080
# DISPATCHER_CONTROL_TOKEN=<injected-secret>
# MTLS_PEER_CERT_FINGERPRINTS=<approved-agent-certificate-fingerprint>
# Inject only the credential variables explicitly referenced by dispatcher.json.
# Never put actual values in this example or commit them:
# GO_SIP_OSS_ACCESS_KEY_ID=<injected-at-runtime>
# GO_SIP_OSS_ACCESS_KEY_SECRET=<injected-at-runtime>
+5 -11
View File
@@ -1,12 +1,6 @@
# Offline/non-ECS OSS integration profile.
# Do not use this profile as the production ECS profile.
# Isolated non-production profile; not permission to access real OSS.
SIP_GO_AGENT_MODE=mock
DISPATCHER_OSS_REGION=cn-beijing
DISPATCHER_OSS_ENDPOINT=oss-cn-beijing.aliyuncs.com
DISPATCHER_OSS_BUCKET=<injected-offline-test-bucket>
DISPATCHER_OSS_KEY_PREFIX=agent-call/offline-recordings
DISPATCHER_OSS_GRANT_TTL_SECONDS=900
DISPATCHER_OSS_MAX_ASSET_BYTES=67108864
# Supply these through protected runtime files; never commit or log credentials.
DISPATCHER_OSS_ACCESS_KEY_ID_FILE=/run/secrets/oss-access-key-id
DISPATCHER_OSS_ACCESS_KEY_SECRET_FILE=/run/secrets/oss-access-key-secret
# OSS endpoint/bucket/prefix and credential references come only from the
# required --config JSON file. Inject its referenced credential variables via
# the controlled local test launcher; do not store keys in this example.
# Keep real egress blocked unless separately authorized.
@@ -9,7 +9,7 @@ User=rogee
Group=rogee
WorkingDirectory=/opt/sip-go-agent/current
EnvironmentFile=/etc/sip-go-agent/dispatcher.env
ExecStart=/opt/sip-go-agent/current/sip-go-agent dispatcher
ExecStart=/opt/sip-go-agent/current/sip-go-agent dispatcher --config /etc/sip-go-agent/dispatcher.json --consume --tenant-key ${DISPATCHER_TENANT_KEY}
Restart=on-failure
RestartSec=5s
NoNewPrivileges=yes