|
24 | 24 | import os |
25 | 25 | from typing import Dict, List |
26 | 26 |
|
| 27 | +import requests |
| 28 | +from requests.exceptions import ConnectionError, SSLError |
27 | 29 | from keycloak import KeycloakAdmin |
28 | 30 | from keycloak.exceptions import ( |
29 | 31 | KeycloakConnectionError, |
|
35 | 37 |
|
36 | 38 | logging.basicConfig(level=logging.INFO) |
37 | 39 |
|
| 40 | + |
38 | 41 | def _check_existing(existing_object: Dict, new_object: Dict, case, id_key) -> bool: |
39 | 42 | """ |
40 | 43 | Compare the new object to the existing one, warn about mismatches. Return True if there are mismatches. |
@@ -183,6 +186,26 @@ def _check_and_create_user(keycloak_admin, new_user): |
183 | 186 | logging.info("done") |
184 | 187 |
|
185 | 188 |
|
| 189 | +def _wait_for_tls(url: str, retries=60, wait_secs=2): |
| 190 | + """Keeps calling the url and waits in between retries until the name resolution and TLS works.""" |
| 191 | + logging.info("Waiting for name resolution and TLS.") |
| 192 | + cur_retry = 1 |
| 193 | + while True: |
| 194 | + try: |
| 195 | + requests.get(url, allow_redirects=True) |
| 196 | + except (ConnectionError, SSLError) as err: |
| 197 | + if cur_retry >= retries: |
| 198 | + raise Exception( |
| 199 | + "Timed out trying to wait for name resolution or TLS" |
| 200 | + ) from err |
| 201 | + logging.warning("Failed name resolution or TLS, will wait and retry.") |
| 202 | + time.sleep(wait_secs) |
| 203 | + else: |
| 204 | + break |
| 205 | + finally: |
| 206 | + cur_retry += 1 |
| 207 | + |
| 208 | + |
186 | 209 | # The actual script |
187 | 210 |
|
188 | 211 | parser = argparse.ArgumentParser() |
@@ -221,14 +244,18 @@ def _check_and_create_user(keycloak_admin, new_user): |
221 | 244 | n_attempts = 0 |
222 | 245 | success = False |
223 | 246 |
|
| 247 | +server_url = args.keycloak_url if args.keycloak_url.endswith("/") else args.keycloak_url + "/" |
| 248 | + |
| 249 | +_wait_for_tls(server_url) |
| 250 | + |
224 | 251 | while not success and n_attempts < 31: |
225 | 252 | try: |
226 | 253 | logging.info("Getting an admin access token for Keycloak...") |
227 | 254 | # NOTE: The keycloak python library does not follow redirect fully so passing in |
228 | 255 | # "http://dev.renku.ch/auth" without the trailing "/" will fail with a 405 whereas |
229 | 256 | # "http://dev.renku.ch/auth/" will work without a problem. |
230 | 257 | keycloak_admin = KeycloakAdmin( |
231 | | - server_url=args.keycloak_url if args.keycloak_url.endswith("/") else args.keycloak_url + "/", |
| 258 | + server_url=server_url, |
232 | 259 | username=args.admin_user, |
233 | 260 | password=keycloak_admin_password, |
234 | 261 | verify=True, |
|
0 commit comments