async def test_spawn_internal_ssl( kube_ns, kube_client, ssl_app, hub_pod_ssl, hub_ssl, config, exec_python_pod, ): hub_pod_name = hub_pod_ssl.metadata.name spawner = KubeSpawner( config=config, hub=hub_ssl, user=MockUser(name="ssl"), api_token="abc123", oauth_client_id="unused", internal_ssl=True, internal_trust_bundles=ssl_app.internal_trust_bundles, internal_certs_location=ssl_app.internal_certs_location, ) # initialize ssl config hub_paths = await spawner.create_certs() spawner.cert_paths = await spawner.move_certs(hub_paths) # start the spawner url = await spawner.start() pod_name = "jupyter-%s" % spawner.user.name # verify the pod exists pods = kube_client.list_namespaced_pod(kube_ns).items pod_names = [p.metadata.name for p in pods] assert pod_name in pod_names # verify poll while running status = await spawner.poll() assert status is None # verify service and secret exist secret_name = spawner.secret_name secrets = kube_client.list_namespaced_secret(kube_ns).items secret_names = [s.metadata.name for s in secrets] assert secret_name in secret_names service_name = pod_name services = kube_client.list_namespaced_service(kube_ns).items service_names = [s.metadata.name for s in services] assert service_name in service_names # resolve internal-ssl paths in hub-ssl pod # these are in /etc/jupyterhub/internal-ssl hub_ssl_dir = "/etc/jupyterhub" hub_ssl_ca = os.path.join(hub_ssl_dir, ssl_app.internal_trust_bundles["hub-ca"]) # use certipy to resolve these? hub_internal = os.path.join(hub_ssl_dir, "internal-ssl", "hub-internal") hub_internal_cert = os.path.join(hub_internal, "hub-internal.crt") hub_internal_key = os.path.join(hub_internal, "hub-internal.key") r = exec_python_pod( hub_pod_name, check_up, { "url": url, "ssl_ca": hub_ssl_ca, "ssl_client_cert": hub_internal_cert, "ssl_client_key": hub_internal_key, }, _retries=3, ) assert r == "302" # stop the pod await spawner.stop() # verify pod is gone pods = kube_client.list_namespaced_pod(kube_ns).items pod_names = [p.metadata.name for p in pods] assert "jupyter-%s" % spawner.user.name not in pod_names # verify service and secret are gone # it may take a little while for them to get cleaned up for i in range(5): secrets = kube_client.list_namespaced_secret(kube_ns).items secret_names = {s.metadata.name for s in secrets} services = kube_client.list_namespaced_service(kube_ns).items service_names = {s.metadata.name for s in services} if secret_name in secret_names or service_name in service_names: time.sleep(1) else: break assert secret_name not in secret_names assert service_name not in service_names
async def test_variable_expansion(ssl_app): """ Variable expansion not tested here: - pod_connect_ip: is tested in test_url_changed - user_namespace_template: isn't tested because it isn't set as part of the Pod manifest but. """ config_to_test = { "pod_name_template": { "configured_value": "pod-name-template-{username}", "findable_in": ["pod"], }, "pvc_name_template": { "configured_value": "pvc-name-template-{username}", "findable_in": ["pvc"], }, "secret_name_template": { "configured_value": "secret-name-template-{username}", "findable_in": ["secret"], }, "storage_selector": { "configured_value": { "matchLabels": { "dummy": "storage-selector-{username}" } }, "findable_in": ["pvc"], }, "storage_extra_labels": { "configured_value": { "dummy": "storage-extra-labels-{username}" }, "findable_in": ["pvc"], }, "extra_labels": { "configured_value": { "dummy": "common-extra-labels-{username}" }, "findable_value": "common-extra-labels-user1", "findable_in": ["pod", "service", "secret"], }, "extra_annotations": { "configured_value": { "dummy": "common-extra-annotations-{username}" }, "findable_value": "common-extra-annotations-user1", "findable_in": ["pod", "service", "secret"], }, "working_dir": { "configured_value": "working-dir-{username}", "findable_in": ["pod"], }, "service_account": { "configured_value": "service-account-{username}", "findable_in": ["pod"], }, "volumes": { "configured_value": [{ 'name': 'volumes-{username}', 'secret': { 'secretName': 'dummy' }, }], "findable_in": ["pod"], }, "volume_mounts": { "configured_value": [{ 'name': 'volume-mounts-{username}', 'mountPath': '/tmp/', }], "findable_in": ["pod"], }, "init_containers": { "configured_value": [{ 'name': 'init-containers-{username}', 'image': 'busybox', }], "findable_in": ["pod"], }, "extra_containers": { "configured_value": [{ 'name': 'extra-containers-{username}', 'image': 'busybox', }], "findable_in": ["pod"], }, "extra_pod_config": { "configured_value": { "schedulerName": "extra-pod-config-{username}" }, "findable_in": ["pod"], }, } c = Config() for key, value in config_to_test.items(): c.KubeSpawner[key] = value["configured_value"] if "findable_value" not in value: value["findable_value"] = key.replace("_", "-") + "-user1" user = MockUser(name="user1") spawner = KubeSpawner( config=c, user=user, internal_trust_bundles=ssl_app.internal_trust_bundles, internal_certs_location=ssl_app.internal_certs_location, _mock=True, ) hub_paths = await spawner.create_certs() spawner.cert_paths = await spawner.move_certs(hub_paths) manifests = { "pod": await spawner.get_pod_manifest(), "pvc": spawner.get_pvc_manifest(), "secret": spawner.get_secret_manifest("dummy-owner-ref"), "service": spawner.get_service_manifest("dummy-owner-ref"), } for resource_kind, manifest in manifests.items(): manifest_string = str(manifest) for config in config_to_test.values(): if resource_kind in config["findable_in"]: assert config["findable_value"] in manifest_string, ( manifest_string + "\n\n" + "finable_value: " + config["findable_value"] + "\n" + "resource_kind: " + resource_kind)