Add open enrollment + update Windows installer
Open enrollment (OPEN_ENROLLMENT=true in .env): - Agents can register with just --server <url>, no token needed - Machines assigned to OPEN_ENROLLMENT_USER_EMAIL, first admin, or first user - Falls back gracefully if env var not set - agent.py register() now takes optional token; --server alone triggers registration Agent CLI changes: - --server without --enroll triggers open enrollment registration on first run - --enroll still works for token-based or re-enrollment - Error message updated to reflect new syntax NSIS installer changes: - Interactive mode: custom page prompts for server URL + optional token - Silent mode: /SERVER= alone works with open enrollment, /ENROLL= still supported - Cleans up config on uninstall agent.spec: add pyperclip, base64, struct, uuid to hidden imports docker-compose + .env: OPEN_ENROLLMENT and OPEN_ENROLLMENT_USER_EMAIL vars Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -112,24 +112,26 @@ def save_config(data: dict):
|
||||
|
||||
# ── Registration ──────────────────────────────────────────────────────────────
|
||||
|
||||
async def register(server_url: str, enrollment_token: str) -> dict:
|
||||
"""Self-register with the server using an enrollment token."""
|
||||
async def register(server_url: str, enrollment_token: Optional[str] = None) -> dict:
|
||||
"""Self-register with the server. Token is optional when open enrollment is enabled."""
|
||||
hostname = platform.node()
|
||||
os_name = platform.system()
|
||||
os_version = platform.version()
|
||||
|
||||
payload: dict = {
|
||||
"name": hostname,
|
||||
"hostname": hostname,
|
||||
"os": os_name,
|
||||
"osVersion": os_version,
|
||||
"agentVersion": AGENT_VERSION,
|
||||
"macAddress": get_mac_address(),
|
||||
}
|
||||
if enrollment_token:
|
||||
payload["enrollmentToken"] = enrollment_token
|
||||
|
||||
url = f"{server_url.rstrip('/')}/api/agent/register"
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.post(url, json={
|
||||
"enrollmentToken": enrollment_token,
|
||||
"name": hostname,
|
||||
"hostname": hostname,
|
||||
"os": os_name,
|
||||
"osVersion": os_version,
|
||||
"agentVersion": AGENT_VERSION,
|
||||
"ipAddress": None,
|
||||
"macAddress": get_mac_address(),
|
||||
})
|
||||
resp = await client.post(url, json=payload)
|
||||
if resp.status_code != 200:
|
||||
raise RuntimeError(f"Registration failed: {resp.status_code} {resp.text}")
|
||||
data = resp.json()
|
||||
@@ -815,11 +817,25 @@ async def main():
|
||||
config = load_config()
|
||||
|
||||
# ── First-time registration ──────────────────────────────────────────────
|
||||
if args.enroll:
|
||||
if args.server and not config:
|
||||
# Register with enrollment token (if provided) or open enrollment
|
||||
log.info(f"Registering with server {args.server}…")
|
||||
reg = await register(args.server, args.enroll or None)
|
||||
relay_url = args.relay or _default_relay_url(args.server)
|
||||
config = {
|
||||
"server_url": args.server,
|
||||
"relay_url": relay_url,
|
||||
"machine_id": reg["machineId"],
|
||||
"access_key": reg["accessKey"],
|
||||
}
|
||||
if not args.run_once:
|
||||
save_config(config)
|
||||
elif args.enroll:
|
||||
# Re-enroll existing machine with a new token (replaces config)
|
||||
if not args.server:
|
||||
log.error("--server is required with --enroll")
|
||||
sys.exit(1)
|
||||
log.info(f"Enrolling with server {args.server}…")
|
||||
log.info(f"Re-enrolling with server {args.server}…")
|
||||
reg = await register(args.server, args.enroll)
|
||||
relay_url = args.relay or _default_relay_url(args.server)
|
||||
config = {
|
||||
@@ -830,11 +846,10 @@ async def main():
|
||||
}
|
||||
if not args.run_once:
|
||||
save_config(config)
|
||||
|
||||
elif not config:
|
||||
log.error(
|
||||
f"No config found at {CONFIG_FILE}.\n"
|
||||
"Run with --server <url> --enroll <token> to register this machine."
|
||||
"Run with --server <url> to register (or --server <url> --enroll <token> if enrollment tokens are required)."
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user