summaryrefslogtreecommitdiff
path: root/bin/taler-deployment-config-instances-iban
blob: 2a5daef7b401a68d915226bc9548cf3cda0d8988 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/env python3

"""
This script makes sure that the merchant backend instances used by the
test/demo environment are created.

We assume that the merchant backend is running, and that the "~/activate"
file has been sourced to provide the right environment variables.
"""

import requests
from os import environ, system
from sys import exit
from urllib.parse import urljoin
from subprocess import Popen
from time import sleep
import psutil
from getpass import getuser

ibans = dict(
  default = "ME00000000000000000000",
  # Must match the IBAN given in the prepare script, called IBAN_MERCHANT.
  blog = "ME00000000000000000001",
)

def expect_env(name):
    val = environ.get(name)
    if not val:
        print(f"{name} not defined.  Please source the ~/activate file.")
        exit(1)
    return val

def wait_merchant_up():
    # Check it started correctly and it is ready to serve requests.
    checks = 10
    url = urljoin(MERCHANT_BACKEND_BASE_URL, "/config")
    while checks > 0:
        try:
            resp = requests.get(url, timeout=5)
        except Exception:
            print("Merchant unreachable")
            sleep(1)
            checks -= 1
            continue

        if resp.status_code != 200:
            sleep(1)
            checks -= 1
            continue

        # Ready.
        return True

    print("Merchant is not correctly serving requests.")
    return False

MERCHANT_BACKEND_BASE_URL = expect_env("TALER_ENV_MERCHANT_BACKEND")
TALER_ENV_NAME = expect_env("TALER_ENV_NAME")
TALER_CONFIG_CURRENCY = expect_env("TALER_CONFIG_CURRENCY")
TALER_ENV_FRONTENDS_APITOKEN = expect_env("TALER_ENV_FRONTENDS_APITOKEN")
authorization_header = {"Authorization": f"Bearer {TALER_ENV_FRONTENDS_APITOKEN}"}


def ensure_instance(instance_id, name, payto_uris, auth):
    resp = requests.get(
        urljoin(MERCHANT_BACKEND_BASE_URL, f"management/instances/{instance_id}"),
        headers = authorization_header
    )
    req = dict(
        id=instance_id,
        name=name,
        payto_uris=payto_uris,
        address=dict(),
        jurisdiction=dict(),
        default_max_wire_fee=f"{TALER_CONFIG_CURRENCY}:1",
        default_wire_fee_amortization=3,
        default_max_deposit_fee=f"{TALER_CONFIG_CURRENCY}:1",
        default_wire_transfer_delay=dict(d_ms="forever"),
        default_pay_delay=dict(d_ms="forever"),
        auth=auth,
    )
    http_method = requests.post
    endpoint = "management/instances"
    # Instance exists, patching it.
    if resp.status_code == 200:
        if instance_id != "Tutorial":
            print(f"Patching instance '{instance_id}'")
            http_method = requests.patch
            endpoint = f"management/instances/{instance_id}"
    resp = http_method(
        urljoin(MERCHANT_BACKEND_BASE_URL, endpoint),
        json=req,
        headers = authorization_header
    )
    if resp.status_code < 200 or resp.status_code >= 300:
        print(f"Could not create (or patch) instance '{instance_id}', backend responds: {resp.status_code}/{resp.text}")
        exit(1)
        
def is_merchant_running():
    for proc in psutil.process_iter():
        if proc.name() == "taler-merchant-httpd" and proc.username() == getuser():
            return True
    return False


def ensure_default_instance():
    # Assumed is managed by ARM
    merchant_was_running = is_merchant_running()
    if merchant_was_running:
        print("Found running merchant, assuming is managed by ARM.  Terminating it")
        system("taler-deployment-arm -k taler-merchant")

    checks = 10
    while checks > 0:
        if is_merchant_running():
            sleep(1)
            checks -= 1
            continue
        break

    if checks == 0:
        print("Could not stop the running merchant.")
        exit(1)
    # ARM is _not_ running the merchant at this point.
    env_with_token = environ.copy()
    env_with_token["TALER_MERCHANT_TOKEN"] = TALER_ENV_FRONTENDS_APITOKEN
    
    print("Starting the merchant outside ARM to pass the token into the environment.")
    # Start the merchant natively.
    merchant = Popen(["taler-merchant-httpd"], env=env_with_token)

    if not wait_merchant_up():
        merchant.terminate()
        merchant.wait()
        exit(1)
    
    print("Merchant started successfully, creating the default instance now.")
    ensure_instance(
        "default",
        "default",
        payto_uris=[f"payto://sepa/bank.{TALER_ENV_NAME}.taler.net/{ibans.get('default')}"],
        auth=dict(method="token", token=TALER_ENV_FRONTENDS_APITOKEN)
    )
    # Native process can be terminated now.
    merchant.terminate()
    merchant.wait()

ensure_default_instance()
print("Restarting merchant _with_ ARM, to create other non-default instances.")
system("taler-deployment-arm -s")
system("taler-deployment-arm -i taler-merchant")
wait_merchant_up()

ensure_instance(
    "blog",
    name="Blog",
    payto_uris=[f"payto://sepa/bank.{TALER_ENV_NAME}.taler.net/{ibans.get('blog')}"],
    auth=dict(method="token", token=TALER_ENV_FRONTENDS_APITOKEN),
)
print("Stopping the ARM merchant")
system("taler-deployment-arm -k taler-merchant")
# NOTE: ARM itself will be stopped by the main prepare script.
# Stopping here will result in indefinite wait at the caller.