Skip to content

Commit

Permalink
Add --print-vars cli parameter
Browse files Browse the repository at this point in the history
feat: print application variable with --print-vars cli param
misc: centralize cli arguments
  • Loading branch information
Karandash8 committed Jul 12, 2024
1 parent be8ee31 commit 6f6d171
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 20 deletions.
15 changes: 11 additions & 4 deletions make_argocd_fly/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import asyncio
from abc import ABC, abstractmethod
import textwrap
from pprint import pformat

from make_argocd_fly.resource import ResourceViewer, ResourceWriter
from make_argocd_fly.renderer import JinjaRenderer
from make_argocd_fly.utils import multi_resource_parser, resource_parser, merge_dicts, generate_filename
from make_argocd_fly.config import get_config
from make_argocd_fly.cli_args import get_cli_args

log = logging.getLogger(__name__)

Expand All @@ -20,6 +22,7 @@ def __init__(self, app_name: str, env_name: str, app_viewer: ResourceViewer = No
self.env_name = env_name
self.app_viewer = app_viewer
self.config = get_config()
self.cli_args = get_cli_args()
self.resources = None

async def prepare(self) -> str:
Expand Down Expand Up @@ -111,13 +114,15 @@ async def generate_resources(self) -> None:

resources = []
renderer = JinjaRenderer(self.app_viewer)
template_vars = merge_dicts({}, self.config.get_vars(), self.config.get_env_vars(self.env_name),
self.config.get_app_vars(self.env_name, self.app_name))
if self.cli_args.get_print_vars():
log.info('Variables for application {} in environment {}:\n{}'.format(self.app_name, self.env_name, pformat(template_vars)))

yml_children = self.app_viewer.get_files_children(r'(\.yml|\.yml\.j2)$')
for yml_child in yml_children:
content = yml_child.content
if yml_child.element_rel_path.endswith('.j2'):
template_vars = merge_dicts({}, self.config.get_vars(), self.config.get_env_vars(self.env_name),
self.config.get_app_vars(self.env_name, self.app_name))
content = renderer.render(content, template_vars, yml_child.element_rel_path)

resources.append(content)
Expand Down Expand Up @@ -157,13 +162,15 @@ async def prepare(self) -> str:

tmp_resource_writer = ResourceWriter(tmp_dir)
renderer = JinjaRenderer(self.app_viewer)
template_vars = merge_dicts({}, self.config.get_vars(), self.config.get_env_vars(self.env_name),
self.config.get_app_vars(self.env_name, self.app_name))
if self.cli_args.get_print_vars():
log.info('Variables for application {} in environment {}:\n{}'.format(self.app_name, self.env_name, pformat(template_vars)))

yml_children = self.app_viewer.get_files_children(r'(\.yml|\.yml\.j2)$', ['base', self.env_name])
for yml_child in yml_children:
content = yml_child.content
if yml_child.element_rel_path.endswith('.j2'):
template_vars = merge_dicts({}, self.config.get_vars(), self.config.get_env_vars(self.env_name),
self.config.get_app_vars(self.env_name, self.app_name))
try:
content = renderer.render(content, template_vars, yml_child.element_rel_path)
except Exception as e:
Expand Down
104 changes: 104 additions & 0 deletions make_argocd_fly/cli_args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import logging


log = logging.getLogger(__name__)


class CLIArgs:
def __init__(self) -> None:
self.root_dir = None
self.config_file = None
self.source_dir = None
self.output_dir = None
self.tmp_dir = None
self.render_apps = None
self.render_envs = None
self.skip_generate = None
self.preserve_tmp_dir = None
self.clean = None
self.print_vars = None
self.yaml_linter = None
self.kube_linter = None
self.loglevel = None

def init_config(self, **kwargs) -> None:
self.__dict__.update(kwargs)

def get_root_dir(self):
if self.root_dir is None:
raise Exception("root_dir is not set")
return self.root_dir

def get_config_file(self):
if self.config_file is None:
raise Exception("config_file is not set")
return self.config_file

def get_source_dir(self):
if self.source_dir is None:
raise Exception("source_dir is not set")
return self.source_dir

def get_output_dir(self):
if self.output_dir is None:
raise Exception("output_dir is not set")
return self.output_dir

def get_tmp_dir(self):
if self.tmp_dir is None:
raise Exception("tmp_dir is not set")
return self.tmp_dir

def get_render_apps(self):
return self.render_apps

def get_render_envs(self):
return self.render_envs

def get_skip_generate(self):
if self.skip_generate is None:
raise Exception("skip_generate is not set")
return self.skip_generate

def get_preserve_tmp_dir(self):
if self.preserve_tmp_dir is None:
raise Exception("preserve_tmp_dir is not set")
return self.preserve_tmp_dir

def get_clean(self):
if self.clean is None:
raise Exception("clean is not set")
return self.clean

def get_print_vars(self):
if self.print_vars is None:
raise Exception("print_vars is not set")
return self.print_vars

def get_yaml_linter(self):
if self.yaml_linter is None:
raise Exception("yaml_linter is not set")
return self.yaml_linter

def get_kube_linter(self):
if self.kube_linter is None:
raise Exception("kube_linter is not set")
return self.kube_linter

def get_loglevel(self):
if self.loglevel is None:
raise Exception("loglevel is not set")
return self.loglevel


cli_args = CLIArgs()


def populate_cli_args(**kwargs) -> CLIArgs:
cli_args.init_config(**kwargs)

return cli_args


def get_cli_args() -> CLIArgs:
return cli_args
12 changes: 6 additions & 6 deletions make_argocd_fly/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import os
import yaml

from make_argocd_fly.cli_args import CLIArgs

LOG_CONFIG_FILE = 'log_config.yml'
CONFIG_FILE = 'config.yml'
SOURCE_DIR = 'source'
Expand All @@ -23,7 +25,6 @@ def __init__(self) -> None:

def init_config(self, root_dir: str, config: dict, source_dir: str, output_dir: str, tmp_dir: str) -> None:
self.root_dir = root_dir

self.source_dir = source_dir
self.output_dir = output_dir
self.tmp_dir = tmp_dir
Expand All @@ -43,22 +44,19 @@ def get_envs(self) -> dict:
if not self.envs:
log.error('Config was not initialized.')
raise Exception

return self.envs

def get_vars(self) -> dict:
if not self.envs:
log.error('Config was not initialized.')
raise Exception

return self.vars

def get_env_vars(self, env_name: str) -> dict:
envs = self.get_envs()
if env_name not in envs:
log.error('Environment {} is not defined'.format(env_name))
raise Exception

return envs[env_name]['vars'] if 'vars' in envs[env_name] else {}

def get_app_vars(self, env_name: str, app_name: str) -> dict:
Expand Down Expand Up @@ -94,12 +92,14 @@ def get_abs_path(root_dir: str, path: str, allow_missing: bool = False) -> str:
return abs_path


def read_config(root_dir: str, config_file: str, source_dir: str, output_dir: str, tmp_dir: str) -> Config:
def read_config(root_dir: str, config_file: str, cli_args: CLIArgs) -> Config:
root_dir = os.path.abspath(root_dir)
config_content = {}

with open(get_abs_path(root_dir, config_file)) as f:
config_content = yaml.safe_load(f.read())

config.init_config(root_dir, config_content, source_dir, output_dir, tmp_dir)
config.init_config(root_dir, config_content, cli_args.get_source_dir(), cli_args.get_output_dir(), cli_args.get_tmp_dir())

log.info('Root directory: {}'.format(root_dir))
log.info('Config file: {}'.format(get_abs_path(root_dir, config_file)))
Expand Down
23 changes: 14 additions & 9 deletions make_argocd_fly/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import yaml
import yamllint

from make_argocd_fly.cli_args import populate_cli_args, get_cli_args
from make_argocd_fly.config import read_config, get_config, LOG_CONFIG_FILE, CONFIG_FILE, \
SOURCE_DIR, OUTPUT_DIR, TMP_DIR
from make_argocd_fly.utils import multi_resource_parser, generate_filename
Expand Down Expand Up @@ -57,9 +58,11 @@ def create_applications(render_apps, render_envs):
return apps


async def generate(render_envs, render_apps) -> None:
async def generate() -> None:
cli_args = get_cli_args()
config = get_config()
apps = create_applications(render_apps, render_envs)

apps = create_applications(cli_args.get_render_apps(), cli_args.get_render_envs())

try:
log.info('Generating temporary files')
Expand Down Expand Up @@ -102,32 +105,34 @@ def main() -> None:
parser.add_argument('--skip-generate', action='store_true', help='Skip resource generation')
parser.add_argument('--preserve-tmp-dir', action='store_true', help='Preserve temporary directory')
parser.add_argument('--clean', action='store_true', help='Clean all applications in output directory')
parser.add_argument('--print-vars', action='store_true', help='Print variables for each application')
parser.add_argument('--yaml-linter', action='store_true', help='Run yamllint against output directory (https://github.com/adrienverge/yamllint)')
parser.add_argument('--kube-linter', action='store_true', help='Run kube-linter against output directory (https://github.com/stackrox/kube-linter)')
parser.add_argument('--loglevel', type=str, default='INFO', help='DEBUG, INFO, WARNING, ERROR, CRITICAL')
args = parser.parse_args()

init_logging(args.loglevel)

config = read_config(os.path.abspath(args.root_dir), args.config_file, args.source_dir, args.output_dir, args.tmp_dir)
cli_args = populate_cli_args(**vars(args))
config = read_config(args.root_dir, args.config_file, cli_args)

tmp_dir = config.get_tmp_dir()
if os.path.exists(tmp_dir):
shutil.rmtree(tmp_dir)

if args.clean:
if cli_args.get_clean():
log.info('Cleaning all output directory')
if os.path.exists(config.get_output_dir()):
shutil.rmtree(config.get_output_dir())

if not args.skip_generate:
asyncio.run(generate(args.render_envs, args.render_apps))
if not cli_args.get_skip_generate():
asyncio.run(generate())

if not args.preserve_tmp_dir and os.path.exists(tmp_dir):
if not cli_args.get_preserve_tmp_dir() and os.path.exists(tmp_dir):
shutil.rmtree(tmp_dir)

# TODO: it does not make sense to write yamls on disk and then read them again to run through linters
if args.yaml_linter:
if cli_args.get_yaml_linter():
log.info('Running yamllint')
process = subprocess.Popen(['yamllint', '-d', '{extends: default, rules: {line-length: disable}}', config.get_output_dir()],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
Expand All @@ -136,7 +141,7 @@ def main() -> None:

log.info('{} {}\n\n{}'.format(yamllint.APP_NAME, yamllint.APP_VERSION, stdout))

if args.kube_linter:
if cli_args.get_kube_linter():
log.info('Running kube-linter')
process = subprocess.Popen(['kube-linter', 'lint', config.get_output_dir()],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
Expand Down
4 changes: 3 additions & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
from make_argocd_fly.config import get_abs_path, read_config, Config
from make_argocd_fly.cli_args import populate_cli_args


def test_get_abs_path_with_relative_path_in_current_directory(tmp_path):
Expand Down Expand Up @@ -85,6 +86,7 @@ def test_read_config_with_valid_config_file(tmp_path):
config_file_path.write_text('test')
source_dir_path = tmp_path / source_dir
source_dir_path.mkdir()
config = read_config(root_dir, config_file, source_dir, output_dir, tmp_dir)
cli_args = populate_cli_args(root_dir=root_dir, config_file=config_file, source_dir=source_dir, output_dir=output_dir, tmp_dir=tmp_dir)
config = read_config(root_dir, config_file, cli_args)
assert isinstance(config, Config)
assert config.get_source_dir() == str(source_dir_path)

0 comments on commit 6f6d171

Please sign in to comment.