diff --git a/charts/eric-oss-hello-world-python-app/templates/configmap/envoy-configmap.yaml b/charts/eric-oss-hello-world-python-app/templates/configmap/envoy-configmap.yaml index bf71f2e..34743ca 100644 --- a/charts/eric-oss-hello-world-python-app/templates/configmap/envoy-configmap.yaml +++ b/charts/eric-oss-hello-world-python-app/templates/configmap/envoy-configmap.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: ConfigMap metadata: @@ -14,7 +13,9 @@ data: ENVOY_CONFIG_FILE: |- static_resources: listeners: - # TLS listener for mTLS endpoint + # ============================================================ + # INGRESS + # ============================================================ - name: listener_https address: socket_address: @@ -38,11 +39,12 @@ data: - match: path: "/sample-app/python/metrics" route: - cluster: eric-oss-hello-world-python-app-cluster + cluster: eric-oss-hello-world-python-app-cluster http_filters: - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + transport_socket: name: envoy.transport_sockets.tls typed_config: @@ -57,7 +59,40 @@ data: validation_context: trusted_ca: filename: {{ printf "%s/%s" (default $.Values.instantiationDefaults.proxyCaCertMountPath $.Values.proxyCaCertMountPath) (default $.Values.instantiationDefaults.platformCaCertFileName $.Values.platformCaCertFileName) | quote }} + + # ============================================================ + # OUTBOUND listener (localhost:9000) + # ============================================================ + - name: listener_token_outbound + address: + socket_address: + address: 127.0.0.1 + port_value: 9000 + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: token_outbound + route_config: + virtual_hosts: + - name: token_service + domains: ["*"] + routes: + - match: + prefix: "/" + route: + cluster: eic-outbound-cluster + host_rewrite_literal: {{ .Values.eicBaseUrl | default "" | replace "https://" "" | quote }} + http_filters: + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + # ============================================================ + # App cluster + # ============================================================ - name: eric-oss-hello-world-python-app-cluster type: STATIC load_assignment: @@ -69,3 +104,34 @@ data: socket_address: address: 127.0.0.1 port_value: 8050 + + # ============================================================ + # EIC outbound cluster (mTLS) + # ============================================================ + - name: eic-outbound-cluster + type: LOGICAL_DNS + connect_timeout: 10s + dns_lookup_family: V4_ONLY + load_assignment: + cluster_name: eic-outbound-cluster + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: {{ .Values.eicBaseUrl | default "" | replace "https://" "" | quote }} + port_value: 443 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + sni: {{ .Values.eicBaseUrl | default "" | replace "https://" "" | quote }} + common_tls_context: + tls_certificates: + - certificate_chain: + filename: {{ printf "%s/%s" (default $.Values.instantiationDefaults.proxyAppCertMountPath $.Values.proxyAppCertMountPath) (default $.Values.instantiationDefaults.appCertFileName $.Values.appCertFileName) | quote }} + private_key: + filename: {{ printf "%s/%s" (default $.Values.instantiationDefaults.proxyAppCertMountPath $.Values.proxyAppCertMountPath) (default $.Values.instantiationDefaults.appKeyFileName $.Values.appKeyFileName) | quote }} + validation_context: + trusted_ca: + filename: {{ printf "%s/%s" (default $.Values.instantiationDefaults.proxyCaCertMountPath $.Values.proxyCaCertMountPath) (default $.Values.instantiationDefaults.platformCaCertFileName $.Values.platformCaCertFileName) | quote }} diff --git a/eric-oss-hello-world-python-app/login.py b/eric-oss-hello-world-python-app/login.py index 4cbfe07..1cb0fc2 100644 --- a/eric-oss-hello-world-python-app/login.py +++ b/eric-oss-hello-world-python-app/login.py @@ -5,10 +5,10 @@ """ import os -from urllib.parse import urljoin import json import time import requests +from urllib.parse import urljoin from config import get_config @@ -21,34 +21,25 @@ def login(): https://developer.intelligentautomationplatform.ericsson.net/#tutorials/app-authentication """ config = get_config() + login_path = "/auth/realms/master/protocol/openid-connect/token" - login_url = urljoin(config.get("eic_host_url"), login_path) - headers = {"Content-Type": "application/x-www-form-urlencoded"} - resp = tls_login(login_url, headers) - resp = json.loads(resp.decode("utf-8")) - token, time_until_expiry = resp["access_token"], resp["expires_in"] - time_until_expiry -= ( - 10 # add a buffer to ensure our session doesn't expire mid-request - ) - return token, time.time() + time_until_expiry + # Envoy outbound listener + envoy_base_url = "http://127.0.0.1:9000" + login_url = urljoin(envoy_base_url, login_path) + + headers = { + "Content-Type": "application/x-www-form-urlencoded" + } + + form_data = { + "grant_type": "client_credentials", + "tenant_id": "master", + } -def tls_login(url, headers): - """This function sends an HTTP POST request with TLS for the login operation""" - config = get_config() - ca_cert = os.path.join( - "/", config.get("ca_cert_file_path"), config.get("ca_cert_file_name") - ) - app_cert = os.path.join( - "/", config.get("app_cert_file_path"), config.get("app_cert") - ) - app_key = os.path.join( - "/", config.get("app_cert_file_path"), config.get("app_key")) client_id_path = os.path.join( "/", config.get("client_creds_file_path"), config.get("client_id_file_name") ) - form_data = {"grant_type": "client_credentials", "tenant_id": "master"} - cert = (app_cert, app_key) try: with open(client_id_path, "r", encoding="utf-8") as f: @@ -58,10 +49,26 @@ def tls_login(url, headers): try: response = requests.post( - url, data=form_data, headers=headers, timeout=5, verify=ca_cert, cert=cert + login_url, + data=form_data, + headers=headers, + timeout=5, ) + if response.status_code != 200: - raise LoginError(f"Login failed ({response.status_code})") + raise LoginError( + f"Login failed ({response.status_code}): {response.text}" + ) + except Exception as exception: raise LoginError(f"Login failed ({exception})") from exception - return response.content + + resp = response.json() + + token = resp["access_token"] + time_until_expiry = resp["expires_in"] + + # buffer to avoid expiry mid-request + time_until_expiry -= 10 + + return token, time.time() + time_until_expiry