From a2944c1ee432985c2bb8e8d52c22710ec73f7039 Mon Sep 17 00:00:00 2001 From: Mustafa Baser Date: Fri, 4 Mar 2022 16:28:38 +0300 Subject: [PATCH] feat(jans-linux-setup): check availibility of ports for OpenDJ backend (#949) * feat: jans-linux-setup check if opendj ports are free * feat: jans-linux-setup check availibilty of ports when backend is opendj --- jans-linux-setup/jans_setup/jans_setup.py | 312 ++++++++---------- .../jans_setup/setup_app/messages.py | 14 +- .../setup_app/utils/properties_utils.py | 13 + .../jans_setup/setup_app/utils/setup_utils.py | 15 + 4 files changed, 177 insertions(+), 177 deletions(-) diff --git a/jans-linux-setup/jans_setup/jans_setup.py b/jans-linux-setup/jans_setup/jans_setup.py index ee428175187..c4192943116 100755 --- a/jans-linux-setup/jans_setup/jans_setup.py +++ b/jans-linux-setup/jans_setup/jans_setup.py @@ -11,47 +11,33 @@ import traceback import code import site -import argparse from pathlib import Path from queue import Queue __STATIC_SETUP_DIR__ = '/opt/jans/jans-setup/' -os.environ['LC_ALL'] = 'C' - queue = Queue() + dir_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(dir_path) -from setup_app.utils import arg_parser - -import install - -group = arg_parser.parser.add_argument_group(install.parser.description) - -for action in install.parser._actions: - if isinstance(action, argparse._HelpAction): - continue - if isinstance(action, argparse._StoreTrueAction): - arg = group.add_argument(*action.option_strings, action='store_true') +if not (os.path.exists('/opt/dist/jans/jans.zip') or os.path.exists('jans-auth.war')) or '-uninstall' in sys.argv: + import install + install.setup_dir = dir_path + if '-uninstall' in sys.argv: + install.uninstall_jans() + sys.exit() else: - arg = group.add_argument(*action.option_strings) - - arg.option_strings = action.option_strings - arg.default = action.default - arg.help = action.help - arg.choices = action.choices - arg.required = False - arg.type = action.type - -argsp = arg_parser.parser.parse_known_args()[0] + print("Downloading Files") + install.download_files() + install.extract_yaml_files() + install.prepare_jans_cli_package() -if not (os.path.exists('/opt/dist/jans/jans.zip') or os.path.exists('/opt/dist/jans/jans-auth.war')) or '-uninstall' in sys.argv or argsp.force_download: +os.environ['LC_ALL'] = 'C' +from setup_app.utils.arg_parser import arg_parser - install.app_globals.argsp = argsp - install.setup_dir = dir_path - install.init_installer() +argsp = arg_parser() # first import paths and make changes if necassary from setup_app import paths @@ -142,180 +128,166 @@ def ami_packaged(): if not os.path.exists(Config.outputFolder): os.makedirs(Config.outputFolder) +# initialize config object +Config.init(paths.INSTALL_DIR) +Config.determine_version() -def main(): +base.profile = Config.profile +if Config.profile != 'jans': + argsp.t = False - if '-uninstall' in sys.argv: - install.uninstall_jans() - sys.exit() - elif not os.path.exists('/opt/dist/jans/jans-auth.war'): - print("Downloading Files") - install.download_files() - install.extract_yaml_files() - install.prepare_jans_cli_package() - if argsp.profile != 'jans': - install.profile_setup() - elif not argsp.no_gcs: - install.download_gcs() +# we must initilize SetupUtils after initilizing Config +SetupUtils.init() - # initialize config object - Config.init(paths.INSTALL_DIR) - Config.determine_version() +# get setup options from args +setupOptions = get_setup_options() - base.profile = Config.profile - if Config.profile != 'jans': - argsp.t = False +terminal_size = shutil.get_terminal_size() +tty_rows = terminal_size.lines +tty_columns = terminal_size.columns - # we must initilize SetupUtils after initilizing Config - SetupUtils.init() +# check if we are running in terminal +try: + os.get_terminal_size() +except: + argsp.no_progress = True - # get setup options from args - setupOptions = get_setup_options() +if not argsp.n: + base.check_resources() - terminal_size = shutil.get_terminal_size() - tty_rows = terminal_size.lines - tty_columns = terminal_size.columns +# pass progress indicator to Config object +Config.pbar = jansProgress - # check if we are running in terminal - try: - os.get_terminal_size() - except: - argsp.no_progress = True - - if not argsp.n: - base.check_resources() - - # pass progress indicator to Config object - Config.pbar = jansProgress - - for key in setupOptions: - setattr(Config, key, setupOptions[key]) - - jansInstaller = JansInstaller() - jansInstaller.initialize() - - print() - detected_os = '{} {}'.format(base.os_type, base.os_version) - if base.snap: - detected_os = 'snap ' + detected_os - print("Installing Janssen Server...\n\nFor more info see:\n {} \n {}\n".format(paths.LOG_FILE, paths.LOG_ERROR_FILE)) - print("Profile : {}".format(Config.profile)) - print("Detected OS : {}".format(detected_os)) - print("Janssen Version : {}".format(Config.oxVersion)) - print("Detected init : {}".format(base.os_initdaemon)) - print("Detected Apache : {}".format(base.determineApacheVersion())) - print() - - setup_loaded = {} - if setupOptions['setup_properties']: - base.logIt('%s Properties found!\n' % setupOptions['setup_properties']) - setup_loaded = propertiesUtils.load_properties(setupOptions['setup_properties']) - elif os.path.isfile(Config.setup_properties_fn): - base.logIt('%s Properties found!\n' % Config.setup_properties_fn) - setup_loaded = propertiesUtils.load_properties(Config.setup_properties_fn) - elif os.path.isfile(Config.setup_properties_fn + '.enc'): - base.logIt('%s Properties found!\n' % Config.setup_properties_fn + '.enc') - setup_loaded = propertiesUtils.load_properties(Config.setup_properties_fn + '.enc') - - if argsp.import_ldif: - if os.path.isdir(argsp.import_ldif): - base.logIt("Found setup LDIF import directory {}".format(argsp.import_ldif)) - else: - base.logIt("The custom LDIF import directory {} does not exist. Exiting...".format(argsp.import_ldif, True, True)) - - collectProperties = CollectProperties() - if os.path.exists(Config.jans_properties_fn): - collectProperties.collect() - collectProperties.save() - Config.installed_instance = True +for key in setupOptions: + setattr(Config, key, setupOptions[key]) - if argsp.csx: - print("Saving collected properties") - collectProperties.save() - sys.exit() +jansInstaller = JansInstaller() +jansInstaller.initialize() - if not Config.noPrompt and not Config.installed_instance and not setup_loaded: - propertiesUtils.promptForProperties() +print() +detected_os = '{} {}'.format(base.os_type, base.os_version) +if base.snap: + detected_os = 'snap ' + detected_os +print("Installing Janssen Server...\n\nFor more info see:\n {} \n {}\n".format(paths.LOG_FILE, paths.LOG_ERROR_FILE)) +print("Profile : {}".format(Config.profile)) +print("Detected OS : {}".format(detected_os)) +print("Janssen Version : {}".format(Config.oxVersion)) +print("Detected init : {}".format(base.os_initdaemon)) +print("Detected Apache : {}".format(base.determineApacheVersion())) +print() + +setup_loaded = {} +if setupOptions['setup_properties']: + base.logIt('%s Properties found!\n' % setupOptions['setup_properties']) + setup_loaded = propertiesUtils.load_properties(setupOptions['setup_properties']) +elif os.path.isfile(Config.setup_properties_fn): + base.logIt('%s Properties found!\n' % Config.setup_properties_fn) + setup_loaded = propertiesUtils.load_properties(Config.setup_properties_fn) +elif os.path.isfile(Config.setup_properties_fn + '.enc'): + base.logIt('%s Properties found!\n' % Config.setup_properties_fn + '.enc') + setup_loaded = propertiesUtils.load_properties(Config.setup_properties_fn + '.enc') + +if argsp.import_ldif: + if os.path.isdir(argsp.import_ldif): + base.logIt("Found setup LDIF import directory {}".format(argsp.import_ldif)) + else: + base.logIt("The custom LDIF import directory {} does not exist. Exiting...".format(argsp.import_ldif, True, True)) - propertiesUtils.check_properties() - # initialize installers, order is important! - jreInstaller = JreInstaller() - jettyInstaller = JettyInstaller() - jythonInstaller = JythonInstaller() +collectProperties = CollectProperties() +if os.path.exists(Config.jans_properties_fn): + collectProperties.collect() + collectProperties.save() + Config.installed_instance = True - if Config.profile == 'jans': - openDjInstaller = OpenDjInstaller() - couchbaseInstaller = CouchbaseInstaller() + if argsp.csx: + print("Saving collected properties") + collectProperties.save() + sys.exit() - rdbmInstaller = RDBMInstaller() - httpdinstaller = HttpdInstaller() - jansAuthInstaller = JansAuthInstaller() - configApiInstaller = ConfigApiInstaller() +if not Config.noPrompt and not Config.installed_instance and not setup_loaded: + propertiesUtils.promptForProperties() - if Config.profile == 'jans': - fidoInstaller = FidoInstaller() - scimInstaller = ScimInstaller() - elevenInstaller = ElevenInstaller() +propertiesUtils.check_properties() +# initialize installers, order is important! +jreInstaller = JreInstaller() +jettyInstaller = JettyInstaller() +jythonInstaller = JythonInstaller() - jansCliInstaller = JansCliInstaller() +if Config.profile == 'jans': + openDjInstaller = OpenDjInstaller() + couchbaseInstaller = CouchbaseInstaller() - # oxdInstaller = OxdInstaller() +rdbmInstaller = RDBMInstaller() +httpdinstaller = HttpdInstaller() +jansAuthInstaller = JansAuthInstaller() +configApiInstaller = ConfigApiInstaller() - rdbmInstaller.packageUtils = packageUtils +if Config.profile == 'jans': + fidoInstaller = FidoInstaller() + scimInstaller = ScimInstaller() + elevenInstaller = ElevenInstaller() - if Config.installed_instance: - for service in jansProgress.services: - setattr(Config, service['object'].install_var, service['object'].installed()) +jansCliInstaller = JansCliInstaller() - if not argsp.shell: - propertiesUtils.promptForProperties() +# oxdInstaller = OxdInstaller() - if not (argsp.t or argsp.x) and not Config.addPostSetupService: - print("No service was selected to install. Exiting ...") - sys.exit() +rdbmInstaller.packageUtils = packageUtils - def print_or_log(msg): - print(msg) if argsp.x else base.logIt(msg) +if Config.installed_instance: + for service in jansProgress.services: + setattr(Config, service['object'].install_var, service['object'].installed()) + if not argsp.shell: + propertiesUtils.promptForProperties() - if Config.profile == 'jans': - if argsp.t: - testDataLoader = TestDataLoader() + if not (argsp.t or argsp.x) and not Config.addPostSetupService: + print("No service was selected to install. Exiting ...") + sys.exit() - if argsp.t and argsp.x: - print_or_log("Loading test data") - testDataLoader.dbUtils.bind() - testDataLoader.createLdapPw() - configApiInstaller.load_test_data() - testDataLoader.load_test_data() - testDataLoader.deleteLdapPw() - print_or_log("Test data loaded.") +def print_or_log(msg): + print(msg) if argsp.x else base.logIt(msg) - if not argsp.t and argsp.x and argsp.load_config_api_test: - print_or_log("Loading Config Api Test data") - configApiInstaller.load_test_data() - print_or_log("Test data loaded. Exiting ...") - if argsp.x: - print("Exiting ...") - sys.exit() +if Config.profile == 'jans': + if argsp.t: + testDataLoader = TestDataLoader() + + if argsp.t and argsp.x: + print_or_log("Loading test data") + testDataLoader.dbUtils.bind() + testDataLoader.createLdapPw() + configApiInstaller.load_test_data() + testDataLoader.load_test_data() + testDataLoader.deleteLdapPw() + print_or_log("Test data loaded.") + + if not argsp.t and argsp.x and argsp.load_config_api_test: + print_or_log("Loading Config Api Test data") + configApiInstaller.load_test_data() + print_or_log("Test data loaded. Exiting ...") + + if argsp.x: + print("Exiting ...") + sys.exit() - Config.installJansCli = Config.installConfigApi or Config.installScimServer +Config.installJansCli = Config.installConfigApi or Config.installScimServer - app_vars = locals().copy() +app_vars = locals().copy() - if argsp.shell: - code.interact(local=locals()) - sys.exit() +if argsp.shell: + code.interact(local=locals()) + sys.exit() - if Config.profile == 'jans': - # re-calculate memory usage - Config.calculate_mem() +if Config.profile == 'jans': + # re-calculate memory usage + Config.calculate_mem() - print() - print(jansInstaller) +print() +print(jansInstaller) - base.current_app.proceed_installation = True +base.current_app.proceed_installation = True + +def main(): if not Config.noPrompt: proceed_prompt = input('Proceed with these values [Y|n] ').lower().strip() diff --git a/jans-linux-setup/jans_setup/setup_app/messages.py b/jans-linux-setup/jans_setup/setup_app/messages.py index 072eb73ecaf..abb3a962f70 100644 --- a/jans-linux-setup/jans_setup/setup_app/messages.py +++ b/jans-linux-setup/jans_setup/setup_app/messages.py @@ -24,7 +24,7 @@ class msg: password_label = "Password" hosts_label = "Hosts" username_label = "Username" - + installOxAuth_label = "Install OxAuth" installOxTrust_label = "Install OxTrust" backend_types_label = "Backend Types" @@ -40,13 +40,13 @@ class msg: installCasa_label = "Install Casa" installScimServer_label = "Install Scim" installFido2_label = "Install Fido2" - + insufficient_free_disk_space = "Available free disk space was determined to be {1:0.1f} GB. This is less than the required disk space of {} GB." insufficient_mem_size = "RAM size was determined to be {:0.1f} GB. This is less than the suggested RAM size of {} GB" insufficient_number_of_cpu = "Available CPU Units found was {}. This is less than the required amount of {} CPU Units" insufficient_file_max = "Maximum number of files that can be opened on this computer is {}. Please increase number of file-max to {} on the host system and re-run setup.py" insufficient_free_disk_space = "Available free disk space was determined to be {} GB. This is less than the required disk space of {}" - + suggested_free_disk_space = 40 #in GB suggested_number_of_cpu = 2 suggested_file_max = 64000 @@ -83,7 +83,6 @@ class msg: ask_installScimServer = "Install Scim Server" ask_installFido2 = "Install Fido2" - opendj_install_options = ["Don't Install","Install Locally","Use Remote OpenDJ"] oxd_url_label = "oxd Server URL" install_oxd_or_url_warning = "Please either enter oxd Server URL or check Install Oxd" @@ -125,9 +124,10 @@ class msg: installation_description_casa = "Janssen Casa is a self-service web portal for end-users to manage authentication and authorization preferences for their account in a Janssen Server." installation_description_scim = "The Janssen Server implements SCIM to offer standard REST APIs for performing CRUD operations (create, read, update and delete) against user data." installation_description_fido2 = "FIDO 2.0 (FIDO2) is an open authentication standard that enables people to leverage common devices to authenticate to online services in both mobile and desktop environments" - + installation_description_scripts = "Interception scripts can be used to implement custom business logic for authentication, authorization and more in a way that is upgrade-proof and doesn't require forking the Janssen Server code." - - + installation_error = "The following error occurred while installing Janssen Server:" exit_post_setup = "No service was selected to install. Exit now?" + + used_ports = "Port(s) {} should be free to continue. Please check." diff --git a/jans-linux-setup/jans_setup/setup_app/utils/properties_utils.py b/jans-linux-setup/jans_setup/setup_app/utils/properties_utils.py index 1471b2583f1..2c24e03ee1e 100644 --- a/jans-linux-setup/jans_setup/setup_app/utils/properties_utils.py +++ b/jans-linux-setup/jans_setup/setup_app/utils/properties_utils.py @@ -12,6 +12,7 @@ import ldap3 from setup_app import paths +from setup_app.messages import msg from setup_app.utils import base from setup_app.utils.cbm import CBM from setup_app.static import InstallTypes, colors @@ -121,6 +122,12 @@ def check_properties(self): if Config.rdbm_install: Config.mappingLocations = { group: 'rdbm' for group in Config.couchbaseBucketDict } + if Config.opendj_install == InstallTypes.LOCAL: + used_ports = self.opendj_used_ports() + if used_ports: + print(msg.used_ports.format(','.join(used_ports))) + sys.exit(1) + self.set_persistence_type() if not Config.opendj_p12_pass: @@ -654,6 +661,12 @@ def prompt_for_backend(self): else: choice = n + if choice == 1: + used_ports = self.opendj_used_ports() + if used_ports: + print(colors.DANGER, msg.used_ports.format(','.join(used_ports)), colors.ENDC) + choice = None + if choice: break diff --git a/jans-linux-setup/jans_setup/setup_app/utils/setup_utils.py b/jans-linux-setup/jans_setup/setup_app/utils/setup_utils.py index 27d8d2692ac..6963ca345c5 100644 --- a/jans-linux-setup/jans_setup/setup_app/utils/setup_utils.py +++ b/jans-linux-setup/jans_setup/setup_app/utils/setup_utils.py @@ -565,3 +565,18 @@ def add_yacron_job(self, command, schedule, name=None, args={}): yml_str = ruamel.yaml.dump(yacron_yaml, Dumper=ruamel.yaml.RoundTripDumper) self.writeFile(yacron_yaml_fn, yml_str) + + + def port_used(self, port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + result = sock.connect_ex(('127.0.0.1', int(port))) + ret_val = result == 0 + sock.close() + return ret_val + + def opendj_used_ports(self): + ports = [] + for port in (Config.ldaps_port, Config.ldap_admin_port): + if self.port_used(port): + ports.append(port) + return ports