Skip to content

Commit

Permalink
Merge pull request #61 from karellen/issue_60
Browse files Browse the repository at this point in the history
Add summary statistics for created, patched and deleted objects
  • Loading branch information
arcivanov authored May 14, 2024
2 parents 51bb1d9 + 6bc0a17 commit c7239fe
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 33 deletions.
4 changes: 2 additions & 2 deletions src/integrationtest/python/test_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
class IntegrationTestSupport(unittest.TestCase):
K8S_TEST_VERSIONS = ["1.20.15", "1.21.14", "1.22.17",
"1.23.17", "1.24.17", "1.25.16",
"1.26.15", "1.27.12", "1.28.8",
"1.29.3"]
"1.26.15", "1.27.13", "1.28.9",
"1.29.4"]

def load_json_logs(self, log_file):
decoder = json.JSONDecoder()
Expand Down
3 changes: 3 additions & 0 deletions src/main/python/kubernator/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,9 @@ def handle_verify(self):
def handle_shutdown(self):
pass

def handle_summary(self):
pass


def install_python_k8s_client(run, package_major, logger, logger_stdout, logger_stderr, disable_patching):
cache_dir = get_cache_dir("python")
Expand Down
53 changes: 30 additions & 23 deletions src/main/python/kubernator/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,42 +178,49 @@ def run(self):
self.register_plugin(self)

try:
while True:
cwd = self.next()
if not cwd:
logger.debug("No paths left to traverse")
break
try:
while True:
cwd = self.next()
if not cwd:
logger.debug("No paths left to traverse")
break

context = self.context
context = self.context

logger.debug("Inspecting directory %s", self._display_path(cwd))
self._run_handlers(KubernatorPlugin.handle_before_dir, False, context, None, cwd)
logger.debug("Inspecting directory %s", self._display_path(cwd))
self._run_handlers(KubernatorPlugin.handle_before_dir, False, context, None, cwd)

if (ktor_py := (cwd / ".kubernator.py")).exists():
self._run_handlers(KubernatorPlugin.handle_before_script, False, context, None, cwd)
if (ktor_py := (cwd / ".kubernator.py")).exists():
self._run_handlers(KubernatorPlugin.handle_before_script, False, context, None, cwd)

for h in self.context._plugins:
h.set_context(context)
for h in self.context._plugins:
h.set_context(context)

self._exec_ktor(ktor_py)
self._exec_ktor(ktor_py)

for h in self.context._plugins:
h.set_context(None)
for h in self.context._plugins:
h.set_context(None)

self._run_handlers(KubernatorPlugin.handle_after_script, True, context, None, cwd)
self._run_handlers(KubernatorPlugin.handle_after_script, True, context, None, cwd)

self._run_handlers(KubernatorPlugin.handle_after_dir, True, context, None, cwd)
self._run_handlers(KubernatorPlugin.handle_after_dir, True, context, None, cwd)

self.context = self._top_dir_context
context = self.context
self.context = self._top_dir_context
context = self.context

self._run_handlers(KubernatorPlugin.handle_apply, True, context, None)
self._run_handlers(KubernatorPlugin.handle_apply, True, context, None)

self._run_handlers(KubernatorPlugin.handle_verify, True, context, None)
finally:
self._run_handlers(KubernatorPlugin.handle_verify, True, context, None)
finally:
self.context = self._top_dir_context
context = self.context
self._run_handlers(KubernatorPlugin.handle_shutdown, True, context, None)
except: # noqa E722
raise
else:
self.context = self._top_dir_context
context = self.context
self._run_handlers(KubernatorPlugin.handle_shutdown, True, context, None)
self._run_handlers(KubernatorPlugin.handle_summary, True, context, None)

def discover_plugins(self):
importlib.invalidate_caches()
Expand Down
31 changes: 23 additions & 8 deletions src/main/python/kubernator/plugins/k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def __init__(self):

self._transformers = []
self._validators = []
self._summary = 0, 0, 0

def set_context(self, context):
self.context = context
Expand Down Expand Up @@ -248,6 +249,7 @@ def handle_apply(self):

patch_field_excludes = [re.compile(e) for e in context.globals.k8s.patch_field_excludes]
dump_results = []
total_created, total_patched, total_deleted = 0, 0, 0
for resource in self.resources.values():
if dump:
resource_id = {"apiVersion": resource.api_version,
Expand Down Expand Up @@ -280,13 +282,17 @@ def delete_func(*, propagation_policy):
create_func = partial(resource.create, dry_run=dry_run)
delete_func = partial(resource.delete, dry_run=dry_run)

self._apply_resource(dry_run,
patch_field_excludes,
resource,
patch_func,
create_func,
delete_func,
status_msg)
created, patched, deleted = self._apply_resource(dry_run,
patch_field_excludes,
resource,
patch_func,
create_func,
delete_func,
status_msg)

total_created += created
total_patched += patched
total_deleted += deleted

if ((dump or dry_run) and
k8s.field_validation_warn_fatal and self.context.globals.k8s.field_validation_warnings):
Expand All @@ -301,6 +307,12 @@ def delete_func(*, propagation_policy):
indent=4 if file_format == "json-pretty" else None)
else:
yaml.safe_dump(dump_results, file)
else:
self._summary = total_created, total_patched, total_deleted

def handle_summary(self):
total_created, total_patched, total_deleted = self._summary
logger.info("Created %d, patched %d, deleted %d resources", total_created, total_patched, total_deleted)

def api_load_resources(self, path: Path, file_type: str):
return self.add_local_resources(path, FileType[file_type.upper()])
Expand Down Expand Up @@ -422,6 +434,7 @@ def create(exists_ok=False):
if e.status == 404:
try:
create()
return 1, 0, 0
except ApiException as e:
if not handle_400_strict_validation_error(e):
raise
Expand Down Expand Up @@ -459,7 +472,7 @@ def create(exists_ok=False):
status_msg)
delete_func(propagation_policy=propagation_policy)
create(exists_ok=dry_run)
return
return 1, 0, 1
raise
else:
if not handle_400_strict_validation_error(e):
Expand All @@ -476,8 +489,10 @@ def create(exists_ok=False):
if patch:
logger.info("Patching resource %s%s", resource, status_msg)
patch_func(patch)
return 0, 1, 0
else:
logger.info("Nothing to patch for resource %s", resource)
return 0, 0, 0

def _filter_resource_patch(self, patch: Iterable[Mapping], excludes: Iterable[re.compile]):
result = []
Expand Down

0 comments on commit c7239fe

Please sign in to comment.