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
79import bcrypt
8- from click import option , argument , command
10+ from click import option , argument , command , Choice
911from collections import OrderedDict
10- from importlib .metadata import version as get_version
1112import logging
1213from os import chmod , getenv , path , remove
1314from pathlib import Path
2122import stat
2223from sys import exit
2324from 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
2527from .bw_cli import BwCLI
2628from .help_text import RichCommand , options_help
2729from .homelabHelm import helm
2830from .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
4037soft_theme = Theme ({"info" : "dim cornflower_blue" ,
4542PWD = path .dirname (__file__ )
4643HOME_DIR = getenv ("HOME" )
4744HELP = options_help ()
45+ HELP_SETTINGS = dict (help_option_names = ['-h' , '--help' ])
4846
4947
5048def 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 )
0 commit comments