Skip to content

Commit

Permalink
feat(jans-linux-setup): keycloak scheduler service (#8425)
Browse files Browse the repository at this point in the history
* feat(jans-linux-setup): keycloak scheduler service

Signed-off-by: Mustafa Baser <mbaser@mail.com>

* feat(jans-linux-setup): set email for kc jans user

Signed-off-by: Mustafa Baser <mbaser@mail.com>

* fix(jans-linux-setup): copy kc-jans-scheduler.jar to lib dir

Signed-off-by: Mustafa Baser <mbaser@mail.com>

* feat(jans-linux-setup): remove kc-jans-scheduler upon uninstall

Signed-off-by: Mustafa Baser <mbaser@mail.com>

* chore(jans-linux-setup): extract kc-scheduler config files from main repository

Signed-off-by: Mustafa Baser <mbaser@mail.com>

* chore(jans-linux-setup): verbose file extraction from zip

Signed-off-by: Mustafa Baser <mbaser@mail.com>

* fix(jans-linux-setup): kc-scheduler start file

Signed-off-by: Mustafa Baser <mbaser@mail.com>

---------

Signed-off-by: Mustafa Baser <mbaser@mail.com>
  • Loading branch information
devrimyatar committed May 6, 2024
1 parent 5e2fa72 commit 89c799c
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 9 deletions.
5 changes: 4 additions & 1 deletion jans-linux-setup/jans_setup/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ def uninstall_jans():
if os.path.exists('/opt/opa'):
service_list.append('opa')

if os.path.exists('/opt/kc-scheduler'):
service_list.append('kc-scheduler')

for service in service_list:

print("Stopping", service)
Expand All @@ -249,7 +252,7 @@ def uninstall_jans():
os.system('systemctl daemon-reload')
os.system('systemctl reset-failed')

remove_list = ['/etc/certs', '/etc/jans', '/opt/amazon-corretto*', '/opt/jre', '/opt/node*', '/opt/jetty*', '/opt/jython*', '/opt/keycloak', '/opt/idp', '/opt/opa']
remove_list = ['/etc/certs', '/etc/jans', '/opt/amazon-corretto*', '/opt/jre', '/opt/node*', '/opt/jetty*', '/opt/jython*', '/opt/keycloak', '/opt/idp', '/opt/opa', '/opt/kc-scheduler']
if argsp.profile == 'jans':
remove_list.append('/opt/opendj')
if not argsp.keep_downloads:
Expand Down
6 changes: 4 additions & 2 deletions jans-linux-setup/jans_setup/setup_app/installers/jans.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ def initialize(self):
jansProgress.register(self)

Config.install_time_ldap = time.strftime('%Y%m%d%H%M%SZ', time.gmtime(time.time()))
Config.jans_version = base.current_app.app_info['JANS_APP_VERSION']

if not os.path.exists(Config.distFolder):
print("Please ensure that you are running this script inside Jans container.")
sys.exit(1)
Expand Down Expand Up @@ -570,8 +572,7 @@ def secure_files(self):
self.run([paths.cmd_chmod, '640', p.as_posix()])

if not Config.installed_instance:
cron_service = 'crond' if base.os_type in ['centos', 'red', 'fedora'] else 'cron'
self.restart(cron_service)
self.restart(base.cron_service)

# if we are running inside shiv package, copy site pacakages to /opt/dist/jans-setup-packages and add to sys path

Expand Down Expand Up @@ -654,6 +655,7 @@ def order_services(self):
('opa', 'install_opa'),
('saml', 'install_jans_saml'),
('jans-keycloak-link', 'install_jans_keycloak_link'),
('kc-scheduler', 'install_jans_saml'),
]
service_listr = service_list[:]
service_listr.reverse()
Expand Down
72 changes: 68 additions & 4 deletions jans-linux-setup/jans_setup/setup_app/installers/jans_saml.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class JansSamlInstaller(JettyInstaller):
(os.path.join(Config.dist_jans_dir, 'kc-jans-authn-plugin.jar'), os.path.join(base.current_app.app_info['JANS_MAVEN'], 'maven/io/jans/kc-jans-authn-plugin/{0}/kc-jans-authn-plugin-{0}.jar').format(base.current_app.app_info['jans_version'])),
(os.path.join(Config.dist_jans_dir, 'kc-jans-authn-plugin-deps.zip'), os.path.join(base.current_app.app_info['JANS_MAVEN'], 'maven/io/jans/kc-jans-authn-plugin/{0}/kc-jans-authn-plugin-{0}-deps.zip').format(base.current_app.app_info['jans_version'])),
(os.path.join(Config.dist_jans_dir, 'kc-saml-plugin.jar'), os.path.join(base.current_app.app_info['JANS_MAVEN'], 'maven/io/jans/jans-config-api/plugins/kc-saml-plugin/{0}/kc-saml-plugin-{0}-distribution.jar').format(base.current_app.app_info['jans_version'])),
(os.path.join(Config.dist_jans_dir, 'kc-jans-scheduler-deps.zip'), os.path.join(base.current_app.app_info['JANS_MAVEN'], 'maven/io/jans/kc-jans-scheduler/{0}/kc-jans-scheduler-{0}-deps.zip').format(base.current_app.app_info['jans_version'])),
(os.path.join(Config.dist_jans_dir, 'kc-jans-scheduler.jar'), os.path.join(base.current_app.app_info['JANS_MAVEN'], 'maven/io/jans/kc-jans-scheduler/{0}/kc-jans-scheduler-{0}.jar').format(base.current_app.app_info['jans_version'])),
]

def __init__(self):
Expand Down Expand Up @@ -75,15 +77,19 @@ def __init__(self):
Config.jans_idp_sp_metadata_root_dir = os.path.join(self.idp_config_root_dir, 'sp/metadata')
Config.jans_idp_sp_metadata_temp_dir = os.path.join(self.idp_config_root_dir, 'sp/temp_metadata')

Config.scheduler_dir = os.path.join(Config.opt_dir, 'kc-scheduler')

Config.idp_config_hostname = Config.hostname
Config.keycloack_hostname = Config.hostname

self.kc_admin_realm = 'master'
self.kc_admin_username = 'admin'

def install(self):
"""installation steps"""
self.create_clients()
self.install_keycloack()

self.install_keycloak_scheduler()

def render_import_templates(self):
self.logIt("Preparing base64 encodings configuration files")
Expand Down Expand Up @@ -212,12 +218,12 @@ def config_api_idp_plugin_config(self):

with tempfile.TemporaryDirectory() as tmp_dir:
kc_tmp_config = os.path.join(tmp_dir, 'kcadm-jans.config')
self.run([kcadm_cmd, 'config', 'credentials', '--server', kcm_server_url, '--realm', 'master', '--user', 'admin', '--password', 'admin', '--config', kc_tmp_config], env=env)
self.run([kcadm_cmd, 'config', 'credentials', '--server', kcm_server_url, '--realm', self.kc_admin_realm, '--user', self.kc_admin_username, '--password', 'admin', '--config', kc_tmp_config], env=env)

self.run([kcadm_cmd, 'config', 'credentials', '--server', kcm_server_url, '--realm', 'master', '--user', 'admin', '--password', Config.admin_password, '--config', kc_tmp_config], env=env)
self.run([kcadm_cmd, 'config', 'credentials', '--server', kcm_server_url, '--realm', self.kc_admin_realm, '--user', self.kc_admin_username, '--password', Config.admin_password, '--config', kc_tmp_config], env=env)

# Change default password
self.run([kcadm_cmd, 'set-password', '-r', 'master', '--username', 'admin', '--new-password', Config.admin_password, '--config', kc_tmp_config], env=env)
self.run([kcadm_cmd, 'set-password', '-r', self.kc_admin_realm, '--username', self.kc_admin_username, '--new-password', Config.admin_password, '--config', kc_tmp_config], env=env)

# create realm
self.run([kcadm_cmd, 'create', 'realms', '-f', os.path.join(jans_api_output_dir, jans_api_realm_fn),'--config', kc_tmp_config], env=env)
Expand Down Expand Up @@ -253,3 +259,61 @@ def config_api_idp_plugin_config(self):

# create userstorage provider component
self.run([kcadm_cmd, 'create', 'components', '-r', Config.jans_idp_realm, '-f', os.path.join(jans_api_output_dir, jans_userstorage_provider_component_fn), '--config', kc_tmp_config], env=env)

def install_keycloak_scheduler(self):

scheduler_templates_dir = os.path.join(self.templates_folder, 'kc-scheduler')

# create directories
for _ in ('bin', 'conf', 'lib', 'logs'):
self.createDirs(os.path.join(Config.scheduler_dir, _))

#unpack libs
base.unpack_zip(self.source_files[7][0], os.path.join(Config.scheduler_dir, 'lib'))
for s_config in ('config.properties', 'logback.xml'):
base.extract_file(base.current_app.jans_zip, f'jans-keycloak-integration/job-scheduler/src/main/resources/{s_config}.sample', os.path.join(Config.scheduler_dir, 'conf'))
os.rename(os.path.join(Config.scheduler_dir, 'conf', f'{s_config}.sample'), os.path.join(Config.scheduler_dir, 'conf', s_config))

self.copyFile(self.source_files[8][0], os.path.join(Config.scheduler_dir, 'lib'))

# configuration rendering identifiers
_, jans_auth_config = self.dbUtils.get_oxAuthConfDynamic()
self.check_clients([('kc_scheduler_api_client_id', '2102.')])

rendering_dict = {
'api_url': f'https://{Config.hostname}/jans-config-api',
'token_endpoint': jans_auth_config['tokenEndpoint'],
'client_id': Config.kc_scheduler_api_client_id,
'client_secret': Config.kc_scheduler_api_client_pw,
'scopes': '',
'auth_method': 'basic',
'keycloak_admin_url': f'https://{Config.idp_config_hostname}/kc',
'keycloak_admin_realm': self.kc_admin_realm,
'keycloak_admin_username': self.kc_admin_username,
'keycloak_admin_password': Config.admin_password,
'keycloak_client_id': 'admin-cli',
}

config_properties_fn = os.path.join(Config.scheduler_dir, 'conf','config.properties')
config_properties_s = self.render_template(config_properties_fn, pystring=True, rendering_dict=rendering_dict)
self.writeFile(config_properties_fn, config_properties_s, backup=False)
self.chown(Config.scheduler_dir, Config.jetty_user, Config.jetty_group, recursive=True)

# render start script
self.renderTemplateInOut(
os.path.join(scheduler_templates_dir, 'kc-scheduler.sh'),
scheduler_templates_dir,
os.path.join(Config.scheduler_dir, 'bin')
)

self.run([paths.cmd_chmod, '+x', os.path.join(Config.scheduler_dir, 'bin/kc-scheduler.sh')])

# render contab entry and restart cron service
self.renderTemplateInOut(
os.path.join(scheduler_templates_dir, 'kc-scheduler-cron'),
scheduler_templates_dir,
'/etc/cron.d'
)

if not Config.installed_instance:
self.restart(base.cron_service)
3 changes: 3 additions & 0 deletions jans-linux-setup/jans_setup/setup_app/utils/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@

os_name = os_type + os_version
deb_sysd_clone = os_name.startswith(('ubuntu', 'debian'))
cron_service = 'crond' if os_type in ['centos', 'red', 'fedora'] else 'cron'


# Determine service path
if (os_type in ('centos', 'red', 'fedora', 'suse') and os_initdaemon == 'systemd') or deb_sysd_clone:
Expand Down Expand Up @@ -373,6 +375,7 @@ def extract_file(zip_file, source, target, ren=False):
target_p = Path(target).joinpath(p.name)
if not target_p.parent.exists():
target_p.parent.mkdir(parents=True)
logIt(f"Extracting {source} from {zip_file} to {target}")
target_p.write_bytes(zip_obj.read(member))
break
zip_obj.close()
Expand Down
4 changes: 3 additions & 1 deletion jans-linux-setup/jans_setup/setup_app/utils/setup_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,9 +493,11 @@ def in_ignoredirs(p):
self.logIt("Writing rendered template {}".format(full_output_file))
full_output_file.write_text(rendered_text)

def render_template(self, tmp_fn, pystring=False):
def render_template(self, tmp_fn, pystring=False, rendering_dict=None):
template_text = self.readFile(tmp_fn)
format_dict = self.merge_dicts(Config.__dict__, Config.templateRenderingDict)
if rendering_dict:
format_dict = self.merge_dicts(format_dict, rendering_dict)
for k in format_dict:
if isinstance(format_dict[k], bool):
format_dict[k] = str(format_dict[k]).lower()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Unit]
Description=Keycloak Scheduler Service
After=kc.service

[Service]
Type=simple
Environment="JAVA_HOME=%(jre_home)s"
Environment="SCHEDULER_HOME=%(scheduler_dir)s"
Environment="SCHEDULER_VERSION=v%(jans_version)s"
ExecStart=%(scheduler_dir)s/bin/kc-scheduler.sh
User=%(jetty_user)s
Group=%(jetty_group)s

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/10 * * * * %(jetty_user)s %(scheduler_dir)s/bin/kc-scheduler.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#! /bin/bash

JAVA_HOME=%(jre_home)s
SCHEDULER_HOME=%(scheduler_dir)s
SCHEDULER_VERSION=v%(jans_version)s

APP_CONFIG_FILE=${SCHEDULER_HOME}/conf/config.properties
LOG_CONFIG_FILE=${SCHEDULER_HOME}/conf/logback.xml

if [ -z "$JAVA" ]; then
if [ -n "$JAVA_HOME" ]; then
JAVA="$JAVA_HOME/bin/java"
else
JAVA="java"
fi
fi

$JAVA -Dapp.config="${APP_CONFIG_FILE}" \
-Dlogback.configurationFile="${SCHEDULER_HOME}/conf/logback.xml" \
-Dapp.version=${SCHEDULER_VERSION} -Dapp.home="${SCHEDULER_HOME}" \
-cp "${SCHEDULER_HOME}/lib/*" io.jans.kc.scheduler.App
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"username": "${jans_idp_user_name}",
"firstName": "Jans",
"lastName": "API User",
"email": "${admin_email}",
"emailVerified": true,
"attributes": [],
"enabled": true
}
}

0 comments on commit 89c799c

Please sign in to comment.