import importlib.resources import os import socket from flask import Flask from flask_kerberos import init_kerberos from zope import component from .error_handlers import register_error_handlers from ceo_common.interfaces import IConfig, IKerberosService, ILDAPService, IFileService, \ IMailmanService, IMailService, IUWLDAPService, IHTTPClient from ceo_common.model import Config, HTTPClient, RemoteMailmanService from ceod.model import KerberosService, LDAPService, FileService, \ MailmanService, MailService, UWLDAPService def create_app(flask_config={}): app = Flask(__name__) app.config.from_mapping(flask_config) if app.config.get('ENV') == 'development' and 'CEOD_CONFIG' not in os.environ: with importlib.resources.path('ceo_common.test', 'ceod_dev.ini') as p: config_file = p.__fspath__() else: config_file = None cfg = Config(config_file) component.provideUtility(cfg, IConfig) init_kerberos(app, service='ceod') hostname = socket.gethostname() # Only ceod_admin_host has the ceod/admin key in its keytab if hostname == cfg.get('ceod_admin_host'): krb_srv = KerberosService(cfg.get('ldap_admin_principal')) from ceod.api import members app.register_blueprint(members.bp, url_prefix='/api/members') else: fqdn = socket.getfqdn() krb_srv = KerberosService(f'ceod/{fqdn}') component.provideUtility(krb_srv, IKerberosService) # Any host can use LDAPService, but only ceod_admin_host can write ldap_srv = LDAPService() component.provideUtility(ldap_srv, ILDAPService) http_client = HTTPClient() component.provideUtility(http_client, IHTTPClient) # Only instantiate FileService if this host has NFS no_root_squash # If admin_host and fs_root_host become separate, we will need # to create a RemoteFileService if hostname == cfg.get('ceod_fs_root_host'): file_srv = FileService() component.provideUtility(file_srv, IFileService) # Only offer mailman API if this host is running Mailman if hostname == cfg.get('ceod_mailman_host'): mailman_srv = MailmanService() component.provideUtility(mailman_srv, IMailmanService) from ceod.api import mailman app.register_blueprint(mailman.bp, url_prefix='/api/mailman') else: mailman_srv = RemoteMailmanService() component.provideUtility(mailman_srv, IMailmanService) mail_srv = MailService() component.provideUtility(mail_srv, IMailService) uwldap_srv = UWLDAPService() component.provideUtility(uwldap_srv, IUWLDAPService) 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