#!/usr/bin/env bash # check_devtesting.sh — fake-franken (CHF) via rusty.taler-ops.ch taler-devtesting # # Requires SSH to Host DEVTESTING_SSH (default: taler-rusty-devtesting → # rusty.taler-ops.ch user devtesting, forced command taler-devtesting). # # Probes: # 1) CLI reachable (fake-incoming --help) # 2) geniban → Swiss IBAN # 3) fake-incoming CHF amount to exchange credit IBAN (nexus IN) # Bounce "missing reserve public key" = plumbing OK (no real wallet reserve) # Full credit needs a real reserve pub as --subject (optional later) # # Env: # DEVTESTING_SSH default taler-rusty-devtesting (or user@host) # DEVTESTING_AMOUNT default CHF:1.00 # DEVTESTING_CREDIT_PAYTO exchange IBAN payto (auto from EXCHANGE_PUBLIC/keys if empty) # DEVTESTING_EXCHANGE_IBAN fallback CH6808573105529100001 (TOPS CHF exchange) # DEVTESTING_SKIP=1 skip phase # SKIP_SSH=1 skip (same as other SSH phases) # set -euo pipefail ROOT=$(cd "$(dirname "$0")" && pwd) # shellcheck source=lib.sh source "$ROOT/lib.sh" set_area devtesting section "devtesting · fake-franken CHF (rusty taler-devtesting)" # Do NOT honor SKIP_SSH here: stage/tops profiles set SKIP_SSH=1 for container # inside checks, but rusty.taler-ops.ch is a separate SSH hop (devtesting key). if [ "${DEVTESTING_SKIP:-0}" = "1" ]; then info "skip" "DEVTESTING_SKIP=1" exit 0 fi : "${DEVTESTING_SSH:=taler-rusty-devtesting}" : "${DEVTESTING_AMOUNT:=CHF:1.00}" : "${DEVTESTING_EXCHANGE_IBAN:=CH6808573105529100001}" : "${SSH_CONNECT_TIMEOUT:=8}" : "${SSH_CMD_TIMEOUT:=45}" ssh_dt() { # Prefer Host alias; fall back to explicit user@host if config missing local target="$DEVTESTING_SSH" if ! ssh -G "$target" >/dev/null 2>&1; then target="devtesting@rusty.taler-ops.ch" fi if command -v timeout >/dev/null 2>&1; then timeout "${SSH_CMD_TIMEOUT}" ssh \ -o BatchMode=yes \ -o ConnectTimeout="${SSH_CONNECT_TIMEOUT}" \ -o StrictHostKeyChecking=accept-new \ "$target" "$@" else ssh \ -o BatchMode=yes \ -o ConnectTimeout="${SSH_CONNECT_TIMEOUT}" \ -o StrictHostKeyChecking=accept-new \ "$target" "$@" fi } set_group cli info "ssh" "DEVTESTING_SSH=${DEVTESTING_SSH} amount=${DEVTESTING_AMOUNT}" help_out=$(ssh_dt fake-incoming --help 2>&1) || true if printf '%s' "$help_out" | grep -q 'fake-incoming'; then ok "cli" "taler-devtesting fake-incoming reachable via ${DEVTESTING_SSH}" else fail "cli" "cannot run taler-devtesting on ${DEVTESTING_SSH}" \ "$(printf '%s' "$help_out" | tr '\n' ' ' | head -c 200)" exit 1 fi set_group geniban iban_out=$(ssh_dt geniban 2>&1) || true iban=$(printf '%s\n' "$iban_out" | grep -E '^CH[0-9A-Z]+$' | tail -1 || true) if [ -n "$iban" ]; then ok "geniban" "synthetic IBAN $iban" else fail "geniban" "expected CH… IBAN" "$(printf '%s' "$iban_out" | tr '\n' ' ' | head -c 160)" exit 1 fi # Credit payto: rusty libeufin-nexus only accepts the *production* exchange IBAN # configured there (DEVTESTING_EXCHANGE_IBAN). Do not use stage /keys first-account. set_group credit-payto credit_payto="${DEVTESTING_CREDIT_PAYTO:-}" if [ -z "$credit_payto" ]; then credit_payto="payto://iban/${DEVTESTING_EXCHANGE_IBAN}?receiver-name=Taler+Operations+AG" fi ok "credit-payto" "$credit_payto" # Subject: not a real reserve — nexus should bounce missing reserve public key # (proves CHF fake-incoming path). Real reserve pub would credit wirewatch. subject="mon-fake-franken-$(date -u +%Y%m%d%H%M%S)-$$" debit_payto="payto://iban/${iban}?receiver-name=MonDevTest" set_group fake-incoming info "fake-incoming" "amount=${DEVTESTING_AMOUNT} subject=${subject}" fi_rc=0 fi_out=$(ssh_dt fake-incoming \ --amount "${DEVTESTING_AMOUNT}" \ --subject "${subject}" \ --credit-payto "${credit_payto}" \ --debit-payto "${debit_payto}" 2>&1) || fi_rc=$? # Normalize multi-line for matching fi_flat=$(printf '%s' "$fi_out" | tr '\n' ' ') if printf '%s' "$fi_flat" | grep -qiE 'Permission denied|Connection refused|Could not resolve|No such command'; then fail "fake-incoming" "SSH/CLI failure" "$(printf '%s' "$fi_flat" | head -c 200)" exit 1 fi if printf '%s' "$fi_flat" | grep -qiE 'Creditor must be the exchange'; then fail "fake-incoming" "wrong credit IBAN (not exchange)" "$(printf '%s' "$fi_flat" | head -c 220)" exit 1 fi if printf '%s' "$fi_flat" | grep -qiE 'Missing amount|unable to read secrets|CalledProcessError'; then # secrets warn alone is soft if we still see IN line if ! printf '%s' "$fi_flat" | grep -qE 'libeufin-nexus - IN .* CHF'; then fail "fake-incoming" "nexus rejected request" "$(printf '%s' "$fi_flat" | head -c 220)" exit 1 fi fi if printf '%s' "$fi_flat" | grep -qE 'libeufin-nexus - IN .* CHF:[0-9]'; then if printf '%s' "$fi_flat" | grep -qiE 'bounced.*missing reserve public key'; then ok "fake-incoming" "CHF IN accepted by nexus · bounced (no reserve pub) — fake-franken plumbing OK" info "note" "use real reserve pub as --subject for wirewatch credit (not required for mon probe)" elif printf '%s' "$fi_flat" | grep -qiE 'bounced'; then warn "fake-incoming" "CHF IN bounced (other reason)" "$(printf '%s' "$fi_flat" | grep -oiE 'bounced[^ ]* [^ ]*' | head -c 160)" else ok "fake-incoming" "CHF IN recorded by nexus (no bounce line)" fi elif [ "$fi_rc" -eq 0 ] && printf '%s' "$fi_flat" | grep -qi 'Faking incoming CHF'; then ok "fake-incoming" "CLI completed CHF fake-incoming" else fail "fake-incoming" "no CHF IN line from nexus" "rc=${fi_rc} $(printf '%s' "$fi_flat" | head -c 200)" exit 1 fi info "done" "devtesting fake-franken probe finished" exit 0