in apps/replikate/src/main.py [0:0]
def reconcile_ns(logger, name, body, patch, **_):
"""
Triggered on profile change or periodically
---
Synchronizes the resources describes as templates and propagate it to the profile
"""
logger.debug(f"Reconciling {name}")
self_obj = deep_merge({}, body)
# logger.info(f" >> {type(self_obj)}")
params = {"name": name, "this": self_obj}
self_hash = k8s_hash(body)
for tpl in TEMPLATES:
txt = tpl.render(params)
data = yaml.safe_load(txt)
_hash = k8s_hash(data)
if self_hash == _hash:
# this is a special case. It seems user wants to change
# the same object by template that we are watching
diff = deep_merge(body, data)
if diff:
logger.info(f"Patching self {name}: {diff}")
deep_merge(patch, diff)
continue
# see: https://github.com/nolar/kopf/issues/687
# kopf.adopt(data)
# for ref in data['metadata']['ownerReferences']:
# if ref.get('Kind') == body['kind'] and ref.get('Name') == name:
# ref['controller'] = False
client = pykube.object_factory(api, data['apiVersion'], data['kind'])
resource = client(api, data)
if resource.exists():
resource.reload()
changed = deep_merge(resource.obj, data)
if changed:
logger.info(f"* {resource.kind.lower()}/{resource.name}: update {changed}")
try:
resource.update()
except HTTPError as e:
logger.exception(f"Failed to update {resource.kind.lower()}/{resource.name}")
else:
logger.debug(f"* {resource.kind.lower()}/{resource.name}: already up to date")
else:
logger.info(f"* {resource.kind.lower()}/{resource.name}: creating")
try:
resource.create()
except HTTPError as e:
logger.exception(f"Failed to create {resource.kind.lower()}/{resource.name}")