From 0ff917f82ced8bea57312c7a8e8565d192561d9b Mon Sep 17 00:00:00 2001 From: Mustafa Baser Date: Tue, 15 Feb 2022 19:54:33 +0300 Subject: [PATCH] feat: flex-linux-setup add casa install --- .../flex_linux_setup/flex_setup.py | 240 ++++++++++++++---- .../auiConfiguration.properties | 0 .../flex_linux_setup/templates/casa.default | 11 + .../flex_linux_setup/templates/casa.service | 13 + .../templates/casa_apache_directive | 5 + .../templates/casa_client.ldif | 33 +++ .../templates/casa_config.ldif | 5 + 7 files changed, 254 insertions(+), 53 deletions(-) rename flex-linux-setup/flex_linux_setup/{ => templates}/auiConfiguration.properties (100%) create mode 100644 flex-linux-setup/flex_linux_setup/templates/casa.default create mode 100644 flex-linux-setup/flex_linux_setup/templates/casa.service create mode 100644 flex-linux-setup/flex_linux_setup/templates/casa_apache_directive create mode 100644 flex-linux-setup/flex_linux_setup/templates/casa_client.ldif create mode 100644 flex-linux-setup/flex_linux_setup/templates/casa_config.ldif diff --git a/flex-linux-setup/flex_linux_setup/flex_setup.py b/flex-linux-setup/flex_linux_setup/flex_setup.py index 85f07e47a..fcc619501 100755 --- a/flex-linux-setup/flex_linux_setup/flex_setup.py +++ b/flex-linux-setup/flex_linux_setup/flex_setup.py @@ -4,15 +4,20 @@ import os import zipfile import argparse +import time from urllib.parse import urljoin jans_setup_dir = '/opt/jans/jans-setup' sys.path.append(jans_setup_dir) -if not (os.path.join(jans_setup_dir) and ('/etc/jans/conf/jans.properties')): +if not (os.path.join(jans_setup_dir) and os.path.join('/etc/jans/conf/jans.properties')): print("Please install Jans server then execute this script.") sys.exit() +if not os.path.exists('/opt/jans/jetty/jans-config-api/start.ini'): + print("Please install Jans Config Api then execute this script.") + sys.exit() + from setup_app import paths paths.LOG_FILE = os.path.join(jans_setup_dir, 'logs/flex-setup.log') @@ -26,12 +31,13 @@ from setup_app.installers.node import NodeInstaller from setup_app.installers.httpd import HttpdInstaller from setup_app.installers.config_api import ConfigApiInstaller +from setup_app.installers.jetty import JettyInstaller parser = argparse.ArgumentParser(description="This script downloads Gluu Admin UI components and installs") parser.add_argument('--setup-branch', help="Jannsen setup github branch", default='main') -parser.add_argument('--flex-branch', help="Jannsen setup github branch", default='main') -parser.add_argument('--jans-branch', help="Jannsen setup github branch", default='main') - +parser.add_argument('--flex-branch', help="Jannsen flex setup github branch", default='main') +parser.add_argument('--jans-branch', help="Jannsen github branch", default='main') +parser.add_argument('-casa-integration', help="Install Casa Integration", action='store_true') argsp = parser.parse_args() @@ -49,76 +55,204 @@ "JANS_BRANCH": argsp.jans_branch, "JANS_APP_VERSION": "1.0.0", "JANS_BUILD": "-SNAPSHOT", - "NODE_VERSION": "v14.18.2" + "NODE_VERSION": "v14.18.2", + "CASA_VERSION": "5.0.0-SNAPSHOT", } node_installer = NodeInstaller() -httpdInstaller = HttpdInstaller() -configApiInstaller = ConfigApiInstaller() +httpd_installer = HttpdInstaller() +config_api_installer = ConfigApiInstaller() -def main(): - if not node_installer.installed(): - node_fn = 'node-{0}-linux-x64.tar.xz'.format(app_versions['NODE_VERSION']) - node_path = os.path.join(Config.distAppFolder, node_fn) - if not os.path.exists(node_path): - print("Downloading", node_fn) - base.download('https://nodejs.org/dist/{0}/node-{0}-linux-x64.tar.xz'.format(app_versions['NODE_VERSION']), node_path) - print("Installing node") - node_installer.install() +class flex_installer(JettyInstaller): + + + def __init__(self): + + self.gluu_admin_ui_source_path = os.path.join(Config.distJansFolder, 'gluu-admin-ui.zip') + self.log4j2_adminui_path = os.path.join(Config.distJansFolder, 'log4j2-adminui.xml') + self.log4j2_path = os.path.join(Config.distJansFolder, 'log4j2.xml') + self.admin_ui_plugin_source_path = os.path.join(Config.distJansFolder, 'admin-ui-plugin-distribution.jar') + self.flex_path = os.path.join(Config.distJansFolder, 'flex.zip') + self.source_dir = os.path.join(Config.outputFolder, 'admin-ui') + self.flex_setup_dir = os.path.join(self.source_dir, 'flex-linux-setup') + self.templates_dir = os.path.join(self.flex_setup_dir, 'templates') + self.admin_ui_config_properties_path = os.path.join(self.templates_dir, 'auiConfiguration.properties') + self.casa_web_resources_fn = os.path.join(Config.distJansFolder, 'casa_web_resources.xml') + self.casa_war_fn = os.path.join(Config.distJansFolder, 'casa.war') + + def download_files(self): + + print("Downloading components") + base.download(urljoin(maven_base_url, 'admin-ui-plugin/{0}{1}/admin-ui-plugin-{0}{1}-distribution.jar'.format(app_versions['JANS_APP_VERSION'], app_versions['JANS_BUILD'])), self.admin_ui_plugin_source_path) + base.download('https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-config-api/server/src/main/resources/log4j2.xml'.format(app_versions['JANS_BRANCH']), self.log4j2_path) + base.download('https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-config-api/plugins/admin-ui-plugin/config/log4j2-adminui.xml'.format(app_versions['JANS_BRANCH']), self.log4j2_adminui_path) + base.download('https://github.com/GluuFederation/flex/archive/refs/heads/{}.zip'.format(app_versions['FLEX_BRANCH']), self.flex_path) + base.download('https://github.com/GluuFederation/casa/raw/gluu_cloud/extras/casa_web_resources.xml', self.casa_web_resources_fn) + base.download('https://maven.gluu.org/maven/org/gluu/casa/{0}/casa-{0}.war'.format(app_versions['CASA_VERSION']), self.casa_war_fn) + + + def install_gluu_admin_ui(self): + + print("Installing Gluu Admin UI Frontend") + + print("Extracting admin-ui from", self.flex_path) + if os.path.exists(self.source_dir): + os.rename(self.source_dir, self.source_dir+'-'+time.ctime().replace(' ', '_')) + base.extract_from_zip(self.flex_path, 'admin-ui', self.source_dir) + base.extract_from_zip(self.flex_path, 'flex-linux-setup/flex_linux_setup', self.flex_setup_dir) + + print("self.source_dir", self.source_dir) + env_tmp = os.path.join(self.source_dir, '.env.tmp') + print("env_tmp", env_tmp) + config_api_installer.renderTemplateInOut(env_tmp, self.source_dir, self.source_dir) + config_api_installer.copyFile(os.path.join(self.source_dir, '.env.tmp'), os.path.join(self.source_dir, '.env')) + config_api_installer.run([paths.cmd_chown, '-R', 'node:node', self.source_dir]) + cmd_path = 'PATH=$PATH:{}/bin:{}/bin'.format(Config.jre_home, Config.node_home) + + for cmd in ('npm install @openapitools/openapi-generator-cli', 'npm run api', 'npm install', 'npm run build:prod'): + print("Executing `{}`".format(cmd)) + run_cmd = '{} {}'.format(cmd_path, cmd) + config_api_installer.run(['/bin/su', 'node','-c', run_cmd], self.source_dir) + + target_dir = os.path.join(httpd_installer.server_root, 'admin') + + print("Copying files to", target_dir) + config_api_installer.copyTree(os.path.join(self.source_dir, 'dist'), target_dir) + + config_api_installer.check_clients([('role_based_client_id', '2000.')]) + config_api_installer.renderTemplateInOut(self.admin_ui_config_properties_path, os.path.join(self.flex_setup_dir, 'templates'), config_api_installer.custom_config_dir) + admin_ui_plugin_path = os.path.join(config_api_installer.libDir, os.path.basename(self.admin_ui_plugin_source_path)) + config_api_installer.web_app_xml_fn = os.path.join(config_api_installer.jetty_base, config_api_installer.service_name, 'webapps/jans-config-api.xml') + config_api_installer.copyFile(self.admin_ui_plugin_source_path, config_api_installer.libDir) + config_api_installer.add_extra_class(admin_ui_plugin_path) + + for logfn in (self.log4j2_adminui_path, self.log4j2_path): + config_api_installer.copyFile(logfn, config_api_installer.custom_config_dir) + + + def install_casa(self): + Config.templateRenderingDict['casa_redirect_uri'] = 'https://{}/casa'.format(Config.hostname) + Config.templateRenderingDict['casa_redirect_logout_uri'] = 'https://{}/casa/bye.zul'.format(Config.hostname) + Config.templateRenderingDict['casa_frontchannel_logout_uri'] = 'https://{}/casa/autologout'.format(Config.hostname) + Config.templateRenderingDict['casa_web_port'] = '8080' + self.casa_client_fn = os.path.join(self.source_dir, 'templates/casa_client.ldif') + self.casa_config_fn = os.path.join(self.source_dir, 'templates/casa_config.ldif') + self.service_name = 'casa' - gluu_admin_ui_source_path = os.path.join(Config.distJansFolder, 'gluu-admin-ui.zip') - log4j2_adminui_path = os.path.join(Config.distJansFolder, 'log4j2-adminui.xml') - log4j2_path = os.path.join(Config.distJansFolder, 'log4j2.xml') - admin_ui_plugin_source_path = os.path.join(Config.distJansFolder, 'admin-ui-plugin-distribution.jar') - flex_path = os.path.join(Config.distJansFolder, 'flex.zip') - source_dir = os.path.join(Config.outputFolder, 'admin-ui') - flex_setup_dir = os.path.join(source_dir, 'flex-linux-setup') - admin_ui_config_properties_path = os.path.join(flex_setup_dir, 'auiConfiguration.properties') + self.check_clients([('casa_client_id', '3000.')]) - print("Downloading components") - base.download(urljoin(maven_base_url, 'admin-ui-plugin/{0}{1}/admin-ui-plugin-{0}{1}-distribution.jar'.format(app_versions['JANS_APP_VERSION'], app_versions['JANS_BUILD'])), admin_ui_plugin_source_path) - base.download('https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-config-api/server/src/main/resources/log4j2.xml'.format(app_versions['JANS_BRANCH']), log4j2_path) - base.download('https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-config-api/plugins/admin-ui-plugin/config/log4j2-adminui.xml'.format(app_versions['JANS_BRANCH']), log4j2_adminui_path) - base.download('https://github.com/GluuFederation/flex/archive/refs/heads/{}.zip'.format(app_versions['FLEX_BRANCH']), flex_path) + print(Config.casa_client_id) + print(Config.casa_client_encoded_pw) + print(Config.casa_client_pw) + self.renderTemplateInOut(self.casa_client_fn, self.templates_dir, self.source_dir) + self.renderTemplateInOut(self.casa_config_fn, self.templates_dir, self.source_dir) + self.dbUtils.import_ldif([ + os.path.join(self.source_dir, os.path.basename(self.casa_client_fn)), + os.path.join(self.source_dir, os.path.basename(self.casa_config_fn)), + ]) - print("Installing Gluu Admin UI Frontend") - print("Extracting admin-ui from", flex_path) - base.extract_from_zip(flex_path, 'admin-ui', source_dir) - base.extract_from_zip(flex_path, 'flex-linux-setup/flex_linux_setup', flex_setup_dir) + Config.installCasa = True - configApiInstaller.renderTemplateInOut(os.path.join(source_dir, '.env.tmp'), source_dir, source_dir) - configApiInstaller.copyFile(os.path.join(source_dir, '.env.tmp'), os.path.join(source_dir, '.env')) - configApiInstaller.run([paths.cmd_chown, '-R', 'node:node', source_dir]) - cmd_path = 'PATH=$PATH:{}/bin:{}/bin'.format(Config.jre_home, Config.node_home) + self.copyFile(os.path.join(self.templates_dir, 'casa.default'), os.path.join(Config.templateFolder, 'jetty/casa')) - for cmd in ('npm install @openapitools/openapi-generator-cli', 'npm run api', 'npm install', 'npm run build:prod'): - print("Executing `{}`".format(cmd)) - run_cmd = '{} {}'.format(cmd_path, cmd) - configApiInstaller.run(['/bin/su', 'node','-c', run_cmd], source_dir) + self.jetty_app_configuration[self.service_name] = { + "memory": { + "max_allowed_mb": 1024, + "metaspace_mb": 128, + "jvm_heap_ration": 0.7, + "ratio": 0.1 + }, + "jetty": { + "modules": "server,deploy,resources,http,http-forwarded,console-capture,jsp,cdi-decorate" + }, + "installed": False, + "name": self.service_name + } - target_dir = os.path.join(httpdInstaller.server_root, 'admin') - print("Copying files to", target_dir) - configApiInstaller.copyTree(os.path.join(source_dir, 'dist'), target_dir) - configApiInstaller.check_clients([('role_based_client_id', '2000.')]) + print("Calculating application memory") - configApiInstaller.renderTemplateInOut(admin_ui_config_properties_path, flex_setup_dir, configApiInstaller.custom_config_dir) - admin_ui_plugin_path = os.path.join(configApiInstaller.libDir, os.path.basename(admin_ui_plugin_source_path)) - configApiInstaller.web_app_xml_fn = os.path.join(configApiInstaller.jetty_base, configApiInstaller.service_name, 'webapps/jans-config-api.xml') - configApiInstaller.copyFile(admin_ui_plugin_source_path, configApiInstaller.libDir) - configApiInstaller.add_extra_class(admin_ui_plugin_path) + installedComponents = [] - for logfn in (log4j2_adminui_path, log4j2_path): - configApiInstaller.copyFile(logfn, configApiInstaller.custom_config_dir) + # Jetty apps + for config_var, service in [('installOxAuth', 'jans-auth'), + ('installScimServer', 'jans-scim'), + ('installFido2', 'jans-fido2'), + ('installConfigApi', 'jans-config-api'), + ('installEleven', 'jans-eleven'), + ('installCasa', self.service_name), + ]: + if Config.get(config_var) and service in self.jetty_app_configuration: + installedComponents.append(self.jetty_app_configuration[service]) + + self.calculate_aplications_memory(Config.application_max_ram, self.jetty_app_configuration, installedComponents) + + self.installJettyService(self.jetty_app_configuration[self.service_name], True) + self.copyFile(os.path.join(self.templates_dir, 'casa.service'), '/etc/systemd/system') + jetty_service_dir = os.path.join(Config.jetty_base, self.service_name) + jetty_service_webapps_dir = os.path.join(jetty_service_dir, 'webapps') + + + self.run([paths.cmd_mkdir, '-p', os.path.join(jetty_service_dir, 'static')]) + self.run([paths.cmd_mkdir, '-p', os.path.join(jetty_service_dir, 'plugins')]) + self.copyFile(self.casa_war_fn, jetty_service_webapps_dir) + self.copyFile(self.casa_web_resources_fn, jetty_service_webapps_dir) + self.run([paths.cmd_chown, '-R', '{0}:{0}'.format(Config.jetty_user), jetty_service_dir]) + gluu_python_dir = '/opt/gluu/python/' + self.run([paths.cmd_mkdir, '-p', os.path.join(gluu_python_dir, 'libs')]) + self.run([paths.cmd_chown, '-R', '{0}:{0}'.format(Config.jetty_user), gluu_python_dir]) + + apache_directive_template_text = self.readFile(os.path.join(self.templates_dir, 'casa_apache_directive')) + + apache_directive_text = self.fomatWithDict(apache_directive_template_text, Config.templateRenderingDict) + + https_jans_text = self.readFile(httpd_installer.https_jans_fn) + + if not '' in https_jans_text: + + https_jans_list = https_jans_text.splitlines() + n = 0 + + for i, l in enumerate(https_jans_list): + if l.strip() == '': + n = i + + https_jans_list.insert(n+1, '\n' + apache_directive_text + '\n') + self.writeFile(httpd_installer.https_jans_fn, '\n'.join(https_jans_list)) + httpd_installer.restart() + + self.enable() + + +def main(): + + if not node_installer.installed(): + node_fn = 'node-{0}-linux-x64.tar.xz'.format(app_versions['NODE_VERSION']) + node_path = os.path.join(Config.distAppFolder, node_fn) + if not os.path.exists(node_path): + print("Downloading", node_fn) + base.download('https://nodejs.org/dist/{0}/node-{0}-linux-x64.tar.xz'.format(app_versions['NODE_VERSION']), node_path) + print("Installing node") + node_installer.install() + + installer_obj = flex_installer() + installer_obj.download_files() + installer_obj.install_gluu_admin_ui() + + if argsp.casa_integration: + installer_obj.install_casa() + + sys.exit() print("Restarting Janssen Config Api") - configApiInstaller.restart() + config_api_installer.restart() print("Installation was completed. Browse https://{}/admin".format(Config.hostname)) if __name__ == "__main__": main() + diff --git a/flex-linux-setup/flex_linux_setup/auiConfiguration.properties b/flex-linux-setup/flex_linux_setup/templates/auiConfiguration.properties similarity index 100% rename from flex-linux-setup/flex_linux_setup/auiConfiguration.properties rename to flex-linux-setup/flex_linux_setup/templates/auiConfiguration.properties diff --git a/flex-linux-setup/flex_linux_setup/templates/casa.default b/flex-linux-setup/flex_linux_setup/templates/casa.default new file mode 100644 index 000000000..08a881fb0 --- /dev/null +++ b/flex-linux-setup/flex_linux_setup/templates/casa.default @@ -0,0 +1,11 @@ +JAVA_HOME=%(jre_home)s +JAVA=$JAVA_HOME/bin/java +JAVA_OPTIONS="-server -Xms%(casa_min_heap_mem)sm -Xmx%(casa_max_heap_mem)sm -XX:+DisableExplicitGC -Djans.base=%(jansBaseFolder)s -Dserver.base=%(jetty_base)s/casa -Dlog.base=%(jetty_base)s/casa -Dpython.home=%(jython_home)s" + +JETTY_HOME=%(jetty_home)s +JETTY_BASE=%(jetty_base)s/casa +JETTY_USER=%(jetty_user)s +JETTY_ARGS="jetty.http.host=localhost jetty.http.port=%(casa_web_port)s" +TMPDIR=%(jetty_dist)s/temp + +export PYTHON_HOME=%(jython_home)s diff --git a/flex-linux-setup/flex_linux_setup/templates/casa.service b/flex-linux-setup/flex_linux_setup/templates/casa.service new file mode 100644 index 000000000..362ec8435 --- /dev/null +++ b/flex-linux-setup/flex_linux_setup/templates/casa.service @@ -0,0 +1,13 @@ +[Unit] +Description=Gluu Casa service +After=jans-auth.service + +[Service] +Type=forking +ExecStart=/opt/dist/scripts/casa start +ExecStop=/opt/dist/scripts/casa stop +User=jetty +Group=jetty + +[Install] +WantedBy=multi-user.target diff --git a/flex-linux-setup/flex_linux_setup/templates/casa_apache_directive b/flex-linux-setup/flex_linux_setup/templates/casa_apache_directive new file mode 100644 index 000000000..18f555e07 --- /dev/null +++ b/flex-linux-setup/flex_linux_setup/templates/casa_apache_directive @@ -0,0 +1,5 @@ + + ProxyPass http://localhost:%(casa_web_port)s/casa retry=5 connectiontimeout=60 timeout=60 + Order deny,allow + Allow from all + diff --git a/flex-linux-setup/flex_linux_setup/templates/casa_client.ldif b/flex-linux-setup/flex_linux_setup/templates/casa_client.ldif new file mode 100644 index 000000000..d01d6a8c1 --- /dev/null +++ b/flex-linux-setup/flex_linux_setup/templates/casa_client.ldif @@ -0,0 +1,33 @@ +version: 1 +dn: inum=%(casa_client_id)s,ou=clients,o=jans +objectClass: top +objectClass: jansClnt +del: false +displayName: Client for Casa +inum: %(casa_client_id)s +jansAccessTknAsJwt: true +jansAccessTknSigAlg: RS256 +jansAppTyp: web +jansClntSecret: %(casa_client_encoded_pw)s +jansDisabled: false +jansGrantTyp: authorization_code +jansGrantTyp: refresh_token +jansGrantTyp: client_credentials +jansIdTknSignedRespAlg: RS256 +jansInclClaimsInIdTkn: false +jansLogoutSessRequired: false +jansPersistClntAuthzs: true +jansRedirectURI: %(casa_redirect_uri)s +jansRedirectURI: %(casa_redirect_logout_uri)s +jansLogoutURI: %(casa_frontchannel_logout_uri)s +jansRequireAuthTime: false +jansRespTyp: code +jansRptAsJwt: false +jansScope: inum=F0C4,ou=scopes,o=jans +jansScope: inum=43F1,ou=scopes,o=jans +jansScope: inum=10B2,ou=scopes,o=jans +jansScope: inum=341A,ou=scopes,o=jans +jansSignedRespAlg: RS256 +jansSubjectTyp: pairwise +jansTknEndpointAuthMethod: client_secret_basic +jansTrustedClnt: false diff --git a/flex-linux-setup/flex_linux_setup/templates/casa_config.ldif b/flex-linux-setup/flex_linux_setup/templates/casa_config.ldif new file mode 100644 index 000000000..7d0bf9171 --- /dev/null +++ b/flex-linux-setup/flex_linux_setup/templates/casa_config.ldif @@ -0,0 +1,5 @@ +dn: ou=casa,ou=configuration,o=jans +objectClass: jansAppConf +objectClass: top +ou: casa +jansConfApp: {"enable_pass_reset": true, "oidc_config": {"authz_redirect_uri": "%(casa_redirect_uri)s", "post_logout_uri": "%(casa_redirect_logout_uri)s", "frontchannel_logout_uri": "%(casa_frontchannel_logout_uri)s", "scopes": ["openid", "profile", "user_name", "clientinfo"], "op_host": "%(hostname)s", "client": {"clientId": "%(casa_client_id)s", "clientSecret": "casa_client_pw", "clientName": "Client for Casa"}}}