示例#1
0
def delete_poddefaults_from_user_namespaces(
    poddefaults: List[Dict[str, Any]],
    user_namespaces: List[str],
    client: DynamicClient,
    logger: kopf.Logger,
) -> None:
    logger.debug(
        "Deleting PodDefaults %s from user Namespaces %s",
        [pd["metadata"]["name"] for pd in poddefaults],
        user_namespaces,
    )
    for poddefault in poddefaults:
        for namespace in user_namespaces:
            try:
                delete_poddefault(
                    namespace=namespace,
                    name=poddefault["metadata"]["name"],
                    client=client,
                    logger=logger,
                )
            except Exception as e:
                logger.warn(
                    "Unable to delete PodDefault %s from Namespace %s: %s",
                    poddefault["metadata"]["name"],
                    namespace,
                    str(e),
                )
def _patch_and_delete_stubborn_custom_resources(  # type: ignore
    group: str,
    version: str,
    plural: str,
    namespace: str,
    status_element: str,
    logger: kopf.Logger,
    use_async=True,
    **_: Any,
):
    logger.info(f"_patch_and_delete_stubborn_custom_resources for {plural}.{group} in namespace {namespace}")
    co = CustomObjectsApi()
    resp = co.list_namespaced_custom_object(group=group, version=version, plural=plural, namespace=namespace)
    failed_res = [
        item.get("metadata").get("name")
        for item in resp["items"]
        if item.get("status", {}).get(status_element) in ["Failed", "Completed", "InProgress"]
    ]
    for item in failed_res:
        try:
            logger.info(f"Patching item {item} in {plural}.{group}")
            patch = json.loads("""{"metadata":{"finalizers":[]}}""")
            co.patch_namespaced_custom_object(
                group=group, version=version, plural=plural, namespace=namespace, name=item, body=patch
            )
            logger.info(f"Deleting item {item} in {plural}.{group}")
            co.delete_namespaced_custom_object(
                group=group,
                version=version,
                plural=plural,
                namespace=namespace,
                name=item,
            )
        except ApiException as e:
            logger.warn("Trying to patch and delete failed: %s\n" % e)
def _delete_pods(namespace: str, logger: kopf.Logger, use_async=True, **_: Any):  # type: ignore
    logger.info(f"Deleting ALL PODS in ns {namespace}")
    api = CoreV1Api()
    try:
        api.delete_collection_namespaced_pod(
            namespace=namespace,
            async_req=use_async,
            grace_period_seconds=0,
            propagation_policy="Background",
            body=V1DeleteOptions(),
        )
    except ApiException as e:
        logger.warn("calling CustomObjectsApi->delete_collection_namespaced_pod: %s\n" % e)
def _remove_user_namespaces(namespace: str, team_spec: str, logger: kopf.Logger, **_: Any):  # type: ignore
    logger.info(
        f"Removing all user namespaces with labels orbit/team={team_spec},orbit/space=user in namespace {namespace} "
    )

    v1 = CoreV1Api()
    label_selector = f"orbit/team={team_spec},orbit/space=user"
    all_namespaces = v1.list_namespace(label_selector=label_selector).to_dict()

    all_ns = [
        item.get("metadata").get("name") for item in all_namespaces["items"] if item.get("metadata", {}).get("name")
    ]
    for ns in all_ns:
        logger.info(f"Calling delete namespace {ns}")
        try:
            v1.delete_namespace(name=ns, async_req=True)
        except ApiException as e:
            logger.warn("calling CoreV1API->delete_namespace had an error: %s\n" % e)
def _delete_custom_objects(  # type: ignore
    group: str, version: str, plural: str, namespace: str, logger: kopf.Logger, use_async=True, **_: Any
):

    logger.info(f"Deleting {plural}.{group} in ns {namespace}")
    co = CustomObjectsApi()

    try:
        resp = co.delete_collection_namespaced_custom_object(
            group=group,
            version=version,
            namespace=namespace,
            plural=plural,
            grace_period_seconds=0,
            propagation_policy="Background",
            pretty="true",
            async_req=use_async,
            body=V1DeleteOptions(),
        )

        return resp
    except ApiException as e:
        logger.warn("calling CustomObjectsApi->delete_collection_namespaced_custom_object: %s\n" % e)
        logger.warn("Assume it did not exist")
示例#6
0
def update_pod_images(
    namespace: str,
    labels: kopf.Labels,
    body: kopf.Body,
    patch: kopf.Patch,
    dryrun: bool,
    logger: kopf.Logger,
    warnings: List[str],
    namespaces_idx: kopf.Index[str, Dict[str, Any]],
    podsettings_idx: kopf.Index[str, Dict[str, Any]],
    **_: Any,
) -> kopf.Patch:
    if dryrun:
        logger.debug("DryRun - Skip Pod Mutation")
        return patch

    # This is a hack to get the only namespace from the index Store
    ns: Dict[str, Any] = {}
    for ns in cast(List[Dict[str, Any]], namespaces_idx.get(namespace, [{}])):
        logger.debug("Namespace: %s", ns)

    team = ns.get("labels", {}).get("orbit/team", None)
    if not team:
        logger.info("No 'orbit/team' label found on Pod's Namespace: %s", namespace)
        # warnings.append(f"No 'orbit/team' label found on Pod's Namespace: {namespace}")
        return patch

    team_podsettings: List[Dict[str, Any]] = cast(List[Dict[str, Any]], podsettings_idx.get(team, []))
    if not team_podsettings:
        logger.info("No PodSettings found for Pod's Team: %s", team)
        # warnings.append(f"No PodSettings found for Pod's Team: {team}")
        return patch

    fitlered_podsettings = podsetting_utils.filter_podsettings(
        podsettings=team_podsettings, pod_labels=labels, logger=logger
    )
    if not fitlered_podsettings:
        logger.info("No PodSetting Selectors matched the Pod")
        return patch

    applied_podsetting_names = []
    body_dict = {
        "metadata": {k: v for k, v in body["metadata"].items()},
        "spec": {k: v for k, v in body["spec"].items()},
    }
    logger.debug("BodyDict: %s", body_dict)
    mutable_body = deepcopy(body)
    for podsetting in fitlered_podsettings:
        try:
            podsetting_utils.apply_settings_to_pod(namespace=ns, podsetting=podsetting, pod=mutable_body, logger=logger)
            applied_podsetting_names.append(podsetting["name"])
        except Exception as e:
            logger.exception("Error applying PodSetting %s: %s", podsetting["name"], str(e))
            warnings.append(f"Error applying PodSetting {podsetting['name']}: {str(e)}")

    if body_dict["spec"] == mutable_body["spec"] and body_dict["metadata"] == mutable_body["metadata"]:
        logger.warn("PodSetting Selectors matched the Pod but no changes were applied")
        warnings.append("PodSetting Selectors matched the Pod but no changes were applied")
        return patch

    patch["metadata"] = {}
    patch["metadata"]["annotations"] = {
        **mutable_body["metadata"].get("annotations", {}),
        **{"orbit/applied-podsettings": ",".join(applied_podsetting_names)},
    }
    patch["metadata"]["annotations"] = {k.replace("/", "~1"): v for k, v in patch["metadata"]["annotations"].items()}

    if "labels" in mutable_body["metadata"]:
        patch["metadata"]["labels"] = {k.replace("/", "~1"): v for k, v in mutable_body["metadata"]["labels"].items()}

    patch["spec"] = mutable_body["spec"]

    logger.info("Applying Patch %s", patch)
    return patch