Example #1
0
def get_backup_metrics_exporter(
    owner_references: Optional[List[V1OwnerReference]],
    name: str,
    labels: LabelType,
    http_port: int,
    prometheus_port: int,
    backup_aws: Dict[str, Any],
    image_pull_secrets: Optional[List[V1LocalObjectReference]],
    has_ssl: bool,
) -> V1Deployment:
    env = [
        V1EnvVar(name="EXPORTER_PORT", value=str(prometheus_port)),
        V1EnvVar(name="PYTHONWARNINGS",
                 value="ignore:Unverified HTTPS request"),
        V1EnvVar(name="REPOSITORY_PREFIX", value="system_backup"),
    ] + get_backup_env(name, http_port, backup_aws, has_ssl)
    return V1Deployment(
        metadata=V1ObjectMeta(
            name=f"backup-metrics-{name}",
            labels=labels,
            owner_references=owner_references,
        ),
        spec=V1DeploymentSpec(
            replicas=1,
            selector=V1LabelSelector(match_labels={
                LABEL_COMPONENT: "backup",
                LABEL_NAME: name
            }),
            template=V1PodTemplateSpec(
                metadata=V1ObjectMeta(
                    annotations={
                        "prometheus.io/port": str(prometheus_port),
                        "prometheus.io/scrape": "true",
                    },
                    labels=labels,
                    name=f"backup-metrics-{name}",
                ),
                spec=V1PodSpec(
                    containers=[
                        V1Container(
                            command=["metrics-exporter", "-vv"],
                            env=env,
                            image=config.CLUSTER_BACKUP_IMAGE,
                            name="metrics-exporter",
                            ports=[
                                V1ContainerPort(
                                    container_port=prometheus_port,
                                    name="backup-metrics",
                                )
                            ],
                        )
                    ],
                    image_pull_secrets=image_pull_secrets,
                    restart_policy="Always",
                ),
            ),
        ),
    )
Example #2
0
def get_webhook_env():
    if (config.WEBHOOK_URL is not None and config.WEBHOOK_USERNAME is not None
            and config.WEBHOOK_PASSWORD is not None):
        return [
            V1EnvVar(name="WEBHOOK_URL", value=config.WEBHOOK_URL),
            V1EnvVar(name="AUTH_USER", value=config.WEBHOOK_USERNAME),
            V1EnvVar(name="AUTH_PASS", value=config.WEBHOOK_PASSWORD),
        ]
    return []
Example #3
0
def get_statefulset_crate_env(
    node_spec: Dict[str, Any],
    jmx_port: int,
    prometheus_port: int,
    ssl: Optional[Dict[str, Any]],
) -> List[V1EnvVar]:
    crate_env = [
        V1EnvVar(
            name="CRATE_HEAP_SIZE",
            value=str(
                int(
                    bitmath.parse_string_unsafe(
                        node_spec["resources"]["memory"]).bytes *
                    node_spec["resources"]["heapRatio"])),
        ),
        V1EnvVar(
            name="CRATE_JAVA_OPTS",
            value=" ".join(
                get_statefulset_crate_env_java_opts(jmx_port,
                                                    prometheus_port)),
        ),
    ]

    if ssl is not None:
        crate_env.extend([
            V1EnvVar(
                name="KEYSTORE_KEY_PASSWORD",
                value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector(
                    key=ssl["keystoreKeyPassword"]["secretKeyRef"]["key"],
                    name=ssl["keystoreKeyPassword"]["secretKeyRef"]["name"],
                )),
            ),
            V1EnvVar(
                name="KEYSTORE_PASSWORD",
                value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector(
                    key=ssl["keystorePassword"]["secretKeyRef"]["key"],
                    name=ssl["keystorePassword"]["secretKeyRef"]["name"],
                )),
            ),
        ])

    return crate_env
Example #4
0
def get_backup_env(
    name: str, http_port: int, backup_aws: Dict[str, Any], has_ssl: bool,
) -> List[V1EnvVar]:
    schema = "https" if has_ssl else "http"
    return [
        V1EnvVar(name="BASE_PATH", value=backup_aws.get("basePath", "")),
        V1EnvVar(
            name="BUCKET",
            value_from=V1EnvVarSource(
                secret_key_ref=V1SecretKeySelector(
                    key=backup_aws["bucket"]["secretKeyRef"]["key"],
                    name=backup_aws["bucket"]["secretKeyRef"]["name"],
                ),
            ),
        ),
        V1EnvVar(name="HOSTS", value=f"{schema}://crate-{name}:{http_port}"),
        V1EnvVar(
            name="PASSWORD",
            value_from=V1EnvVarSource(
                secret_key_ref=V1SecretKeySelector(
                    key="password", name=f"user-system-{name}",
                ),
            ),
        ),
        V1EnvVar(
            name="REGION",
            value_from=V1EnvVarSource(
                secret_key_ref=V1SecretKeySelector(
                    key=backup_aws["region"]["secretKeyRef"]["key"],
                    name=backup_aws["region"]["secretKeyRef"]["name"],
                ),
            ),
        ),
        V1EnvVar(name="USERNAME", value=SYSTEM_USERNAME),
    ]
Example #5
0
def get_backup_env(name: str, http_port: int, backup_aws: Dict[str, Any],
                   has_ssl: bool) -> List[V1EnvVar]:
    schema = "https" if has_ssl else "http"
    return [
        # The base path is here for backwards-compatibility and
        # is not used by newer versions of the backup CronJob,
        # in favour of the namespace.
        V1EnvVar(name="BASE_PATH", value=backup_aws.get("basePath", "")),
        V1EnvVar(
            name="NAMESPACE",
            value_from=V1EnvVarSource(field_ref=V1ObjectFieldSelector(
                api_version="v1",
                field_path="metadata.namespace",
            )),
        ),
        V1EnvVar(
            name="BUCKET",
            value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector(
                key=backup_aws["bucket"]["secretKeyRef"]["key"],
                name=backup_aws["bucket"]["secretKeyRef"]["name"],
            ), ),
        ),
        V1EnvVar(name="HOSTS", value=f"{schema}://crate-{name}:{http_port}"),
        V1EnvVar(
            name="PASSWORD",
            value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector(
                key="password", name=f"user-system-{name}"), ),
        ),
        V1EnvVar(
            name="REGION",
            value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector(
                key=backup_aws["region"]["secretKeyRef"]["key"],
                name=backup_aws["region"]["secretKeyRef"]["name"],
            ), ),
        ),
        V1EnvVar(name="USERNAME", value=SYSTEM_USERNAME),
    ]
Example #6
0
def get_backup_cronjob(
    owner_references: Optional[List[V1OwnerReference]],
    name: str,
    labels: LabelType,
    http_port: int,
    backup_aws: Dict[str, Any],
    image_pull_secrets: Optional[List[V1LocalObjectReference]],
    has_ssl: bool,
) -> V1beta1CronJob:
    env = [
        V1EnvVar(
            name="AWS_ACCESS_KEY_ID",
            value_from=V1EnvVarSource(
                secret_key_ref=V1SecretKeySelector(
                    key=backup_aws["accessKeyId"]["secretKeyRef"]["key"],
                    name=backup_aws["accessKeyId"]["secretKeyRef"]["name"],
                ),
            ),
        ),
        V1EnvVar(
            name="AWS_SECRET_ACCESS_KEY",
            value_from=V1EnvVarSource(
                secret_key_ref=V1SecretKeySelector(
                    key=backup_aws["secretAccessKey"]["secretKeyRef"]["key"],
                    name=backup_aws["secretAccessKey"]["secretKeyRef"]["name"],
                ),
            ),
        ),
        V1EnvVar(name="CLUSTER_ID", value=name),
        V1EnvVar(name="PYTHONWARNINGS", value="ignore:Unverified HTTPS request"),
        V1EnvVar(name="REPOSITORY_PREFIX", value="system_backup"),
    ] + get_backup_env(name, http_port, backup_aws, has_ssl)
    return V1beta1CronJob(
        metadata=V1ObjectMeta(
            name=f"create-snapshot-{name}",
            labels=labels,
            owner_references=owner_references,
        ),
        spec=V1beta1CronJobSpec(
            concurrency_policy="Forbid",
            failed_jobs_history_limit=1,
            job_template=V1beta1JobTemplateSpec(
                metadata=V1ObjectMeta(labels=labels, name=f"create-snapshot-{name}"),
                spec=V1JobSpec(
                    template=V1PodTemplateSpec(
                        metadata=V1ObjectMeta(
                            labels=labels, name=f"create-snapshot-{name}",
                        ),
                        spec=V1PodSpec(
                            containers=[
                                V1Container(
                                    command=["backup", "-vv"],
                                    env=env,
                                    image=config.CLUSTER_BACKUP_IMAGE,
                                    name="backup",
                                )
                            ],
                            image_pull_secrets=image_pull_secrets,
                            restart_policy="Never",
                        ),
                    ),
                ),
            ),
            schedule=backup_aws["cron"],
            successful_jobs_history_limit=1,
        ),
    )
Example #7
0
async def test_create_kubernetes_resources(
    kubernetes_api_mock: KubernetesApiMock, ) -> None:
    spawner = Mock(spec=KubeSpawner)
    spawner.k8s_api_request_timeout = 3
    spawner.k8s_api_request_retry_timeout = 30
    spawner.namespace = "nublado2-someuser"
    spawner.extra_annotations = {
        "argocd.argoproj.io/compare-options": "IgnoreExtraneous",
        "argocd.argoproj.io/sync-options": "Prune=false",
    }
    spawner.extra_labels = {
        "hub.jupyter.org/network-access-hub": "true",
        "argocd.argoproj.io/instance": "nublado-users",
    }
    spawner._make_create_resource_request = kubernetes_api_mock.create_object
    spawner.hub = Mock()
    spawner.hub.base_url = "/nb/hub/"
    spawner.user = Mock(spec=User)
    spawner.user.name = "someuser"
    spawner.api = kubernetes_api_mock
    auth_state = {
        "token": "user-token",
        "uid": 1234,
        "groups": [{
            "name": "foo",
            "id": 1235
        }, {
            "name": "bar",
            "id": 4567
        }],
    }
    pod_manifest = V1Pod(
        api_version="v1",
        kind="Pod",
        metadata=V1ObjectMeta(
            name="user-pod",
            namespace=spawner.namespace,
        ),
        spec=V1PodSpec(containers=[
            V1Container(
                name="container",
                command=["run-something"],
                env=[V1EnvVar(name="FOO", value="BAR")],
                image="blah:latest",
            )
        ], ),
    )
    if sys.version_info < (3, 8):
        spawner.get_pod_manifest.return_value = asyncio.Future()
        spawner.get_pod_manifest.return_value.set_result(pod_manifest)
        spawner.user.get_auth_state.return_value = asyncio.Future()
        spawner.user.get_auth_state.return_value.set_result(auth_state)
    else:
        spawner.get_pod_manifest.return_value = pod_manifest
        spawner.user.get_auth_state.return_value = auth_state

    options = Mock(spec=SelectedOptions)
    options.debug = "true"
    options.clear_dotlocal = "true"
    options.image_info = ImageInfo(
        reference="registry.hub.docker.com/lsstsqre/sciplat-lab:w_2021_13",
        display_name="blah blah blah",
        digest="sha256:123456789abcdef",
    )

    resource_manager = ResourceManager()
    await resource_manager._create_kubernetes_resources(spawner, options)

    assert sorted(
        kubernetes_api_mock.objects,
        key=lambda o: (o["kind"], o["metadata"]["name"]),
    ) == [
        {
            "apiVersion": "v1",
            "kind": "ConfigMap",
            "metadata": {
                "name": "dask",
                "namespace": spawner.namespace,
                "annotations": spawner.extra_annotations,
                "labels": spawner.extra_labels,
            },
            "data": {
                "dask_worker.yml":
                f"""\
apiVersion: v1
kind: Pod
metadata:
  namespace: {spawner.namespace}
spec:
  containers:
    - command:
        - run-something
      env:
        - name: FOO
          value: BAR
        - name: DASK_WORKER
          value: 'TRUE'
      image: blah:latest
      name: container
"""
            },
        },
        {
            "apiVersion": "v1",
            "kind": "ConfigMap",
            "metadata": {
                "name": "group",
                "namespace": spawner.namespace,
                "annotations": spawner.extra_annotations,
                "labels": spawner.extra_labels,
            },
            "data": {
                "group": ("someuser:x:1234:\n"
                          "foo:x:1235:someuser\n"
                          "bar:x:4567:someuser\n")
            },
        },
        {
            "apiVersion": "v1",
            "kind": "ConfigMap",
            "metadata": {
                "name": "lab-environment",
                "namespace": spawner.namespace,
                "annotations": spawner.extra_annotations,
                "labels": spawner.extra_labels,
            },
            "data": {
                "EXTERNAL_INSTANCE_URL": "https://data.example.com/",
                "FIREFLY_ROUTE": "/portal/app",
                "HUB_ROUTE": "/nb/hub/",
                "EXTERNAL_GROUPS": "foo:1235,bar:4567",
                "EXTERNAL_UID": "1234",
                "ACCESS_TOKEN": "user-token",
                "IMAGE_DIGEST": "sha256:123456789abcdef",
                "IMAGE_DESCRIPTION": "blah blah blah",
                "CLEAR_DOTLOCAL": "true",
                "DEBUG": "true",
            },
        },
    ]

    assert sorted(
        kubernetes_api_mock.custom,
        key=lambda o: (o["kind"], o["metadata"]["name"]),
    ) == [{
        "apiVersion": "ricoberger.de/v1alpha1",
        "kind": "VaultSecret",
        "metadata": {
            "name": "butler-secret",
            "namespace": spawner.namespace,
            "annotations": spawner.extra_annotations,
            "labels": spawner.extra_labels,
        },
        "spec": {
            "path": "k8s_operator/data/butler",
            "type": "Opaque",
        },
    }]