Skip to content

Commit 24fa16e

Browse files
authored
Add support of IPA client
Add support of IPA client A lot of work is done in the setup of the environment, support of IPA clients (used for testing as Kerberos users). Most of Bash scripts are replaced with python code. Add unit tests.
2 parents d1457b7 + 5584856 commit 24fa16e

25 files changed

+2271
-989
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,4 +269,9 @@ src/env/keys*
269269
.idea/
270270
.vscode/
271271
src/env/krb-server-client-setup-rhel8.sh
272-
src/env/conf*
272+
*.yml
273+
*.yaml
274+
/src/.env
275+
/conf/*
276+
*original*
277+
*backup*

__init__.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
1-
import logging
2-
from sys import stdout
1+
import colorlog
32

4-
5-
handler = logging.StreamHandler(stdout)
6-
handler.setLevel(logging.DEBUG)
7-
8-
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt="%H:%M:%S")
3+
handler = colorlog.StreamHandler()
4+
formatter = colorlog.ColoredFormatter(
5+
'%(log_color)s%(module)s.%(funcName)s.%(lineno)d [%(levelname)s] %(message)s',
6+
log_colors={
7+
'DEBUG': 'cyan',
8+
'INFO': 'green',
9+
'WARNING': 'yellow',
10+
'ERROR': 'red',
11+
'CRITICAL': 'red,bg_white'})
912
handler.setFormatter(formatter)
1013

1114
# Basic logger
12-
log = logging.getLogger("base")
13-
log.setLevel(logging.DEBUG)
14-
15-
log.addHandler(handler)
15+
base_logger = colorlog.getLogger("base")
16+
base_logger.addHandler(handler)
17+
base_logger.setLevel(colorlog.DEBUG)
1618

1719
# Logger for environment events
18-
env_logger = logging.getLogger("env")
19-
env_logger.setLevel(logging.DEBUG)
20-
20+
env_logger = colorlog.getLogger("env")
2121
env_logger.addHandler(handler)
22+
env_logger.setLevel(colorlog.DEBUG)
23+
24+
25+
def hello():
26+
print("Hello. Just check that SCAutolib is imported")

src/__init__.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from os.path import (dirname, abspath, join)
2+
3+
import yaml
4+
from SCAutolib import env_logger
5+
from decouple import config
6+
7+
DIR_PATH = dirname(abspath(__file__))
8+
SETUP_IPA_SERVER = f"{DIR_PATH}/env/ipa-install-server.sh"
9+
10+
11+
def load_env(conf_file: str) -> str:
12+
"""
13+
Create .env near source files of the library. In .env file following
14+
variables expected to be present: CA_DIR, TMP, KEYS, CERTS, BACKUP.
15+
Deployment process would relay on this variables.
16+
17+
Args:
18+
conf_file: path to YAML configuration fil
19+
Returns:
20+
Path to .env file.
21+
"""
22+
23+
env_file = f"{DIR_PATH}/.env"
24+
with open(conf_file, "r") as f:
25+
env_logger.debug(f"Reading configurations from {conf_file}")
26+
data = yaml.load(f, Loader=yaml.FullLoader)
27+
ca_dir = data["ca_dir"]
28+
data["restore"] = []
29+
30+
with open(conf_file, "w") as f:
31+
yaml.dump(data, f)
32+
env_logger.debug("restore section is added to te configuration file")
33+
34+
with open(env_file, "w") as f:
35+
f.write(f"TMP={join(ca_dir, 'tmp')}\n")
36+
f.write(f"KEYS={join(ca_dir, 'tmp', 'keys')}\n")
37+
f.write(f"CERTS={join(ca_dir, 'tmp', 'certs')}\n")
38+
f.write(f"BACKUP={join(ca_dir, 'tmp', 'backup')}\n")
39+
f.write(f"CONF={abspath(conf_file)}\n")
40+
f.write(f"CA_DIR={ca_dir}\n")
41+
env_logger.debug(f"File {env_file} is created")
42+
return env_file
43+
44+
45+
def read_env(item: str, *args, **kwargs):
46+
"""Just for unifying with read_conf function. Accepts all arguments that
47+
decouple.config() function takes.
48+
Args:
49+
item: variable to read from the .env file
50+
"""
51+
return config(item, *args, **kwargs)
52+
53+
54+
def read_config(*items) -> list or object:
55+
"""
56+
Read data from the configuration file and return require items or full
57+
content.
58+
59+
Args:
60+
items: list of items to extracrt from the configuration file.
61+
If None, full contant would be returned
62+
63+
Returns:
64+
list with required items
65+
"""
66+
try:
67+
with open(read_env("CONF"), "r") as file:
68+
config_data = yaml.load(file, Loader=yaml.FullLoader)
69+
assert config_data, "Data are not loaded correctly."
70+
except FileNotFoundError as e:
71+
env_logger.error(".env file is not present. Try to rerun command"
72+
"with --conf </path/to/conf.yaml> parameter")
73+
raise e
74+
75+
if items is None:
76+
return config_data
77+
78+
return_list = []
79+
for item in items:
80+
parts = item.split(".")
81+
value = config_data
82+
for part in parts:
83+
if value is None:
84+
env_logger.warning(
85+
f"Key {part} not present in the configuration file. Skip.")
86+
return None
87+
88+
value = value.get(part)
89+
if part == parts[-1]:
90+
return_list.append(value)
91+
92+
return return_list if len(items) > 1 else return_list[0]

src/authselect.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
from SCAutolib import log
2-
import subprocess as subp
1+
from subprocess import check_output, PIPE
2+
from traceback import format_exc
3+
4+
from SCAutolib import base_logger
35

46

57
class Authselect:
@@ -38,36 +40,28 @@ def _set(self):
3840
args.append("with-mkhomedir")
3941
args.append("--force")
4042

41-
rc = subp.run(args, stdout=subp.DEVNULL, stderr=subp.STDOUT)
42-
msg = f"Authselect command failed. Return code: {rc.returncode}"
43-
assert rc.returncode == 0, msg
44-
log.debug(f"SSSD is set to: {' '.join(args)}")
45-
log.debug(f"Backupfile: {self.backup_name}")
43+
check_output(args, stderr=PIPE, encoding="utf=8")
44+
base_logger.debug(f"SSSD is set to: {' '.join(args)}")
45+
base_logger.debug(f"Backupfile: {self.backup_name}")
4646

4747
def _reset(self):
4848
"""
4949
Restore the previous configuration of authselect.
5050
"""
51-
rc = subp.run(["authselect", "backup-restore", self.backup_name,
52-
"--debug"], stdout=subp.DEVNULL, stderr=subp.STDOUT)
53-
msg = f"Authselect backup-restore failed. Output: {rc.returncode}"
54-
assert rc.returncode == 0, msg
51+
check_output(["authselect", "backup-restore", self.backup_name,
52+
"--debug"], stderr=PIPE, encoding="utf=8")
5553

56-
rc = subp.run(["authselect", "backup-remove", self.backup_name,
57-
"--debug"], stdout=subp.DEVNULL, stderr=subp.STDOUT)
58-
msg = f"Authselect backup-remove failed. Output: {rc.returncode}"
59-
assert rc.returncode == 0, msg
54+
check_output(["authselect", "backup-remove", self.backup_name,
55+
"--debug"], stderr=PIPE, encoding="utf=8")
6056

61-
log.debug("Authselect backup file is restored")
57+
base_logger.debug("Authselect backup file is restored")
6258

6359
def __enter__(self):
6460
self._set()
6561
return self
6662

6763
def __exit__(self, ext_type, ext_value, ext_traceback):
6864
if ext_type is not None:
69-
log.error("Exception in virtual smart card context")
70-
log.error(f"Exception type: {ext_type}")
71-
log.error(f"Exception value: {ext_value}")
72-
log.error(f"Exception traceback: {ext_traceback}")
65+
base_logger.error("Exception in authselect context")
66+
base_logger.error(format_exc())
7367
self._reset()

0 commit comments

Comments
 (0)