import importlib.resources import os import socket from flask import Flask from zope import component from .error_handlers import register_error_handlers from ceo_common.interfaces import IConfig, IKerberosService, ILDAPService, IFileService, \ IMailmanService, IMailService, IUWLDAPService, IHTTPClient, IDatabaseService from ceo_common.model import Config, HTTPClient, RemoteMailmanService from ceod.api.spnego import init_spnego from ceod.model import KerberosService, LDAPService, FileService, \ MailmanService, MailService, UWLDAPService from ceod.db import MySQLService, PostgreSQLService def create_app(flask_config={}): app = Flask(__name__) app.config.from_mapping(flask_config) if not app.config.get('TESTING'): register_services(app) cfg = component.getUtility(IConfig) init_spnego('ceod') hostname = socket.gethostname() # Only ceod_admin_host should serve the /api/members endpoints because # it needs to run kadmin if hostname == cfg.get('ceod_admin_host'): from ceod.api import members app.register_blueprint(members.bp, url_prefix='/api/members') # Only offer mailman API if this host is running Mailman if hostname == cfg.get('ceod_mailman_host'): from ceod.api import mailman app.register_blueprint(mailman.bp, url_prefix='/api/mailman') if hostname == cfg.get('ceod_database_host'): from ceod.api import database app.register_blueprint(database.bp, url_prefix='/api/db') from ceod.api import groups app.register_blueprint(groups.bp, url_prefix='/api/groups') from ceod.api import positions app.register_blueprint(positions.bp, url_prefix='/api/positions') from ceod.api import uwldap app.register_blueprint(uwldap.bp, url_prefix='/api/uwldap') register_error_handlers(app) @app.route('/ping') def ping(): """Health check""" return 'pong\n' return app def register_services(app): # Config if app.config.get('ENV') == 'development' and 'CEOD_CONFIG' not in os.environ: with importlib.resources.path('tests', 'ceod_dev.ini') as p: config_file = p.__fspath__() else: config_file = None cfg = Config(config_file) component.provideUtility(cfg, IConfig) # KerberosService hostname = socket.gethostname() fqdn = socket.getfqdn() # Only ceod_admin_host has the ceod/admin key in its keytab if hostname == cfg.get('ceod_admin_host'): principal = cfg.get('ldap_admin_principal') else: principal = f'ceod/{fqdn}' krb_srv = KerberosService(principal) component.provideUtility(krb_srv, IKerberosService) # LDAPService ldap_srv = LDAPService() component.provideUtility(ldap_srv, ILDAPService) # HTTPService http_client = HTTPClient() component.provideUtility(http_client, IHTTPClient) # FileService if hostname == cfg.get('ceod_fs_root_host'): file_srv = FileService() component.provideUtility(file_srv, IFileService) # MailmanService if hostname == cfg.get('ceod_mailman_host'): mailman_srv = MailmanService() else: mailman_srv = RemoteMailmanService() component.provideUtility(mailman_srv, IMailmanService) # MailService mail_srv = MailService() component.provideUtility(mail_srv, IMailService) # UWLDAPService uwldap_srv = UWLDAPService() component.provideUtility(uwldap_srv, IUWLDAPService) # MySQLService if hostname == cfg.get('ceod_database_host'): mysql_srv = MySQLService() component.provideUtility(mysql_srv, IDatabaseService, 'mysql') # PostgreSQLService if hostname == cfg.get('ceod_database_host'): psql_srv = PostgreSQLService() component.provideUtility(psql_srv, IDatabaseService, 'postgresql')