configOverrides: secret: | SECRET_KEY = '{openssl rand -base64 42 실행 값}' log_level: | LOG_LEVEL = logging.INFO enable_oauth: | from flask_appbuilder.security.manager import (AUTH_DB, AUTH_OAUTH) from superset.security import SupersetSecurityManager from flask import request import requests import logging class CustomSsoSecurityManager(SupersetSecurityManager): def oauth_user_info(self, provider, response=None): # noqa: ARG002 me = self.appbuilder.sm.oauth_remotes[provider].get("openid-connect/userinfo") me.raise_for_status() data = me.json() logging.debug("User info from Keycloak: %s", data) # 변수 정의 role = [] username = data.get("preferred_username", "") host = request.host dip_api_url = "{dip api url}" # dip api url 수정 필요 ex) https://dip-api.example.org # URL과 데이터 정의 url = f"{dip_api_url}/gwapi/v1/projectusers/{username}" request_data = {"url": f"https://{host}"} response = requests.post(url, json=request_data, headers={"Content-Type": "application/json"}, verify=False) # 응답 출력 if response.status_code == 200: logging.info(f"API 요청 성공: {response.status_code}, {response.text}") role.append(response.json().get("roleName","")) else: logging.info(f"API 요청 실패: {response.status_code}, {response.text}") role.append("") return { "username": data.get("preferred_username", ""), "first_name": data.get("given_name", ""), "last_name": data.get("family_name", ""), "email": data.get("email", ""), "role_keys": role, } # OIDC 설정 AUTH_TYPE = AUTH_OAUTH AUTH_USER_REGISTRATION = True AUTH_USER_REGISTRATION_ROLE = "Public" # 매핑되지 않은 사용자는 기본적으로 'Public'으로 설정 AUTH_ROLES_SYNC_AT_LOGIN = True CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager # Custom Security Manager 활성화 ## OIDC provider 정보 설정 OAUTH_PROVIDERS = [ { "name": "keycloak", "icon": "fa-key", "token_key": "access_token", "remote_app": { "client_id": "superset", "client_secret": "{keycloak client secret}", "client_kwargs": { "scope": "openid email profile", 'verify': False }, 'server_metadata_url': 'https://{keycloak url}/auth/realms/paasup/.well-known/openid-configuration', # keycloak url 수정 필요 'api_base_url': 'https://{keycloak url}/auth/realms/paasup/protocol/' # keycloak url 수정 필요 } } ] # OIDC 권한 맵핑 AUTH_ROLES_MAPPING = { 'root': ['Admin'], 'admin': ['Admin'], 'manager': ['Admin'], 'member': ['Alpha'], } # 접속할 DB에 대한 드라이버를 별도 설치해야함. bootstrapScript: | #!/bin/bash pip install sqlalchemy-drill psycopg2-binary Authlib # superset 공통 사용 이미지 # 워커, 플라워, image: repository: apachesuperset.docker.scarf.sh/apache/superset tag: ~ pullPolicy: IfNotPresent resources: {} nodeSelector: {} tolerations: [] ingress: enabled: true # airflow와 동일하게 실측된 문제 — ingressClassName 미지정 시 이 클러스터의 apisix가 # 아예 인식하지 않아 CLASS: 으로 뜨고 접근이 불가능하다. path도 exact "/" 만 # 매치되면 superset의 내부 리다이렉트(예: /login/) 이후 전부 404가 나 regex로 바꾼다. ingressClassName: "apisix" annotations: cert-manager.io/cluster-issuer: "selfsigned-issuer" cert-manager.io/duration: 8760h cert-manager.io/renew-before: 720h k8s.apisix.apache.org/use-regex: "true" k8s.apisix.apache.org/ssl-redirect: "true" path: /.* pathType: ImplementationSpecific hosts: - superset.example.org tls: - hosts: - superset.example.org secretName: superset-tls-secret # Superset node configuration supersetNode: replicas: enabled: true replicaCount: 1 connections: # -- Change in case of bringing your own redis and then also set redis.enabled:false redis_host: '{{ .Release.Name }}-redis-headless' redis_port: "6379" redis_user: "" # redis_password: superset redis_cache_db: "1" redis_celery_db: "0" # Or SSL port is usually 6380 # Update following for using Redis with SSL redis_ssl: enabled: false ssl_cert_reqs: CERT_NONE # 내장 bitnami postgresql 서브차트 대신 cnpg-cluster(전용 인스턴스)를 외부 DB로 사용한다. # 사전 배포: helm install superset-db manifests/helm/cnpg-cluster/1.0.0 \ # -f manifests/helm/cnpg-cluster/1.0.0/custom-values.yaml \ # -f manifests/applicationset/superset/0.13.5/superset-db-values.yaml -n db_host: 'superset-db-rw' db_port: "5432" db_user: superset db_pass: superset db_name: superset resources: {} # Superset Celery worker configuration supersetWorker: replicas: enabled: true replicaCount: 1 resources: {} # Superset beat configuration (to trigger scheduled jobs like reports) supersetCeleryBeat: enabled: false resources: {} supersetCeleryFlower: enabled: false replicaCount: 1 resources: {} postgresql: enabled: false redis: enabled: true architecture: standalone auth: enabled: false password: superset image: registry: docker.io master: resources: limits: {} requests: {} persistence: enabled: true storageClass: "" size: 8Gi