fix: Cloudron selectors, docker-compose env_file, CLOUDRON_BASE URL
- Fix Cloudron invite form selectors to match real page IDs
(#inputUsername, #inputDisplayName, #inputPassword, #inputPasswordRepeat)
- Fix docker-compose.yml: use env_file instead of ${VAR} interpolation
(password contains $ chars that docker-compose corrupts)
- Update CLOUDRON_BASE from tsys-cloudron.knel.net to my.knownelement.com
Phase 1 Cloudron enrollment now works end-to-end: invite accepted,
password set, TOTP extracted, credential stored in Bitwarden.
Phase 2 (Gitea/Redmine/Discourse) needs selector updates for
the current UI versions of each system.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
+2
-7
@@ -2,13 +2,8 @@ services:
|
|||||||
provision:
|
provision:
|
||||||
build: .
|
build: .
|
||||||
container_name: tsys-agent-provisioner
|
container_name: tsys-agent-provisioner
|
||||||
environment:
|
env_file:
|
||||||
- BW_CLIENTID=${BW_CLIENTID}
|
- ${BW_ENV_FILE:-${HOME}/.config/bw/env}
|
||||||
- BW_CLIENTSECRET=${BW_CLIENTSECRET}
|
|
||||||
- BW_PASSWORD=${BW_PASSWORD}
|
|
||||||
- BW_SERVER=${BW_SERVER:-https://pwvault.turnsys.com}
|
|
||||||
- BW_TOTP_SECRET=${BW_TOTP_SECRET:-}
|
|
||||||
- HEADFUL=${HEADFUL:-false}
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./agents.yaml:/app/agents.yaml:ro
|
- ./agents.yaml:/app/agents.yaml:ro
|
||||||
- ./state:/app/state
|
- ./state:/app/state
|
||||||
|
|||||||
+13
-17
@@ -44,7 +44,7 @@ log = logging.getLogger("provision")
|
|||||||
# Constants
|
# Constants
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
CLOUDRON_BASE = os.environ.get("CLOUDRON_BASE", "https://tsys-cloudron.knel.net")
|
CLOUDRON_BASE = os.environ.get("CLOUDRON_BASE", "https://my.knownelement.com")
|
||||||
GITEA_URL = os.environ.get("GITEA_URL", "https://git.knownelement.com")
|
GITEA_URL = os.environ.get("GITEA_URL", "https://git.knownelement.com")
|
||||||
DISCOURSE_URL = os.environ.get("DISCOURSE_URL", "https://community.turnsys.com")
|
DISCOURSE_URL = os.environ.get("DISCOURSE_URL", "https://community.turnsys.com")
|
||||||
REDMINE_URL = os.environ.get("REDMINE_URL", "https://projects.knownelement.com")
|
REDMINE_URL = os.environ.get("REDMINE_URL", "https://projects.knownelement.com")
|
||||||
@@ -88,29 +88,25 @@ def enroll_cloudron(
|
|||||||
|
|
||||||
# Navigate to invite link
|
# Navigate to invite link
|
||||||
page.goto(invite_url, wait_until="networkidle")
|
page.goto(invite_url, wait_until="networkidle")
|
||||||
|
page.wait_for_timeout(2000)
|
||||||
|
|
||||||
# Fill in the invite acceptance form
|
# Fill in the invite acceptance form using real Cloudron selectors
|
||||||
# Cloudron invite page typically has: username (may be pre-filled), password, confirm password
|
page.wait_for_selector('#inputPassword', timeout=15000)
|
||||||
page.wait_for_selector('input[type="password"]', timeout=15000)
|
|
||||||
|
|
||||||
password_inputs = page.query_selector_all('input[type="password"]')
|
page.fill('#inputPassword', password)
|
||||||
if len(password_inputs) >= 2:
|
page.fill('#inputPasswordRepeat', password)
|
||||||
password_inputs[0].fill(password)
|
|
||||||
password_inputs[1].fill(password)
|
|
||||||
elif len(password_inputs) == 1:
|
|
||||||
password_inputs[0].fill(password)
|
|
||||||
else:
|
|
||||||
raise RuntimeError(f"[{name}] No password field found on Cloudron invite page")
|
|
||||||
|
|
||||||
# Set display name if field exists
|
# Set display name if field exists
|
||||||
name_field = page.query_selector('input[name="displayName"], input[name="name"]')
|
display_field = page.query_selector('#inputDisplayName')
|
||||||
if name_field:
|
if display_field:
|
||||||
name_field.fill(display_name)
|
display_field.fill(display_name)
|
||||||
|
|
||||||
# Submit
|
# Submit — Cloudron uses a button with class btn-primary or type submit
|
||||||
submit = page.query_selector('button[type="submit"], button:has-text("Setup"), button:has-text("Create"), button:has-text("Accept")')
|
submit = page.query_selector('button[type="submit"], button.btn-primary, button:has-text("Setup"), button:has-text("Create"), button:has-text("Accept")')
|
||||||
if submit:
|
if submit:
|
||||||
submit.click()
|
submit.click()
|
||||||
|
else:
|
||||||
|
page.keyboard.press('Enter')
|
||||||
|
|
||||||
page.wait_for_load_state("networkidle")
|
page.wait_for_load_state("networkidle")
|
||||||
log.info(f"[{name}] Invite accepted")
|
log.info(f"[{name}] Invite accepted")
|
||||||
|
|||||||
Reference in New Issue
Block a user