sync dari sicabe-doc/deploy @ e8f8fde
This commit is contained in:
@@ -96,6 +96,30 @@ PUBLIC_URL_ENDPOINTS = {
|
||||
"MINIO_CONSOLE_PUBLIC_URL": ("minio", "http://{addr}:12901"),
|
||||
}
|
||||
|
||||
|
||||
def _ext_url(ext: str, template: str, port: str = "") -> str:
|
||||
"""URL untuk komponen EKSTERNAL dari `components.<c>.address`.
|
||||
|
||||
Bila operator menulis **URL penuh** (mengandung `://`, mis.
|
||||
`https://sso.example.com`) → pakai APA ADANYA: skema + host + port dihormati
|
||||
(default port per skema, mis. https→443, TIDAK ditulis bila default). Bila hanya
|
||||
host/IP polos (perilaku lama) → susun dari `template` + `port` seperti sebelumnya.
|
||||
"""
|
||||
scheme, host, p = inventory.parse_address(ext)
|
||||
if scheme:
|
||||
# Buang port bila = default skema (https→443), supaya `https://host`, bukan
|
||||
# `https://host:443` (ekuivalen, tapi lebih bersih & cocok utk issuer/URL publik).
|
||||
show = p and p != inventory._DEFAULT_SCHEME_PORT.get(scheme)
|
||||
return f"{scheme}://{host}" + (f":{p}" if show else "")
|
||||
if port and "{port}" in template:
|
||||
return template.format(addr=host, port=(p if p else port))
|
||||
return template.format(addr=host)
|
||||
|
||||
|
||||
def _keycloak_external_scheme(doc: dict) -> str:
|
||||
"""Skema URL Keycloak eksternal ('' bila bukan URL penuh). Untuk sslRequired."""
|
||||
return inventory.parse_address(inventory.external_address(doc, "keycloak") or "")[0]
|
||||
|
||||
# SENGAJA TIDAK diarahkan ke IP: KEYCLOAK_URL / TRINO_URL dan var `*_URL` lain yang
|
||||
# bersifat identitas (issuer OIDC harus stabil — lihat R10 §4.10.1: pakai DNS
|
||||
# internal, bukan IP). Itu milik operator dan harus sudah benar di `cluster.yml`
|
||||
@@ -195,7 +219,7 @@ def _is_topology_var(line: str) -> bool:
|
||||
"""
|
||||
key = line.split("=", 1)[0].strip()
|
||||
owned = {
|
||||
"EXTERNAL_SERVICES", "LOCAL_SERVICES", "KEYCLOAK_SSL_REQUIRED",
|
||||
"EXTERNAL_SERVICES", "LOCAL_SERVICES", "KEYCLOAK_SSL_REQUIRED", "KEYCLOAK_INTERNAL_URL",
|
||||
"KC_PROXY_HEADERS", "TRINO_PROCESS_FORWARDED", "CLUSTER_DOMAIN", "TRAEFIK_BIND_ADDR",
|
||||
*ENDPOINT_VARS, *URL_ENDPOINT_VARS,
|
||||
*inventory.PUBLIC_URL_SERVICES, # KEYCLOAK_PUBLIC_URL, GRAFANA_PUBLIC_URL, …
|
||||
@@ -458,7 +482,10 @@ def endpoint_lines(doc: dict, host: str, plan: dict) -> list[str]:
|
||||
for var, component in ENDPOINT_VARS.items():
|
||||
ext = inventory.external_address(doc, component)
|
||||
if ext:
|
||||
lines.append(f"{var}={ext}") # EKSTERNAL (pihak lain) → alamat tetap
|
||||
# EKSTERNAL → HOST saja (buang skema/port bila operator menulis URL penuh,
|
||||
# mis. `https://sso.example.com` → `sso.example.com`). URL lengkapnya
|
||||
# ditangani `*_URL` / KEYCLOAK_INTERNAL_URL, bukan var `*_HOST`.
|
||||
lines.append(f"{var}={inventory.parse_address(ext)[1]}")
|
||||
continue
|
||||
owners = placement.get(component)
|
||||
if not owners:
|
||||
@@ -467,6 +494,13 @@ def endpoint_lines(doc: dict, host: str, plan: dict) -> list[str]:
|
||||
lines.append(f"{var}={component}") # SE-HOST → nama service
|
||||
else:
|
||||
lines.append(f"{var}={plan[owners[0]]['address']}") # LINTAS host → alamat
|
||||
# Keycloak: URL server→server (token/jwks/Grafana). Hanya ditulis bila Keycloak
|
||||
# EKSTERNAL memakai URL PENUH (mis. https://sso.example.com) agar skema+port
|
||||
# dihormati; selain itu compose/script memakai default
|
||||
# `http://${KEYCLOAK_HOST:-keycloak}:${KEYCLOAK_INTERNAL_PORT:-8080}`.
|
||||
kc_ext = inventory.external_address(doc, "keycloak")
|
||||
if kc_ext and inventory.parse_address(kc_ext)[0]:
|
||||
lines.append(f"KEYCLOAK_INTERNAL_URL={_ext_url(kc_ext, '')}")
|
||||
disabled = [n for n, v in inventory.enabled_components(doc).items() if v is False]
|
||||
if disabled:
|
||||
# Komponen `enabled: false` = tidak dijalankan di host mana pun → installer
|
||||
@@ -498,7 +532,7 @@ def public_url_lines(doc: dict, plan: dict | None = None) -> list[str]:
|
||||
for var, (component, tmpl) in PUBLIC_URL_ENDPOINTS.items():
|
||||
ext = inventory.external_address(doc, component)
|
||||
if ext:
|
||||
resolved[var] = tmpl.format(addr=ext) # eksternal → alamat tetap
|
||||
resolved[var] = _ext_url(ext, tmpl) # eksternal → URL penuh dihormati
|
||||
continue
|
||||
owners = placement.get(component)
|
||||
if not owners:
|
||||
@@ -523,8 +557,11 @@ def tls_policy_lines(doc: dict) -> list[str]:
|
||||
tls.mode `edge`/`full` -> `external` (ada Traefik/TLS di depan)
|
||||
"""
|
||||
edge = inventory.tls_mode(doc) != "none"
|
||||
# Keycloak EKSTERNAL ber-URL `https://…` juga menuntut sslRequired=external (permintaan
|
||||
# dari alamat non-lokal lewat TLS di depannya).
|
||||
ext_https = _keycloak_external_scheme(doc) == "https"
|
||||
return [
|
||||
f"KEYCLOAK_SSL_REQUIRED={'external' if edge else 'none'}",
|
||||
f"KEYCLOAK_SSL_REQUIRED={'external' if (edge or ext_https) else 'none'}",
|
||||
# Di belakang Traefik, Keycloak WAJIB memercayai X-Forwarded-* — tanpa itu
|
||||
# permintaan HTTPS dari proxy dianggap HTTP (redirect salah / tuntutan HTTPS).
|
||||
# Sengaja KOSONG saat tanpa proxy: memasangnya membuat Keycloak memercayai
|
||||
@@ -665,7 +702,7 @@ def url_endpoint_lines(doc: dict, host: str, plan: dict, env_path=None) -> list[
|
||||
for var, (component, template) in URL_ENDPOINT_VARS.items():
|
||||
ext = inventory.external_address(doc, component)
|
||||
if ext:
|
||||
lines.append(f"{var}={template.format(addr=ext, port=_endpoint_port(var, env_path))}")
|
||||
lines.append(f"{var}={_ext_url(ext, template, _endpoint_port(var, env_path))}")
|
||||
continue
|
||||
owners = placement.get(component)
|
||||
if not owners:
|
||||
|
||||
Reference in New Issue
Block a user