def main() -> int:
    args = parse_args()
    config.load_kube_config()

    dev_config = load_config(args.config_file, Distro.from_string(args.distro))
    create_kube_config(args.config_file)

    try:
        build_and_push_images(args, dev_config)
        prepare_and_run_test(args, dev_config)
    finally:
        if not args.skip_dump_diagnostic:
            dump_diagnostic.dump_all(dev_config.namespace)

    corev1 = client.CoreV1Api()
    if not k8s_conditions.wait(
            lambda: corev1.read_namespaced_pod(TEST_POD_NAME, dev_config.
                                               namespace),
            lambda pod: pod.status.phase == "Succeeded",
            sleep_time=5,
            timeout=60,
            exceptions_to_ignore=ApiException,
    ):
        return 1
    return 0
def create_kube_config(config_file: str) -> None:
    """Replicates the local kubeconfig file (pointed at by KUBECONFIG),
    as a ConfigMap."""
    corev1 = client.CoreV1Api()
    print("Creating kube-config ConfigMap")
    dev_config = load_config(config_file)

    svc = corev1.read_namespaced_service("kubernetes", "default")

    kube_config_path = os.getenv("KUBECONFIG")
    if kube_config_path is None:
        raise ValueError("kube_config_path must not be None")

    with open(kube_config_path) as fd:
        kube_config = yaml.safe_load(fd.read())

    if kube_config is None:
        raise ValueError("kube_config_path must not be None")

    kube_config["clusters"][0]["cluster"][
        "server"] = "https://" + svc.spec.cluster_ip
    kube_config = yaml.safe_dump(kube_config)
    data = {"kubeconfig": kube_config}
    config_map = client.V1ConfigMap(
        metadata=client.V1ObjectMeta(name="kube-config"), data=data)

    k8s_conditions.ignore_if_already_exists(
        lambda: corev1.create_namespaced_config_map(dev_config.namespace,
                                                    config_map))
Esempio n. 3
0
def _prepare_testrunner_environment():
    """
    _prepare_testrunner_environment ensures the ServiceAccount,
    Role and ClusterRole and bindings are created for the test runner.
    """
    rbacv1 = client.RbacAuthorizationV1Api()
    corev1 = client.CoreV1Api()
    dev_config = load_config()

    _delete_testrunner_pod()

    print("Creating Role")
    k8s_conditions.ignore_if_already_exists(
        lambda: rbacv1.create_namespaced_role(dev_config.namespace,
                                              _load_testrunner_role()))

    print("Creating Role Binding")
    k8s_conditions.ignore_if_already_exists(
        lambda: rbacv1.create_namespaced_role_binding(
            dev_config.namespace, _load_testrunner_role_binding()))

    print("Creating Cluster Role Binding")
    k8s_conditions.ignore_if_already_exists(
        lambda: rbacv1.create_cluster_role_binding(
            _load_testrunner_cluster_role_binding()))

    print("Creating ServiceAccount")
    k8s_conditions.ignore_if_already_exists(
        lambda: corev1.create_namespaced_service_account(
            dev_config.namespace, _load_testrunner_service_account()))
Esempio n. 4
0
def _get_testrunner_pod_body(test: str) -> Dict:
    dev_config = load_config()
    return {
        "kind": "Pod",
        "metadata": {
            "name": TEST_RUNNER_NAME,
            "namespace": dev_config.namespace,
        },
        "spec": {
            "restartPolicy":
            "Never",
            "serviceAccountName":
            TEST_RUNNER_NAME,
            "containers": [{
                "name":
                TEST_RUNNER_NAME,
                "image":
                f"{dev_config.repo_url}/{TEST_RUNNER_NAME}",
                "imagePullPolicy":
                "Always",
                "command": [
                    "./runner",
                    "--operatorImage",
                    f"{dev_config.repo_url}/mongodb-kubernetes-operator",
                    "--preHookImage",
                    f"{dev_config.repo_url}/prehook",
                    "--testImage",
                    f"{dev_config.repo_url}/e2e",
                    f"--test={test}",
                    f"--namespace={dev_config.namespace}",
                ],
            }],
        },
    }
Esempio n. 5
0
def main():
    args = parse_args()
    config.load_kube_config()
    dev_config = load_config()
    create_kube_config()

    if not args.skip_operator_install:
        build_and_push_operator(
            dev_config.repo_url,
            f"{dev_config.repo_url}/mongodb-kubernetes-operator",
            ".",
        )
        deploy_operator()

    build_and_push_testrunner(dev_config.repo_url,
                              f"{dev_config.repo_url}/{TEST_RUNNER_NAME}", ".")
    build_and_push_e2e(dev_config.repo_url, f"{dev_config.repo_url}/e2e", ".")
    build_and_push_prehook(dev_config.repo_url,
                           f"{dev_config.repo_url}/prehook", ".")

    _prepare_testrunner_environment()

    pod = create_test_runner_pod(args.test)
    corev1 = client.CoreV1Api()

    wait_for_pod_to_be_running(corev1, TEST_RUNNER_NAME, dev_config.namespace)

    # stream all of the pod output as the pod is running
    for line in corev1.read_namespaced_pod_log(
            TEST_RUNNER_NAME,
            dev_config.namespace,
            follow=True,
            _preload_content=False).stream():
        print(line.decode("utf-8").rstrip())
def deploy_operator() -> None:
    """
    deploy_operator ensures the CRDs are created, and als creates all the required ServiceAccounts, Roles
    and RoleBindings for the operator, and then creates the operator deployment.
    """
    appsv1 = client.AppsV1Api()
    corev1 = client.CoreV1Api()
    rbacv1 = client.RbacAuthorizationV1Api()

    dev_config = load_config()
    _ensure_crds()

    k8s_conditions.ignore_if_already_exists(
        lambda: rbacv1.create_namespaced_role(dev_config.namespace,
                                              _load_operator_role()))
    k8s_conditions.ignore_if_already_exists(
        lambda: rbacv1.create_namespaced_role_binding(
            dev_config.namespace, _load_operator_role_binding()))
    k8s_conditions.ignore_if_already_exists(
        lambda: corev1.create_namespaced_service_account(
            dev_config.namespace, _load_operator_service_account()))
    k8s_conditions.ignore_if_already_exists(
        lambda: appsv1.create_namespaced_deployment(
            dev_config.namespace,
            _load_operator_deployment(
                f"{dev_config.repo_url}/mongodb-kubernetes-operator"),
        ))
Esempio n. 7
0
def main():
    config.load_kube_config()
    dev_config = load_config()
    build_and_push_operator(
        dev_config.repo_url, f"{dev_config.repo_url}/mongodb-kubernetes-operator", "."
    )
    deploy_operator()
Esempio n. 8
0
def _get_testrunner_pod_body(
    test: str,
    config_file: str,
    tag: str,
    perform_cleanup: str,
    test_runner_image_name: str,
) -> Dict:
    dev_config = load_config(config_file)
    return {
        "kind": "Pod",
        "metadata": {"name": TEST_RUNNER_NAME, "namespace": dev_config.namespace,},
        "spec": {
            "restartPolicy": "Never",
            "serviceAccountName": TEST_RUNNER_NAME,
            "containers": [
                {
                    "name": "test-runner",
                    "image": f"{dev_config.repo_url}/{test_runner_image_name}:{tag}",
                    "imagePullPolicy": "Always",
                    "command": [
                        "./runner",
                        "--operatorImage",
                        f"{dev_config.repo_url}/{dev_config.operator_image}:{tag}",
                        "--versionUpgradeHookImage",
                        f"{dev_config.repo_url}/{dev_config.version_upgrade_hook_image}:{tag}",
                        "--testImage",
                        f"{dev_config.repo_url}/{dev_config.e2e_image}:{tag}",
                        f"--test={test}",
                        f"--namespace={dev_config.namespace}",
                        f"--performCleanup={perform_cleanup}",
                    ],
                }
            ],
        },
    }
Esempio n. 9
0
def create_test_runner_pod(
    test: str,
    config_file: str,
    tag: str,
    perform_cleanup: str,
    test_runner_image_name: str,
) -> None:
    """
    create_test_runner_pod creates the pod which will run all of the tests.
    """
    dev_config = load_config(config_file)
    corev1 = client.CoreV1Api()
    pod_body = _get_testrunner_pod_body(
        test, config_file, tag, perform_cleanup, test_runner_image_name
    )

    if not k8s_conditions.wait(
        lambda: corev1.list_namespaced_pod(
            dev_config.namespace, field_selector=f"metadata.name=={TEST_RUNNER_NAME}",
        ),
        lambda pod_list: len(pod_list.items) == 0,
        timeout=30,
        sleep_time=0.5,
    ):
        raise Exception(
            "Execution timed out while waiting for the existing pod to be deleted"
        )

    if not k8s_conditions.call_eventually_succeeds(
        lambda: corev1.create_namespaced_pod(dev_config.namespace, body=pod_body),
        sleep_time=10,
        timeout=60,
        exceptions_to_ignore=ApiException,
    ):
        raise Exception("Could not create test_runner pod!")
Esempio n. 10
0
def create_test_runner_pod(test: str):
    """
    create_test_runner_pod creates the pod which will run all of the tests.
    """
    dev_config = load_config()
    corev1 = client.CoreV1Api()
    pod_body = _get_testrunner_pod_body(test)
    return corev1.create_namespaced_pod(dev_config.namespace, body=pod_body)
Esempio n. 11
0
def _delete_test_pod(config_file: str) -> None:
    """
    _delete_testrunner_pod deletes the test runner pod
    if it already exists.
    """
    dev_config = load_config(config_file)
    corev1 = client.CoreV1Api()
    k8s_conditions.ignore_if_doesnt_exist(lambda: corev1.delete_namespaced_pod(
        TEST_POD_NAME, dev_config.namespace))
Esempio n. 12
0
def _delete_testrunner_pod() -> None:
    """
    _delete_testrunner_pod deletes the test runner pod
    if it already exists.
    """
    dev_config = load_config()
    corev1 = client.CoreV1Api()
    ignore_if_doesnt_exist(lambda: corev1.delete_namespaced_pod(
        TEST_RUNNER_NAME, dev_config.namespace))
Esempio n. 13
0
def create_test_runner_pod(test: str):
    """
    create_test_runner_pod creates the pod which will run all of the tests.
    """
    dev_config = load_config()
    corev1 = client.CoreV1Api()
    pod_body = _get_testrunner_pod_body(test)

    if not k8s_conditions.wait(
            lambda: corev1.list_namespaced_pod(
                dev_config.namespace,
                field_selector=f"metadata.name=={TEST_RUNNER_NAME}"),
            lambda pod_list: len(pod_list.items) == 0,
            timeout=10,
            sleep_time=0.5,
    ):

        raise Exception(
            "Execution timed out while waiting for the existing pod to be deleted"
        )

    return corev1.create_namespaced_pod(dev_config.namespace, body=pod_body)