release 1.13.0: devtesting fake-franken CHF via rusty
New phase devtesting (aliases franken/fake-franken) probes taler-devtesting on rusty.taler-ops.ch: geniban + fake-incoming CHF to the exchange IBAN. Nexus bounce without reserve pub is OK for the plumbing probe. Stage host-agent can include the phase.
This commit is contained in:
parent
e67ede881c
commit
2931006e3c
9 changed files with 227 additions and 2 deletions
14
README.md
14
README.md
|
|
@ -421,6 +421,20 @@ Soft mode only with `MONPAGES_REQUIRE_PUBLIC=0` (escape hatch).
|
|||
If pages are missing publicly: `sudo /home/hernani/koopa-caddy/apply-monitoring-live.sh` on koopa
|
||||
(FP: Infomaniak vhost for `/monitoring*`).
|
||||
|
||||
## Devtesting · fake-franken CHF (v1.13+)
|
||||
|
||||
Phase **`devtesting`** (aliases: `franken`, `fake-franken`) exercises the
|
||||
Taler Operations **rusty** host (`taler-devtesting` forced command):
|
||||
|
||||
```bash
|
||||
./taler-monitoring.sh -d stage.taler-ops.ch --currency CHF devtesting
|
||||
```
|
||||
|
||||
Needs SSH to `devtesting@rusty.taler-ops.ch` (Host `taler-rusty-devtesting`).
|
||||
Probes: CLI help, `geniban` (CH IBAN), `fake-incoming` CHF to exchange credit
|
||||
IBAN. A nexus bounce *missing reserve public key* is **OK** for the plumbing
|
||||
probe (no real wallet reserve required).
|
||||
|
||||
## Version on monitoring pages (v1.3+ / sticky bar)
|
||||
|
||||
The sticky bar shows the suite **tag** (e.g. `v1.11.0`) and links to that tag on Forgejo.
|
||||
|
|
|
|||
10
TESTS.md
10
TESTS.md
|
|
@ -193,3 +193,13 @@ totals: 40 OK, 1 ERROR, 2 WARN, 5 INFO
|
|||
|
||||
`NO_COLOR=1` or `CLICOLOR=0` disables boxes/colours (ASCII `[ OK ]` + `-- group --` headers).
|
||||
Always use `printf --` friendly plain headers when colour is off (leading `---` is not a printf option).
|
||||
|
||||
|
||||
## devtesting · fake-franken (v1.13+)
|
||||
|
||||
| ID prefix | What |
|
||||
|-----------|------|
|
||||
| **devtesting.cli-** | SSH to rusty · `taler-devtesting` CLI |
|
||||
| **devtesting.geniban-** | synthetic CH IBAN |
|
||||
| **devtesting.credit-payto-** | exchange credit IBAN for nexus |
|
||||
| **devtesting.fake-incoming-** | CHF IN via nexus; bounce missing reserve pub = plumbing OK |
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
1.12.0
|
||||
1.13.0
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.8.0`). File `VERSION` omits the `v` pre
|
|||
|
||||
| Tag | Date (UTC) | Notes |
|
||||
|-----|------------|--------|
|
||||
| **v1.13.0** | 2026-07-19 | **Feature:** phase **devtesting** / **franken** — fake-franken CHF via `rusty.taler-ops.ch` (`taler-devtesting` geniban + fake-incoming); stage host-agent can include it. |
|
||||
| **v1.12.0** | 2026-07-19 | **Feature:** collapsible **monitoring env context** (agent header: env_file, suite pin, domain/hosts/flags) — `<details>` default closed; summary shows agent · domain · suite. |
|
||||
| **v1.11.0** | 2026-07-19 | **Feature:** sticky **error/warn filter** — click counts to show only error or only warn log lines; sticky bar + overviews stay; `#filter-error` / `#filter-warn` (+ `#first-*` still works). |
|
||||
| **v1.10.11** | 2026-07-19 | **Bugfix:** surface/aptdeploy wrappers **force** MON_HOSTS+PHASES+MONPAGES_INVENTORY (env cannot expand job to bank/exchange); wrap more mon knobs. |
|
||||
|
|
|
|||
147
check_devtesting.sh
Executable file
147
check_devtesting.sh
Executable file
|
|
@ -0,0 +1,147 @@
|
|||
#!/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
|
||||
35
host-agent/env/mytops-stage.env.example
vendored
Normal file
35
host-agent/env/mytops-stage.env.example
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# Copy to: ~/.config/taler-monitoring/env (user taler-monitoring @ betel)
|
||||
# mytops CHF stage — NOT lifeline / production
|
||||
#
|
||||
SUITE_GIT_URL=https://git.hacktivism.ch/hernani/taler-monitoring.git
|
||||
SUITE_GIT_REF=main
|
||||
SUITE_DIR=$HOME/src/taler-monitoring
|
||||
TALER_DOMAIN=stage.taler-ops.ch
|
||||
MON_HOSTS="stage.my.taler-ops.ch stage.taler-ops.ch"
|
||||
HTML_OUT=$HOME/monitoring-sites-staging
|
||||
DEPLOY_WWW_ROOT=/var/www/monitoring-sites
|
||||
HTML_URL_OK=/monitoring/
|
||||
HTML_URL_ERR=/monitoring_err/
|
||||
HTML_OK_DIR=monitoring
|
||||
HTML_ERR_DIR=monitoring_err
|
||||
# urls + monpages + fake-franken CHF (rusty.taler-ops.ch)
|
||||
PHASES="urls monpages devtesting"
|
||||
SKIP_SSH=1
|
||||
LOCAL_STACK=0
|
||||
INSIDE_PODMAN=0
|
||||
CONTINUE_ON_ERROR=1
|
||||
RUN_TIMEOUT=600
|
||||
STRICT_EXIT=1
|
||||
MONPAGES_REQUIRE_PUBLIC=1
|
||||
MONPAGES_INVENTORY=job
|
||||
TALER_MON_LANG=en
|
||||
AGENT_LABEL=mytops-stage-host-agent
|
||||
STATE_NAME=taler-monitoring-mytops-stage
|
||||
SUITE_UPDATE_STRICT=1
|
||||
CHECK_BANK=0
|
||||
MERCHANT_REQUIRED=1
|
||||
CHECK_LANDING=0
|
||||
# rusty devtesting (SSH Host taler-rusty-devtesting → devtesting@rusty.taler-ops.ch)
|
||||
DEVTESTING_SSH=taler-rusty-devtesting
|
||||
DEVTESTING_AMOUNT=CHF:1.00
|
||||
# DEVTESTING_SKIP=1
|
||||
|
|
@ -69,6 +69,15 @@
|
|||
# AUTH401_ADMIN_USER=admin
|
||||
# FRANCPAYSAN_SECRETS=$HOME/francpaysan-secrets
|
||||
|
||||
# --- Devtesting / fake-franken CHF (rusty.taler-ops.ch) ---
|
||||
# Phase: devtesting | franken | fake-franken
|
||||
# SSH Host taler-rusty-devtesting (user devtesting, forced taler-devtesting CLI).
|
||||
# DEVTESTING_SSH=taler-rusty-devtesting
|
||||
# DEVTESTING_AMOUNT=CHF:1.00
|
||||
# DEVTESTING_CREDIT_PAYTO= # optional; auto from EXCHANGE_PUBLIC/keys or TOPS IBAN
|
||||
# DEVTESTING_EXCHANGE_IBAN=CH6808573105529100001
|
||||
# DEVTESTING_SKIP=1 # skip phase
|
||||
|
||||
# --- Ladder (GOA withdraw ladder · explorer pool) ---
|
||||
# Prefer SECRETS_ROOT / KOOPA_ADMIN_SECRETS (bank-explorer-password.txt).
|
||||
# Overrides only if needed:
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ def ui(lang: str, key: str, **kwargs) -> str:
|
|||
"stage_i3": "Phases: {phases} · suite auto-upgrade each timer run",
|
||||
"stage_i4": "Not GOA: no surface/aptdeploy/mail pages · no koopa-admin-log",
|
||||
"stage_i5": "Timer: taler-monitoring-mytops-stage.timer (4h) · user taler-monitoring",
|
||||
"stage_i6": "devtesting: fake-franken CHF via rusty.taler-ops.ch (geniban + fake-incoming)",
|
||||
"pages_section_lead": "Monitoring pages themselves (suite):",
|
||||
"mm_title": "Mattermost chat health",
|
||||
"mm_summary": "mattermost.taler.net · SPA + /api/v4/system/ping · TLS",
|
||||
|
|
@ -182,6 +183,7 @@ def ui(lang: str, key: str, **kwargs) -> str:
|
|||
"stage_i3": "Phases : {phases} · auto-upgrade suite à chaque minuterie",
|
||||
"stage_i4": "Pas GOA : pas de pages surface/aptdeploy/mail · pas de koopa-admin-log",
|
||||
"stage_i5": "Minuterie : taler-monitoring-mytops-stage.timer (4 h) · user taler-monitoring",
|
||||
"stage_i6": "devtesting : fake-franken CHF via rusty.taler-ops.ch (geniban + fake-incoming)",
|
||||
"pages_i6": "Hôte de cette page : {host} · libellé : {label}",
|
||||
"pages_section_lead": "Les pages de monitoring elles-mêmes (suite) :",
|
||||
"mm_title": "Santé du chat Mattermost",
|
||||
|
|
@ -612,6 +614,7 @@ def monitoring_scope(
|
|||
ui(lang, "stage_i3", phases=phase_txt),
|
||||
ui(lang, "stage_i4"),
|
||||
ui(lang, "stage_i5"),
|
||||
ui(lang, "stage_i6"),
|
||||
ui(lang, "pages_i6", host=host, label=label),
|
||||
]
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -104,6 +104,9 @@ Phases:
|
|||
mail MX/SMTP/IMAP for Taler mail (firefly, pixel/TSA, catalogued domains)
|
||||
monpages public monitoring HTML via FQDN (obligatory ERROR; GOA full inventory, FP only FP)
|
||||
uses MON_HOSTS + HTML_URL_OK (same as host-agent); v1.3.1+
|
||||
devtesting fake-franken CHF via rusty.taler-ops.ch (taler-devtesting)
|
||||
geniban + fake-incoming; needs SSH Host DEVTESTING_SSH (key to devtesting@rusty)
|
||||
franken|fake-franken aliases for devtesting
|
||||
all urls + inside + versions + sanity + e2e (SSH phases only on koopa)
|
||||
full all + server + ladder + auth401 (maximum; long-running, needs secrets)
|
||||
NOTE: surface is never included in all/full — pass it explicitly
|
||||
|
|
@ -245,7 +248,7 @@ while [ $# -gt 0 ]; do
|
|||
CURRENCY_OVERRIDE="$2"; shift 2
|
||||
;;
|
||||
--no-probe) NO_PROBE=1; shift ;;
|
||||
urls|inside|versions|sanity|server|e2e|ladder|goa-ladder|auth401|aptdeploy|apt-deploy|apt_src|surface|ecosystem|mattermost|mail|monpages|pages|all|full) PHASES+=("$1"); shift ;;
|
||||
urls|inside|versions|sanity|server|e2e|ladder|goa-ladder|auth401|aptdeploy|apt-deploy|apt_src|surface|ecosystem|mattermost|mail|monpages|pages|devtesting|franken|fake-franken|fake_franken|all|full) PHASES+=("$1"); shift ;;
|
||||
*)
|
||||
# bare domain shorthand: ./taler-monitoring.sh taler.net
|
||||
if [[ "$1" == *.* && "$1" != *://* && "$1" != -* ]]; then
|
||||
|
|
@ -532,6 +535,9 @@ for p in "${PHASES[@]}"; do
|
|||
mattermost) run_phase mattermost "$ROOT/check_mattermost.sh" || ec=1 ;;
|
||||
mail) run_phase mail "$ROOT/check_mail.sh" || ec=1 ;;
|
||||
monpages|pages) run_phase monpages "$ROOT/check_monitoring_pages.sh" || ec=1 ;;
|
||||
devtesting|franken|fake-franken|fake_franken)
|
||||
run_phase devtesting "$ROOT/check_devtesting.sh" || ec=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue