summaryrefslogtreecommitdiff
path: root/bin/WIP
diff options
context:
space:
mode:
authorms <ms@taler.net>2021-09-24 17:59:13 +0200
committerms <ms@taler.net>2021-09-24 17:59:13 +0200
commitb2dec5aa6b7ef665d31f7f79c5cdfa78e8368b42 (patch)
tree48cd9ecbed6299909c62284feb6dbc392bdff814 /bin/WIP
parent70d2127910b525e68b8150d10d0dfce367daf437 (diff)
downloaddeployment-b2dec5aa6b7ef665d31f7f79c5cdfa78e8368b42.tar.gz
deployment-b2dec5aa6b7ef665d31f7f79c5cdfa78e8368b42.tar.bz2
deployment-b2dec5aa6b7ef665d31f7f79c5cdfa78e8368b42.zip
move all the deployment to one script: taler-local
includes compilation, configuration, preparation. Will have the starting up / shutting down of all the services too.
Diffstat (limited to 'bin/WIP')
-rwxr-xr-xbin/WIP/taler-local741
1 files changed, 740 insertions, 1 deletions
diff --git a/bin/WIP/taler-local b/bin/WIP/taler-local
index 82107d4..7e6b5fd 100755
--- a/bin/WIP/taler-local
+++ b/bin/WIP/taler-local
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with GNU Taler. If not, see <https://www.gnu.org/licenses/>.
+import atexit
import click
import types
import os
@@ -29,8 +30,15 @@ from pathlib import Path
from dataclasses import dataclass
from typing import List, Callable
from shutil import copy
-from taler_urls import get_urls
from string import ascii_letters, ascii_uppercase
+from sys import exit
+from os import remove
+from requests import get, auth
+from collections import OrderedDict
+import errno
+from pathlib import Path
+from subprocess import check_call as Popen, DEVNULL
+from datetime import datetime
@dataclass
class Repo:
@@ -381,5 +389,736 @@ def bootstrap(repos) -> None:
reposList = split_repos_list(repos)
checkout_repos(load_repos(reposList))
+@cli.command()
+def prepare():
+ # Print No Newline.
+ def print_nn(msg):
+ print(msg, env="")
+
+ # Runs a command synchronously.
+ # FIXME: avoid overriding the log file.
+ def cmd(name, args, env=os.environ):
+ handle = launch(name, args, env)
+ return_code = handle.wait()
+ if return_code != 0:
+ print("Command: " + " ".join(args) + " failed, return code: " + str(return_code))
+ print(f"See logs in /tmp/{name}.log")
+ return False
+ return handle
+
+ def kill(name, s):
+ s.terminate()
+ s.wait()
+
+ # Runs a command in the background.
+ def launch(name, cmd, env=os.environ):
+ log_file = open("/tmp/{name}.log", "w")
+ handle = Popen(
+ cmd,
+ stdin=DEVNULL,
+ stdout=log_file,
+ stderr=log_file,
+ env=env
+ )
+ atexit.register(lambda: kill(name, handle))
+ return handle
+
+ def check_running(name, check_url):
+ print_nn(f"Checking {name} is running...")
+ for i in range(10):
+ print_nn(".")
+ try:
+ # Raises if the service is not reachable.
+ response = get(check_url)
+ # Raises if the request gets a non 200 OK.
+ response.raise_for_status()
+ except:
+ if i == 10:
+ print("ERROR: {name} is not running (correctly)")
+ return False
+ print(" OK")
+ return True
+
+ def get_nexus_cli_env(
+ username, password,
+ nexus_url
+ ):
+ env = os.environ.copy()
+ env["LIBEUFIN_NEXUS_USERNAME"] = username
+ env["LIBEUFIN_NEXUS_PASSWORD"] = password,
+ env["LIBEUFIN_NEXUS_URL"] = nexus_url
+ return env
+
+ def get_sandbox_cli_env(
+ username, password
+ ):
+ env = os.environ.copy()
+ env["LIBEUFIN_SANDBOX_USERNAME"] = username
+ env["LIBEUFIN_SANDBOX_PASSWORD"] = password
+ return env
+
+ def prepare_nexus_account(
+ ebics_url,
+ ebics_host_id,
+ ebics_partner_id,
+ ebics_user_id,
+ bank_connection_name,
+ bank_account_name_sandbox,
+ bank_account_name_nexus,
+ env
+ ):
+ # make connection
+ cmd(
+ "new-ebics-connection",
+ [
+ "libeufin-cli", "connections",
+ "new-ebics-connection",
+ "--ebics-url", ebics_url,
+ "--host-id", ebics_host_id,
+ "--partner-id", ebics_partner_id,
+ "--ebics-user-id", ebics_user_id,
+ bank_connection_name
+ ],
+ env
+ )
+ # connect
+ cmd(
+ "bankconnection-connect",
+ [
+ "libeufin-cli", "connections",
+ "connect", bank_connection_name
+ ],
+ env
+ )
+ # Import bank account
+ cmd(
+ "download-bank-accounts",
+ [
+ "libeufin-cli", "connections",
+ "download-bank-accounts",
+ bank_connection_name
+ ],
+ env
+ )
+ cmd(
+ "import-bank-account",
+ [
+ "libeufin-cli", "connections",
+ "import-bank-account",
+ "--offered-account",
+ bank_account_name_sandbox,
+ "--nexus-bank-account",
+ bank_account_name_nexus,
+ bank_connection_name
+ ],
+ env
+ )
+ # Set background tasks.
+ cmd(
+ "task-schedule-submit-payments",
+ [
+ "libeufin-cli", "accounts",
+ "task-schedule", bank_account_name_nexus,
+ "--task-type", "submit",
+ "--task-name", "submit-payments-each-second",
+ "--task-cronspec", "* * *"
+ ],
+ env
+ )
+ cmd(
+ "task-schedule-fetch-reports",
+ [
+ "libeufin-cli", "accounts",
+ "task-schedule", bank_account_name_nexus,
+ "--task-type", "fetch",
+ "--task-name", "fetch-reports-each-second",
+ "--task-cronspec", "* * *",
+ "--task-param-level", "report",
+ "--task-param-range-type", "latest"
+ ],
+ env
+ )
+
+ def prepare_sandbox_account(
+ currency,
+ sandbox_url,
+ ebics_host_id,
+ ebics_partner_id,
+ ebics_user_id,
+ person_name,
+ bank_account_name,
+ bank_account_iban,
+ env
+ ):
+ cmd(
+ "ebicssubscriber-create",
+ [
+ "libeufin-cli", "sandbox",
+ "--sandbox-url", sandbox_url,
+ "ebicssubscriber", "create",
+ "--host-id", ebics_host_id,
+ "--partner-id", ebics_partner_id,
+ "--user-id", ebics_user_id
+ ],
+ env
+ )
+ cmd(
+ "ebicsbankaccount-create",
+ [
+ "libeufin-cli", "sandbox",
+ "--sandbox-url", sandbox_url,
+ "ebicsbankaccount", "create",
+ "--iban", bank_account_iban,
+ "--bic", "ABCDEFGH",
+ "--person-name", person_name,
+ "--account-name", bank_account_name,
+ "--ebics-user-id", ebics_user_id,
+ "--ebics-host-id", ebics_host_id,
+ "--ebics-partner-id", ebics_partner_id,
+ "--currency", currency
+ ],
+ env
+ )
+
+ class ConfigFile:
+ def __init__(self, filename):
+ self.sections = OrderedDict()
+ self.filename = filename
+
+ def destroy(self):
+ del self.sections
+ self.sections = OrderedDict()
+
+ def cfg_put(self, section_name, key, value):
+ s = self.sections[section_name] = self.sections.get(section_name, OrderedDict())
+ s[key] = value
+
+ def cfg_write(self, outdir):
+
+ if outdir:
+ fstream = open(os.path.join(outdir, self.filename), "w")
+ else:
+ fstream = open(sys.stdout)
+
+ for section_name, section in self.sections.items():
+ fstream.write("[" + section_name + "]" + "\n")
+ for key, value in section.items():
+ fstream.write(key + " = " + value + "\n")
+ fstream.write("\n")
+ fstream.close()
+
+ def config_main(
+ filename,
+ outdir,
+ currency,
+ rev_proxy_url,
+ wire_method,
+ exchange_wire_address,
+ merchant_wire_address,
+ exchange_wire_gateway_username,
+ exchange_wire_gateway_password,
+ frontend_api_key,
+ ):
+ def coin(
+ obj,
+ currency,
+ name,
+ value,
+ d_withdraw="3 years",
+ d_spend="5 years",
+ d_legal="10 years",
+ f_withdraw="0.01",
+ f_deposit="0.01",
+ f_refresh="0.01",
+ f_refund="0.01",
+ rsa_keysize="2048",
+ ):
+ sec = "coin_" + currency + "_" + name
+ obj.cfg_put(sec, "value", currency + ":" + value)
+ obj.cfg_put(sec, "duration_withdraw", d_withdraw)
+ obj.cfg_put(sec, "duration_spend", d_spend)
+ obj.cfg_put(sec, "duration_legal", d_legal)
+ obj.cfg_put(sec, "fee_withdraw", currency + ":" + f_withdraw)
+ obj.cfg_put(sec, "fee_refresh", currency + ":" + f_refresh)
+ obj.cfg_put(sec, "fee_refund", currency + ":" + f_refund)
+ obj.cfg_put(sec, "fee_deposit", currency + ":" + f_deposit)
+ obj.cfg_put(sec, "rsa_keysize", rsa_keysize)
+
+
+ obj = ConfigFile("taler.conf")
+ obj.cfg_put("paths", "TALER_DATA_HOME", "${HOME}/.taler-data")
+ obj.cfg_put("paths", "TALER_RUNTIME_DIR", "${HOME}/.taler-runtime")
+ obj.cfg_put("taler", "CURRENCY", currency)
+ obj.cfg_put("taler", "CURRENCY_ROUND_UNIT", f"{currency}:0.01")
+
+ obj.cfg_put("bank", "serve", "uwsgi")
+ obj.cfg_put("bank", "uwsgi_serve", "unix")
+ obj.cfg_put("bank", "uwsgi_unixpath", "/tmp/bank.sock")
+ obj.cfg_put("bank", "uwsgi_unixpath_mode", "660")
+ obj.cfg_put("bank", "database", "taler")
+ obj.cfg_put("bank", "max_debt", "%s:500.0" % currency)
+ obj.cfg_put("bank", "max_debt_bank", "%s:1000000000.0" % currency)
+ obj.cfg_put("bank", "allow_registrations", "YES")
+ obj.cfg_put("bank", "base_url", rev_proxy_url + "/bank/")
+ obj.cfg_put("bank", "database", "postgres:///taler")
+ obj.cfg_put("bank", "suggested_exchange", rev_proxy_url + "/exchange/")
+
+ obj.cfg_put("donations", "serve", "uwsgi")
+ obj.cfg_put("donations", "uwsgi_serve", "unix")
+ obj.cfg_put("donations", "uwsgi_unixpath", "/tmp/donations.sock")
+ obj.cfg_put("donations", "uwsgi_unixpath_mode", "660")
+
+ obj.cfg_put("landing", "serve", "uwsgi")
+ obj.cfg_put("landing", "uwsgi_serve", "unix")
+ obj.cfg_put("landing", "uwsgi_unixpath", "/tmp/landing.sock")
+ obj.cfg_put("landing", "uwsgi_unixpath_mode", "660")
+
+ obj.cfg_put("blog", "serve", "uwsgi")
+ obj.cfg_put("blog", "uwsgi_serve", "unix")
+ obj.cfg_put("blog", "uwsgi_unixpath", "/tmp/blog.sock")
+ obj.cfg_put("blog", "uwsgi_unixpath_mode", "660")
+
+ obj.cfg_put("survey", "serve", "uwsgi")
+ obj.cfg_put("survey", "uwsgi_serve", "unix")
+ obj.cfg_put("survey", "uwsgi_unixpath", "/tmp/survey.sock")
+ obj.cfg_put("survey", "uwsgi_unixpath_mode", "660")
+ obj.cfg_put("survey", "bank_password", "x")
+
+ obj.cfg_put("merchant", "serve", "unix")
+ obj.cfg_put("merchant", "unixpath", "/tmp/merchant-backend.sock")
+ obj.cfg_put("merchant", "wire_transfer_delay", "0 s")
+ obj.cfg_put("merchant", "default_max_wire_fee", currency + ":" + "0.01")
+ obj.cfg_put("merchant", "default_max_deposit_fee", currency + ":" + "0.05")
+ obj.cfg_put("merchantdb-postgres", "config", "postgres:///taler")
+
+ obj.cfg_put("frontends", "backend", rev_proxy_url + "/merchant-backend/")
+ obj.cfg_put(
+ "merchant-exchange-{}".format(currency),
+ "exchange_base_url", rev_proxy_url + "/exchange/",
+ )
+
+ obj.cfg_put("auditor", "serve", "unix")
+ # FIXME: both below used?
+ obj.cfg_put("auditor", "base_url", rev_proxy_url + "/auditor")
+ obj.cfg_put("auditor", "auditor_url", rev_proxy_url + "/auditor")
+ obj.cfg_put("auditor", "unixpath", "/tmp/auditor.sock")
+ obj.cfg_put("auditor", "tiny_amount", currency + ":0.01")
+
+ obj.cfg_put("taler-exchange-secmod-eddsa", "unixpath", "/tmp/exchange-secmod-eddsa.sock")
+ obj.cfg_put("taler-exchange-secmod-rsa", "unixpath", "/tmp/exchange-secmod-rsa.sock")
+ obj.cfg_put("taler-exchange-secmod-rsa", "sm_priv_key",
+ "/tmp/taler-data/taler-exchange-secmod-rsa/secmod-private-key"
+ )
+ obj.cfg_put("exchange", "base_url", rev_proxy_url + "/exchange/")
+
+ obj.cfg_put("exchange", "serve", "unix")
+ obj.cfg_put("exchange", "unixpath", "/tmp/exchange.sock")
+
+ obj.cfg_put("exchange", "terms_etag", "0")
+ obj.cfg_put("exchange", "terms_dir", "$HOME/local/share/taler-exchange/tos")
+ obj.cfg_put("exchange", "privacy_etag", "0")
+ obj.cfg_put("exchange", "privacy_dir", "$HOME/local/share/taler-exchange/pp")
+
+
+ obj.cfg_put("exchangedb-postgres", "db_conn_str", "postgres:///taler")
+ obj.cfg_put("exchangedb-postgres", "config", "postgres:///taler")
+ obj.cfg_put("auditordb-postgres", "db_conn_str", "postgres:///taler")
+ obj.cfg_put("auditordb-postgres", "config", "postgres:///taler")
+
+ obj.cfg_put(
+ "exchange-account-1",
+ "payto_uri",
+ f"payto://{wire_method}/{rev_proxy_url + '/bank'}/{exchange_wire_address}"
+ )
+ obj.cfg_put("exchange-account-1", "enable_debit", "yes")
+ obj.cfg_put("exchange-account-1", "enable_credit", "yes")
+ obj.cfg_put("merchant-account-merchant", "payto_uri",
+ f"payto://{wire_method}/{rev_proxy_url + '/bank'}/{merchant_wire_address}"
+ )
+ obj.cfg_put("merchant-account-merchant",
+ "wire_response",
+ "${TALER_DATA_HOME}/merchant/wire/merchant.json",
+ )
+ obj.cfg_put("merchant-account-merchant", "wire_file_mode", "770")
+
+ obj.cfg_put("frontends", "backend_apikey", f"{frontend_api_key}")
+ coin(obj, currency, "ct_10", "0.10")
+ coin(obj, currency, "1", "1")
+ coin(obj, currency, "2", "2")
+ coin(obj, currency, "5", "5")
+ coin(obj, currency, "10", "10")
+ coin(obj, currency, "1000", "1000")
+ obj.cfg_write(outdir)
+ return obj
+
+ def config_sync(filename, outdir, currency, api_key, rev_proxy_url):
+ obj = ConfigFile(filename)
+ obj.cfg_put("taler", "currency", currency)
+ obj.cfg_put("sync", "serve", "unix")
+ obj.cfg_put("sync", "unixpath", "$HOME/sockets/sync.http")
+ obj.cfg_put("sync", "apikey", f"Bearer {api_key}")
+ obj.cfg_put("sync", "annual_fee", f"{currency}:0.1")
+ obj.cfg_put("sync", "fulfillment_url", "taler://fulfillment-success/")
+ obj.cfg_put("sync", "payment_backend_url", rev_proxy_url + "merchant-backend/instances/Taler/")
+ obj.cfg_put("syncdb-postgres", "config", f"postgres:///taler")
+ obj.cfg_write(outdir)
+
+ def config_anastasis(filename, outdir, currency, rev_proxy_url, api_key):
+ obj = ConfigFile(filename)
+ obj.cfg_put("taler", "currency", currency)
+ obj.cfg_put("anastasis", "serve", "unix")
+ obj.cfg_put("anastasis", "business_name", f"GNU Taler Demo Anastasis Provider")
+ obj.cfg_put("anastasis", "unixpath", "/tmp/anastasis.sock")
+ obj.cfg_put("anastasis", "annual_fee", f"{currency}:0")
+ obj.cfg_put("anastasis", "question_cost", f"{currency}:0")
+ obj.cfg_put("anastasis", "insurance", f"{currency}:0")
+ obj.cfg_put("anastasis", "truth_upload_fee", f"{currency}:0")
+ obj.cfg_put("anastasis", "fulfillment_url", "taler://fulfillment-success/")
+ obj.cfg_put("anastasis", "server_salt", "kreb3ia9dmj43gfa")
+ obj.cfg_put("stasis-postgres", "config", f"postgres:///taler")
+ obj.cfg_put("anastasis-merchant-backend",
+ "payment_backend_url",
+ rev_proxy_url + "merchant-backend/instances/anastasis/"
+ )
+ obj.cfg_put("anastasis-merchant-backend", "api_key", f"Bearer {api_key}")
+ obj.cfg_put("authorization-question", "cost", f"{currency}:0")
+ obj.cfg_put("authorization-question", "enabled", "yes")
+ obj.cfg_write(outdir)
+
+ CURRENCY = "EUR"
+ WIRE_METHOD = "sepa"
+ CFG_OUTDIR = Path.home() / ".config"
+
+ # IBANs
+ IBAN_EXCHANGE = "EX00000000000000000000"
+ IBAN_MERCHANT = "ME00000000000000000001"
+ IBAN_CUSTOMER = "WA00000000000000000000"
+
+ # Credentials / API keys
+ SANDBOX_ADMIN_USERNAME = "admin"
+ SANDBOX_ADMIN_PASSWORD = "secret"
+ EXCHANGE_NEXUS_USERNAME = "exchange-nexus-user"
+ EXCHANGE_NEXUS_PASSWORD = "exchange-nexus-password"
+ FRONTENDS_API_KEY = "secret:secret"
+ TALER_MERCHANT_TOKEN = "secret" # same as above?
+
+ # URLs
+ REV_PROXY = "http://localhost:8080"
+ SANDBOX_URL = REV_PROXY + "/sandbox"
+ NEXUS_URL = REV_PROXY + "/nexus"
+
+ # EBICS
+ EBICS_HOST_ID = "ebicsDeployedHost"
+ EXCHANGE_EBICS_USER_ID = "exchangeEbicsUserId"
+ EXCHANGE_EBICS_PARTNER_ID = "exchangeEbicsPartnerId"
+ EBICS_URL = REV_PROXY + "/sandbox/ebicsweb"
+
+ # euFin
+ NEXUS_DB_FILE = "/tmp/nexus.sqlite"
+ SANDBOX_DB_FILE = "/tmp/sandbox.sqlite"
+ EXCHANGE_BANK_ACCOUNT_NEXUS = "exchange-imported-account-nexus"
+ EXCHANGE_BANK_ACCOUNT_SANDBOX = "exchange-account-sandbox"
+ EXCHANGE_BANK_CONNECTION = "exchange-ebics-connection"
+ EXCHANGE_FACADE_NAME = "exchange-taler-facade"
+
+ mc = config_main(
+ "taler.conf",
+ outdir=CFG_OUTDIR,
+ currency=CURRENCY,
+ rev_proxy_url=REV_PROXY,
+ wire_method=WIRE_METHOD,
+ exchange_wire_address=IBAN_EXCHANGE,
+ merchant_wire_address=IBAN_MERCHANT,
+ exchange_wire_gateway_username=EXCHANGE_NEXUS_USERNAME,
+ exchange_wire_gateway_password=EXCHANGE_NEXUS_PASSWORD,
+ frontend_api_key=FRONTENDS_API_KEY
+ )
+ config_sync(
+ "sync.conf",
+ outdir=CFG_OUTDIR,
+ currency=CURRENCY,
+ api_key=FRONTENDS_API_KEY,
+ rev_proxy_url=REV_PROXY
+ )
+ config_anastasis(
+ "anastasis.conf",
+ outdir=CFG_OUTDIR,
+ currency=CURRENCY,
+ rev_proxy_url=REV_PROXY,
+ api_key=FRONTENDS_API_KEY
+ )
+
+ print_nn("Reset and init exchange DB..")
+ cmd("exchange-dbinit", ["taler-exchange-dbinit", "--reset"])
+ print(" OK")
+
+ print_nn("Remove previous key and data files..")
+ cmd("remove-taler-data", ["rm", "-fr", Path.home() / ".taler-data" / "*"])
+ print(" OK")
+
+ print_nn("Launching the exchange...")
+ exchange_handle = launch("exchange", ["taler-exchange-httpd"])
+ if not check_running("exchange-httpd", REV_PROXY + "/exchange/keys"):
+ exit(1)
+ print(" OK")
+ print_nn("Launching the exchange RSA helper...")
+ exchange_rsa_handle = launch("exchange-rsa", ["taler-exchange-secmod-rsa"])
+ print_nn("Launching the exchange RSA helper...")
+ exchange_eddsa_handle = launch("exchange-eddsa", ["taler-exchange-secmod-eddsa"])
+ print_nn("exchange-offline: signing the exchange keys, hence testing the crypto helpers are correct...")
+ cmd("taler-exchange-offline", ["taler-exchange-offline", "download", "sign", "upload"])
+ print(" OK")
+ PAYTO_URI=mc.sections["exchange-account-1"]["payto-uri"]
+ print_nn("exchange-offline: enabling {PAYTO_URI}...")
+ cmd("exchange-offline", ["taler-exchange-offline", "enable-account", PAYTO_URI, "upload"])
+ print(" OK")
+
+ # Set up wire fees for next 5 years
+ NOW = datetime.now()
+ YEAR = NOW.year
+ print_nn("Setting wire fees for the next 5 years...")
+ for year in range(YEAR, YEAR+5):
+ cmd("exchange-offline",
+ [
+ "taler-exchange-offline",
+ "wire-fee",
+ year,
+ WIRE_METHOD,
+ CURRENCY + ":0.01",
+ CURRENCY + ":0.01",
+ "upload"
+ ]
+ )
+ print(" OK")
+ print_nn("Getting exchange master public key via /keys..")
+ try:
+ response = get(REV_PROXY + "/exchange/keys")
+ response.raise_for_status()
+ except:
+ EXCHANGE_MASTER_PUB = response.json().get("master_public_key")
+ print(" OK")
+ print_nn("Stopping exchange HTTP daemon and crypto helpers...")
+ kill("exchange-rsa", exchange_rsa_handle)
+ kill("exchange-eddsa", exchange_eddsa_handle)
+ print(" OK")
+ print_nn("Add this exchange to the auditor...")
+ cmd(
+ "auditor-exchange",
+ [
+ "taler-auditor-exchange",
+ "-m", EXCHANGE_MASTER_PUB,
+ "-u", REV_PROXY + "/exchange"
+ ]
+ )
+ ## Step 4: Set up euFin
+ print_nn("Resetting euFin databases...")
+ try:
+ remove(SANDBOX_DB_FILE)
+ remove(NEXUS_DB_FILE)
+ except OSError as error:
+ if error.errno != errno.ENOENT:
+ raise error
+ print(" OK")
+
+ print_nn("Create Sandbox superuser...")
+ cmd(
+ "sandbox-superuser",
+ [
+ "libeufin-sandbox", "superuser",
+ SANDBOX_ADMIN_USERNAME,
+ "--password", SANDBOX_ADMIN_PASSWORD
+ ]
+ )
+ print(" OK")
+ print_nn("Launching Sandbox...")
+ handle_sandbox = launch("sandbox", [
+ "libeufin-sandbox", "serve",
+ "--with-unix-socket", "/tmp/sandbox.sock"
+ ])
+ if not check_running("sandbox", SANDBOX_URL):
+ exit(1)
+ print(" OK")
+
+ print_nn("Make Sandbox EBICS host...")
+ cmd(
+ "sandbox-create-ebicshost",
+ [
+ "libeufin-cli", "sandbox",
+ "--sandbox-url", SANDBOX_URL,
+ "ebicshost", "create",
+ "--host-id", EBICS_HOST_ID,
+ ],
+ get_sandbox_cli_env(
+ SANDBOX_ADMIN_USERNAME,
+ SANDBOX_ADMIN_PASSWORD
+ )
+ )
+ print(" OK")
+
+ prepare_sandbox_account(
+ currency=CURRENCY,
+ sandbox_url=SANDBOX_URL,
+ ebics_host_id=EBICS_HOST_ID,
+ ebics_partner_id=EXCHANGE_EBICS_PARTNER_ID,
+ ebics_user_id=EXCHANGE_EBICS_USER_ID,
+ person_name="Exchange Owner",
+ bank_account_name="sandbox-account-exchange",
+ bank_account_iban=IBAN_EXCHANGE,
+ env=get_sandbox_cli_env(
+ SANDBOX_ADMIN_USERNAME,
+ SANDBOX_ADMIN_PASSWORD
+ )
+ )
+ prepare_sandbox_account(
+ currency=CURRENCY,
+ sandbox_url=SANDBOX_URL,
+ ebics_host_id=EBICS_HOST_ID,
+ ebics_partner_id="unusedMerchantEbicsPartnerId",
+ ebics_user_id="unusedMerchantEbicsUserId",
+ person_name="Shop Owner",
+ bank_account_name="sandbox-account-merchant",
+ bank_account_iban=IBAN_MERCHANT,
+ env=get_sandbox_cli_env(
+ SANDBOX_ADMIN_USERNAME,
+ SANDBOX_ADMIN_PASSWORD
+ )
+ )
+ prepare_sandbox_account(
+ currency=CURRENCY,
+ sandbox_url=SANDBOX_URL,
+ ebics_host_id=EBICS_HOST_ID,
+ ebics_partner_id="unusedCustomerEbicsPartnerId",
+ ebics_user_id="unusedCustomerEbicsUserId",
+ person_name="Customer Person",
+ bank_account_name="sandbox-account-customer",
+ bank_account_iban=IBAN_CUSTOMER,
+ env=get_sandbox_cli_env(
+ SANDBOX_ADMIN_USERNAME,
+ SANDBOX_ADMIN_PASSWORD
+ )
+ )
+ print_nn("Make Nexus superuser ...")
+ cmd(
+ "nexus-superuser",
+ [
+ "libeufin-nexus", "superuser",
+ EXCHANGE_NEXUS_USERNAME,
+ "--password", EXCHANGE_NEXUS_PASSWORD
+ ]
+ )
+ print(" OK")
+ print_nn("Launching Nexus...")
+ handle_nexus = launch("nexus", [
+ "libeufin-nexus", "serve",
+ "--with-unix-socket", "/tmp/nexus.sock"
+ ])
+ if not check_running("nexus", NEXUS_URL):
+ exit(1)
+ print(" OK")
+
+ prepare_nexus_account(
+ ebics_url=EBICS_URL,
+ ebics_host_id=EBICS_HOST_ID,
+ ebics_partner_id=EXCHANGE_EBICS_PARTNER_ID,
+ ebics_user_id=EXCHANGE_EBICS_USER_ID,
+ bank_connection_name=EXCHANGE_BANK_CONNECTION,
+ bank_account_name_sandbox=EXCHANGE_BANK_ACCOUNT_SANDBOX,
+ bank_account_name_nexus=EXCHANGE_BANK_ACCOUNT_NEXUS,
+ env=get_nexus_cli_env(
+ EXCHANGE_NEXUS_USERNAME,
+ EXCHANGE_NEXUS_PASSWORD,
+ NEXUS_URL
+ )
+ )
+ print_nn("Create Taler facade ...")
+ cmd(
+ "create-taler-facade",
+ [
+ "libeufin-cli", "facades",
+ "new-taler-wire-gateway-facade",
+ "--currency", CURRENCY,
+ "--facade-name", EXCHANGE_FACADE_NAME,
+ EXCHANGE_BANK_CONNECTION,
+ EXCHANGE_BANK_ACCOUNT_NEXUS
+ ],
+ get_nexus_cli_env(
+ EXCHANGE_NEXUS_USERNAME,
+ EXCHANGE_NEXUS_PASSWORD,
+ NEXUS_URL
+ )
+ )
+ print(" OK")
+ try:
+ response = get(
+ NEXUS_URL + "/facades",
+ auth=auth.HTTPBasicAuth(
+ EXCHANGE_NEXUS_USERNAME,
+ EXCHANGE_NEXUS_PASSWORD
+ )
+ )
+ response.raise_for_status()
+ except Exception as error:
+ print(error)
+ exit(1)
+ FACADE_URL=response.json().get("facade")[0].get("baseUrl")
+
+ print_nn("Terminating Nexus...")
+ kill("nexus", handle_nexus)
+ print(" OK")
+ print_nn("Terminating Sandbox...")
+ kill("sandbox", handle_sandbox)
+ print(" OK")
+
+ # Finish configuration now:
+ cmd(
+ "specify-exchange-pub-for-merchant",
+ [
+ "taler-config", "-s"
+ f"merchant-exchange-{CURRENCY}",
+ "-o" "master_key", "-V",
+ EXCHANGE_MASTER_PUB
+ ]
+ )
+
+ # Point the exchange to the facade.
+ cmd(
+ "specify-facade-url",
+ [
+ "taler-config", "-s"
+ f"exchange-account-credentials-1",
+ "-o" "wire_gateway_url",
+ "-V", FACADE_URL
+ ]
+ )
+
+ cmd(
+ "specify-username-for-facade",
+ [
+ "taler-config", "-s"
+ f"exchange-account-credentials-1",
+ "-o" "username",
+ "-V", EXCHANGE_NEXUS_USERNAME
+ ]
+ )
+ cmd(
+ "specify-password-for-facade",
+ [
+ "taler-config", "-s"
+ f"exchange-account-credentials-1",
+ "-o" "password",
+ "-V", EXCHANGE_NEXUS_PASSWORD
+ ]
+ )
+
+ ## Step 6: Set up merchant
+
+ print_nn("Reset and init merchant database...")
+ cmd("merchant-dbinit", ["taler-merchant-dbinit", "--reset"])
+ print(" OK")
+
+ # FIXME: Configure instances here!
+
+
+
if __name__ == "__main__":
cli()