Skip to content

Commit 69c08b3

Browse files
authored
Merge pull request #17 from jessebot/add_debug_logging
adding better, more configurable logging
2 parents 28244b3 + 1cca331 commit 69c08b3

File tree

14 files changed

+541
-202
lines changed

14 files changed

+541
-202
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,3 @@ deps/Brewfile.lock.json
1111
smol_k8s_lab.egg-info/**
1212
dist/**
1313
build/**
14-
poetry.lock

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ There's also full tutorials to manually set up different distros in the [docs we
3232

3333
We tend to test first on k3s and then kind.
3434

35-
We're working on cluster api next :)
35+
We're working on k0s next :)
3636

3737

3838
### Stack We Install on K8s

docs/quickstart.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,39 @@ The help should return this:
4242

4343
[<img src="https://raw.githubusercontent.com/jessebot/smol-k8s-lab/main/docs/screenshots/help_text.svg" alt="Output of smol-k8s-lab --help after cloning the directory and installing the prerequisites.">](https://raw.githubusercontent.com/jessebot/smol-k8s-lab/main/docs/screenshots/help_text.svg)
4444

45-
🔔 Then you *Have To* edit the `config_sample.yml` to be your own values:
45+
🔔 Then you *have to edit* the `~/.config/smol-k8s-lab/config.yaml` to be your own values (for _right now_).
4646

47-
```yaml
48-
---
49-
domains:
50-
argo_cd: "argocd.coolwebsitefordogs.com"
47+
Here's an example file already filled out with comments:
5148

52-
# these HAVE to be full CIDR notation
49+
```yaml
50+
# FQDN to access your web interfaces
51+
domain:
52+
# your base domain for use with subdomains below
53+
base: "coolwebsitefordogs.com"
54+
# subdomain for Argo CD, so this would be argocd.coolwebsitefordogs.com
55+
argo_cd: "argocd"
56+
57+
# metallb IPs used for DNS later (make sure they're not in use)
5358
metallb_address_pool:
59+
# HAVE to be full CIDR notation
5460
- 192.168.90.01/32
55-
- 192.168.90.02/32
56-
- 192.168.90.03/32
5761

58-
62+
# Used for letsencrypt-staging, to generate certs
63+
5964

65+
# Use the external secrets provider with gitlab
6066
external_secrets:
6167
gitlab:
68+
# going to be deprecated soon in favor of using another password manager
69+
# token from here: https://gitlab.com/-/profile/personal_access_tokens
6270
access_token: "kjdfsk758934fkldsafds"
6371
namespace: "nextcloud"
72+
73+
log:
74+
# logging level, Options: debug, info, warn, error
75+
level: "info"
76+
# path of file to log to
77+
file: "./smol-k8s-log.log"
6478
```
6579
6680
## Install a distro of k8s with smol-k8s-lab

docs/screenshots/help_text.svg

Lines changed: 107 additions & 89 deletions
Loading

poetry.lock

Lines changed: 260 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "smol_k8s_lab"
3-
version = "0.9.1"
3+
version = "0.9.2"
44
description = "bootstrap simple projects on kubernetes with kind and k3s"
55
authors = ["Jesse Hitch <[email protected]>"]
66
readme = "README.md"

smol_k8s_lab/__init__.py

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#!/usr/bin/env python3.11
22
"""
3-
AUTHOR: @jessebot email: jessebot(AT)linux(d0t)com
4-
Works with k3s and KinD
3+
NAME: smol-k8s-lab
4+
DESCRIPTION: Works with k3s and KinD
5+
AUTHOR: jessebot(AT)linux(d0t)com
6+
LICENSE: GNU AFFERO GENERAL PUBLIC LICENSE
57
"""
68

79
import bcrypt
8-
from click import option, argument, command
10+
from click import option, argument, command, Choice
911
from collections import OrderedDict
10-
from importlib.metadata import version as get_version
1112
import logging
1213
from os import chmod, getenv, path, remove
1314
from pathlib import Path
@@ -21,20 +22,16 @@
2122
import stat
2223
from sys import exit
2324
from yaml import dump, safe_load
24-
from .console_logging import simple_loading_bar, header, sub_header
25+
from .console_logging import simple_loading_bar, header, sub_header, print_panel
26+
from .env_config import check_os_support, USR_CONFIG_FILE, VERSION
2527
from .bw_cli import BwCLI
2628
from .help_text import RichCommand, options_help
2729
from .homelabHelm import helm
2830
from .subproc import subproc
2931

3032

31-
# for console AND file logging
32-
log_config = {"level": "INFO",
33-
"format": "%(message)s",
34-
"datefmt": "[%X]",
35-
"handlers": [RichHandler()]}
36-
logging.basicConfig(**log_config)
37-
log = logging.getLogger("rich")
33+
from smol_k8s_lab.console_logging import log
34+
3835

3936
# this is for rich text, to pretty print things
4037
soft_theme = Theme({"info": "dim cornflower_blue",
@@ -45,11 +42,11 @@
4542
PWD = path.dirname(__file__)
4643
HOME_DIR = getenv("HOME")
4744
HELP = options_help()
45+
HELP_SETTINGS = dict(help_option_names=['-h', '--help'])
4846

4947

5048
def setup_logger(level="", log_file=""):
5149
"""
52-
TODO: make this work, not working yet
5350
Sets up rich logger and stores the values for it in a db for future import
5451
in other files. Returns logging.getLogger("rich")
5552
"""
@@ -58,7 +55,7 @@ def setup_logger(level="", log_file=""):
5855
if USR_CONFIG_FILE and 'log' in USR_CONFIG_FILE:
5956
level = USR_CONFIG_FILE['log']['level']
6057
else:
61-
level = 'warn'
58+
level = 'info'
6259

6360
log_level = getattr(logging, level.upper(), None)
6461

@@ -81,6 +78,9 @@ def setup_logger(level="", log_file=""):
8178
# log the name of the function if we're in debug mode :)
8279
opts['format'] = "[bold]%(funcName)s()[/bold]: %(message)s"
8380
rich_handler_opts['markup'] = True
81+
else:
82+
rich_handler_opts['show_path'] = False
83+
rich_handler_opts['show_level'] = False
8484

8585
opts['handlers'] = [RichHandler(**rich_handler_opts)]
8686

@@ -122,7 +122,7 @@ def install_k3s_cluster():
122122
# create the k3s cluster (just one server node)
123123
cmd = ('./install.sh --disable=servicelb --disable=traefik '
124124
'--write-kubeconfig-mode=647')
125-
subproc([cmd], False, True, False)
125+
subproc([cmd], spinner=False)
126126

127127
# create the ~/.kube directory if it doesn't exist
128128
Path(f'{HOME_DIR}/.kube').mkdir(exist_ok=True)
@@ -134,7 +134,7 @@ def install_k3s_cluster():
134134
chmod_cmd = f'sudo chmod 644 {HOME_DIR}/.kube/kubeconfig'
135135

136136
# run both commands one after the other
137-
subproc([cp, chmod_cmd], False, True)
137+
subproc([cp, chmod_cmd])
138138

139139
# remove the script after we're done
140140
remove('./install.sh')
@@ -166,7 +166,7 @@ def delete_cluster(k8s_distro="k3s"):
166166
header(f"Bye bye, [b]{k8s_distro}[/b]!")
167167

168168
if k8s_distro == 'k3s':
169-
subproc(['k3s-uninstall.sh'], True, True, False)
169+
subproc(['k3s-uninstall.sh'], error_ok=True, spinner=False)
170170

171171
elif k8s_distro == 'kind':
172172
subproc(['kind delete cluster'])
@@ -279,7 +279,7 @@ def configure_metallb(address_pool=[]):
279279
"component=controller")
280280

281281
# metallb requires a address pool configured and a layer 2 advertisement CR
282-
log.info("Installing IPAddressPool and L2Advertisement custom resources.")
282+
print_panel(log.info("Installing IPAddressPool and L2Advertisement custom resources."))
283283

284284
ip_pool_cr = {'apiVersion': 'metallb.io/v1beta1',
285285
'kind': 'IPAddressPool',
@@ -363,7 +363,7 @@ def configure_external_secrets(external_secrets_config):
363363
gitlab_namespace = external_secrets_config['namespace']
364364

365365
# create the namespace if does not exist
366-
subproc([f'kubectl create namespace {gitlab_namespace}'], True)
366+
subproc([f'kubectl create namespace {gitlab_namespace}'], error_ok=True)
367367

368368
# this currently only works with gitlab
369369
gitlab_secret = {'apiVersion': 'v1',
@@ -462,45 +462,55 @@ def install_kyverno():
462462

463463

464464
# an ugly list of decorators, but these are the opts/args for the whole script
465-
@command(cls=RichCommand)
465+
@command(cls=RichCommand, context_settings=HELP_SETTINGS)
466466
@argument("k8s", metavar="<k3s OR kind>", default="")
467467
@option('--argo', '-a', is_flag=True, help=HELP['argo'])
468+
@option('--config', '-c', metavar="CONFIG_FILE", type=str,
469+
default=path.join(HOME_DIR, '.config/smol-k8s-lab/config.yaml'),
470+
help=HELP['config'])
468471
@option('--delete', '-D', is_flag=True, help=HELP['delete'])
469472
@option('--external_secret_operator', '-e', is_flag=True,
470473
help=HELP['external_secret_operator'])
471-
@option('--config', '-c', metavar="CONFIG_FILE", type=str,
472-
default=path.join(HOME_DIR, '.config/smol-k8s-lab/config.yml'),
473-
help=HELP['config'])
474474
@option('--kyverno', '-k', is_flag=True, help=HELP['kyverno'])
475475
@option('--k9s', '-K', is_flag=True, help=HELP['k9s'])
476+
@option('--log_level', '-l', metavar='LOGLEVEL', help=HELP['log_level'],
477+
type=Choice(['debug', 'info', 'warn', 'error']))
478+
@option('--log_file', '-o', metavar='LOGFILE', help=HELP['log_file'])
476479
@option('--password_manager', '-p', is_flag=True,
477480
help=HELP['password_manager'])
478-
@option('--version', is_flag=True, help=HELP['version'])
479-
def main(k8s: str,
481+
@option('--version', '-v', is_flag=True, help=HELP['version'])
482+
def main(k8s: str = "",
480483
argo: bool = False,
484+
config: str = "",
481485
delete: bool = False,
482486
external_secret_operator: bool = False,
483-
config: str = "",
484487
kyverno: bool = False,
485488
k9s: bool = False,
489+
log_level: str = "",
490+
log_file: str = "",
486491
password_manager: bool = False,
487492
version: bool = False):
488493
"""
489494
Quickly install a k8s distro for a homelab setup. Installs k3s
490495
with metallb, ingess-nginx, cert-manager, and argocd
491496
"""
497+
# setup logging immediately
498+
log = setup_logger(log_level, log_file)
492499

493500
# only return the version if --version was passed in
494501
if version:
495-
print(f'\n🎉 v{get_version("smol-k8s-lab")}\n')
502+
print(f'\n🎉 v{VERSION}\n')
496503
return True
497504

498505
# make sure we got a valid k8s distro
499506
if k8s not in ['k3s', 'kind']:
500-
CONSOLE.print(f'\n☹ Sorry, "[b]{k8s}[/]" is not a currently supported '
501-
'k8s distro. Please try again with k3s or kind.\n')
507+
log.error(f'\n☹ Sorry, "[b]{k8s}[/]" is not a currently supported k8s'
508+
' distro. Please try again with k3s or kind.\n')
502509
exit()
503510

511+
# before we do anything, we need to make sure this OS is supported
512+
check_os_support()
513+
504514
if delete:
505515
# this exist the script after deleting the cluster
506516
delete_cluster(k8s)
@@ -510,7 +520,7 @@ def main(k8s: str,
510520
with open(config, 'r') as yaml_file:
511521
input_variables = safe_load(yaml_file)
512522
except FileNotFoundError:
513-
log.error("Expected config file, {config}, but it was not found")
523+
log.error(f"Expected config file, {config}, but it was not found")
514524

515525
# make sure the tmp directory exists, to store stuff
516526
Path("/tmp/smol-k8s-lab").mkdir(exist_ok=True)

smol_k8s_lab/bw_cli.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def generate(self, special_characters=False):
3939
if special_characters:
4040
command += " --special"
4141

42-
password = subproc([command], False, False)
42+
password = subproc([command], quiet=True)
4343
log.info('New password generated.')
4444
return password
4545

@@ -53,16 +53,16 @@ def unlock(self):
5353
password = Prompt.ask("[cyan]🤫 Enter your Bitwarden vault password",
5454
password=True)
5555

56-
self.session = subproc([f"bw unlock {password} --raw"], False, False,
57-
False)
56+
self.session = subproc([f"bw unlock {password} --raw"], quiet=True,
57+
spinner=False)
5858
log.info('Unlocked the Bitwarden vault.')
5959

6060
def lock(self):
6161
"""
6262
lock the local bitwarden vault
6363
"""
6464
log.info('Locking the Bitwarden vault...')
65-
subproc([f"bw lock --session {self.session}"], False, False)
65+
subproc([f"bw lock --session {self.session}"], quiet=True)
6666
log.info('Bitwarden vault locked.')
6767
return
6868

@@ -103,5 +103,5 @@ def create_login(self, name="", item_url="", user="", password="",
103103
encodedStr = str(encodedBytes, "utf-8")
104104

105105
subproc([f"bw create item {encodedStr} --session {self.session}"],
106-
False, False)
106+
quiet=True)
107107
log.info('Created bitwarden login item.')

smol_k8s_lab/config/config.yml

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
1-
---
2-
domains:
3-
base: "coolwebsite4dogs.com"
1+
# FQDN to access your web interfaces
2+
domain:
3+
# your base domain for use with subdomains below
4+
base: "coolwebsitefordogs.com"
5+
# subdomain for Argo CD, so this would be argocd.coolwebsitefordogs.com
46
argo_cd: "argocd"
5-
argo_cd_grpc: "grpc.argocd"
67

7-
# these HAVE to be full CIDR notation
8+
# metallb IPs used for DNS later (make sure they're not in use)
89
metallb_address_pool:
9-
- 192.168.90.01/32
10-
- 192.168.90.02/32
11-
- 192.168.90.03/32
10+
# Example of required full CIDR notation
11+
# - 192.168.90.01/32
1212

13-
13+
# Used for letsencrypt-staging, to generate certs
14+
1415

16+
# Use the external secrets provider with gitlab
1517
external_secrets:
1618
gitlab:
19+
# going to be deprecated soon in favor of using another password manager
20+
# token from here: https://gitlab.com/-/profile/personal_access_tokens
1721
access_token: "kjdfsk758934fkldsafds"
1822
namespace: "nextcloud"
23+
24+
log:
25+
# logging level, Options: debug, info, warn, error
26+
level: "info"
27+
# path of file to log to
28+
file: "./smol-k8s-log.log"

smol_k8s_lab/console_logging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def simple_loading_bar(tasks={}, time_to_wait=120):
7373
progress.update(task1, advance=2)
7474
# loops until this succeeds
7575
try:
76-
subproc([task_command], False, True, False)
76+
subproc([task_command], spinner=False)
7777
except Exception as reason:
7878
log.debug(f"Encountered Exception: {reason}")
7979
sleep(3)

0 commit comments

Comments
 (0)