def reconcile_ns()

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}")