From 86fb93d60393930f8b340cc97e51ed2fce2bb9fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Sedl=C3=A1=C5=99?= Date: Wed, 6 Mar 2019 10:12:43 +0100 Subject: [PATCH] orchestrator: Support getting kerberos ticket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the configuration sets keytab path and principal, run kinit with custom cache file, and delete the file at the end of the run. JIRA: COMPOSE-3288 Signed-off-by: Lubomír Sedlář --- doc/multi_compose.rst | 8 ++++++++ pungi_utils/orchestrator.py | 24 +++++++++++++++++++++++- tests/test_orchestrator.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/doc/multi_compose.rst b/doc/multi_compose.rst index 8848ad6b..dcc35b1a 100644 --- a/doc/multi_compose.rst +++ b/doc/multi_compose.rst @@ -39,6 +39,14 @@ General settings If specified, a current event will be retrieved from the Koji instance and used for all parts. +**kerberos** + If set to yes, a kerberos ticket will be automatically created at the start. + Set keytab and principal as well. +**kerberos_keytab** + Path to keytab file used to create the kerberos ticket. +**kerberos_principal** + Kerberos principal for the ticket + Partial compose settings ------------------------ diff --git a/pungi_utils/orchestrator.py b/pungi_utils/orchestrator.py index 6940014f..4a439862 100644 --- a/pungi_utils/orchestrator.py +++ b/pungi_utils/orchestrator.py @@ -3,6 +3,7 @@ from __future__ import print_function import argparse +import atexit import errno import json import logging @@ -11,11 +12,13 @@ import re import shutil import subprocess import sys +import tempfile from collections import namedtuple import kobo.conf import kobo.log import productmd +from kobo import shortcuts from six.moves import configparser, shlex_quote from pungi.compose import get_compose_dir @@ -465,14 +468,33 @@ def setup_for_restart(global_config, parts, to_restart): raise RuntimeError("All restarted parts are blocked. Nothing to do.") +def run_kinit(config): + if not config.getboolean("general", "kerberos"): + return + + keytab = config.get("general", "kerberos_keytab") + principal = config.get("general", "kerberos_principal") + + fd, fname = tempfile.mkstemp(prefix="krb5cc_pungi-orchestrate_") + os.close(fd) + os.environ["KRB5CCNAME"] = fname + shortcuts.run(["kinit", "-k", "-t", keytab, principal]) + log.debug("Created a kerberos ticket for %s", principal) + + atexit.register(os.remove, fname) + + def run(work_dir, main_config_file, args): config_dir = os.path.join(work_dir, "config") shutil.copytree(os.path.dirname(main_config_file), config_dir) # Read main config - parser = configparser.RawConfigParser() + parser = configparser.RawConfigParser(defaults={"kerberos": "false"}) parser.read(main_config_file) + # Create kerberos ticket + run_kinit(parser) + compose_info = dict(parser.items("general")) compose_type = parser.get("general", "compose_type") diff --git a/tests/test_orchestrator.py b/tests/test_orchestrator.py index 79d5f293..cbdcc1a6 100644 --- a/tests/test_orchestrator.py +++ b/tests/test_orchestrator.py @@ -804,3 +804,32 @@ class TestSetupForRestart(BaseTestCase): self.assertEqual(parts["p1"].path, "/p1") self.assertEqual(parts["p2"].status, "WAITING") self.assertEqual(parts["p2"].path, None) + + +@mock.patch("atexit.register") +@mock.patch("kobo.shortcuts.run") +class TestRunKinit(BaseTestCase): + def test_without_config(self, run, register): + conf = mock.Mock() + conf.getboolean.return_value = False + + o.run_kinit(conf) + + self.assertEqual(run.call_args_list, []) + self.assertEqual(register.call_args_list, []) + + @mock.patch.dict("os.environ") + def test_with_config(self, run, register): + conf = mock.Mock() + conf.getboolean.return_value = True + conf.get.side_effect = lambda section, option: option + + o.run_kinit(conf) + + self.assertEqual( + run.call_args_list, + [mock.call(["kinit", "-k", "-t", "kerberos_keytab", "kerberos_principal"])], + ) + self.assertEqual( + register.call_args_list, [mock.call(os.remove, os.environ["KRB5CCNAME"])] + )