Exemplo n.º 1
0
def test_reload_proxy(tljh_dir):
    with mock.patch(
            "tljh.systemd.restart_service") as restart_service, mock.patch(
                "tljh.systemd.check_service_active") as check_active:
        config.reload_component('proxy')
    assert restart_service.called_with('traefik')
    assert check_active.called_with('traefik')
    assert os.path.exists(os.path.join(config.STATE_DIR, 'traefik.toml'))
Exemplo n.º 2
0
def test_reload_hub():
    with mock.patch(
            'tljh.systemd.restart_service') as restart_service, mock.patch(
                'tljh.systemd.check_service_active'
            ) as check_active, mock.patch(
                'tljh.config.check_hub_ready') as check_ready:
        config.reload_component('hub')
    assert restart_service.called_with('jupyterhub')
    assert check_active.called_with('jupyterhub')
def test_manual_https(preserve_config):
    ssl_dir = "/etc/tljh-ssl-test"
    key = ssl_dir + "/ssl.key"
    cert = ssl_dir + "/ssl.cert"
    os.makedirs(ssl_dir, exist_ok=True)
    os.chmod(ssl_dir, 0o600)
    # generate key and cert
    check_call([
        "openssl",
        "req",
        "-nodes",
        "-newkey",
        "rsa:2048",
        "-keyout",
        key,
        "-x509",
        "-days",
        "1",
        "-out",
        cert,
        "-subj",
        "/CN=tljh.jupyer.org",
    ])
    set_config_value(CONFIG_FILE, "https.enabled", True)
    set_config_value(CONFIG_FILE, "https.tls.key", key)
    set_config_value(CONFIG_FILE, "https.tls.cert", cert)
    reload_component("proxy")
    for i in range(10):
        time.sleep(i)
        try:
            server_cert = ssl.get_server_certificate(("127.0.0.1", 443))
        except Exception as e:
            print(e)
        else:
            break
    with open(cert) as f:
        file_cert = f.read()

    # verify that our certificate was loaded by traefik
    assert server_cert == file_cert

    for i in range(10):
        time.sleep(i)
        # verify that we can still connect to the hub
        try:
            req = HTTPRequest("https://127.0.0.1/hub/api",
                              method="GET",
                              validate_cert=False)
            resp = HTTPClient().fetch(req)
            break
        except Exception as e:
            pass
    assert resp.code == 200

    # cleanup
    shutil.rmtree(ssl_dir)
def test_extra_traefik_config():
    extra_config_dir = os.path.join(CONFIG_DIR, "traefik_config.d")
    os.makedirs(extra_config_dir, exist_ok=True)

    extra_config = {
        "entryPoints": {
            "no_auth_api": {
                "address": "127.0.0.1:9999"
            }
        },
        "api": {
            "dashboard": True,
            "entrypoint": "no_auth_api"
        },
    }

    success = False
    for i in range(5):
        time.sleep(i)
        try:
            with pytest.raises(HTTPClientError,
                               match="HTTP 401: Unauthorized"):
                # The default dashboard entrypoint requires authentication, so it should fail
                req = HTTPRequest("http://127.0.0.1:8099/dashboard/",
                                  method="GET")
                HTTPClient().fetch(req)
            success = True
            break
        except Exception as e:
            pass

    assert success == True

    # Load the extra config
    with open(os.path.join(extra_config_dir, "extra.toml"),
              "w+") as extra_config_file:
        toml.dump(extra_config, extra_config_file)
    reload_component("proxy")

    for i in range(5):
        time.sleep(i)
        try:
            # The new dashboard entrypoint shouldn't require authentication anymore
            req = HTTPRequest("http://127.0.0.1:9999/dashboard/", method="GET")
            resp = HTTPClient().fetch(req)
            break
        except ConnectionRefusedError:
            pass
    # If the request didn't get through after 5 tries, this should fail
    assert resp.code == 200

    # cleanup
    os.remove(os.path.join(extra_config_dir, "extra.toml"))
    reload_component("proxy")
Exemplo n.º 5
0
def preserve_config(request):
    """Fixture to save and restore config around tests"""
    if os.path.exists(CONFIG_FILE):
        with open(CONFIG_FILE) as f:
            save_config = f.read()
    else:
        save_config = None
    try:
        yield
    finally:
        if save_config:
            with open(CONFIG_FILE, "w") as f:
                f.write(save_config)
        elif os.path.exists(CONFIG_FILE):
            os.remove(CONFIG_FILE)
        reload_component("hub")
        reload_component("proxy")
Exemplo n.º 6
0
def preserve_config(request):
    """Fixture to save and restore config around tests"""
    # Import TLJH only when needed. This lets us run tests in places
    # where TLJH is not installed - particularly, the 'distro check' test.
    from tljh.config import CONFIG_FILE, reload_component
    if os.path.exists(CONFIG_FILE):
        with open(CONFIG_FILE) as f:
            save_config = f.read()
    else:
        save_config = None
    try:
        yield
    finally:
        if save_config:
            with open(CONFIG_FILE, "w") as f:
                f.write(save_config)
        elif os.path.exists(CONFIG_FILE):
            os.remove(CONFIG_FILE)
        reload_component("hub")
        reload_component("proxy")
Exemplo n.º 7
0
def test_extra_traefik_config():
    extra_static_config_dir = os.path.join(CONFIG_DIR, "traefik_config.d")
    os.makedirs(extra_static_config_dir, exist_ok=True)

    dynamic_config_dir = os.path.join(STATE_DIR, "rules")
    os.makedirs(dynamic_config_dir, exist_ok=True)

    extra_static_config = {
        "entryPoints": {
            "no_auth_api": {
                "address": "127.0.0.1:9999"
            }
        },
        "api": {
            "dashboard": True,
            "entrypoint": "no_auth_api"
        },
    }

    extra_dynamic_config = {
        "frontends": {
            "test": {
                "backend": "test",
                "routes": {
                    "rule1": {
                        "rule": "PathPrefixStrip: /the/hub/runs/here/too"
                    }
                },
            }
        },
        "backends": {
            # redirect to hub
            "test": {
                "servers": {
                    "server1": {
                        "url": "http://127.0.0.1:15001"
                    }
                }
            }
        },
    }

    success = False
    for i in range(5):
        time.sleep(i)
        try:
            with pytest.raises(HTTPClientError,
                               match="HTTP 401: Unauthorized"):
                # The default dashboard entrypoint requires authentication, so it should fail
                req = HTTPRequest("http://127.0.0.1:8099/dashboard/",
                                  method="GET")
                HTTPClient().fetch(req)
            success = True
            break
        except Exception as e:
            pass

    assert success == True

    # write the extra static config
    with open(os.path.join(extra_static_config_dir, "extra.toml"),
              "w+") as extra_config_file:
        toml.dump(extra_static_config, extra_config_file)

    # write the extra dynamic config
    with open(os.path.join(dynamic_config_dir, "extra_rules.toml"),
              "w+") as extra_config_file:
        toml.dump(extra_dynamic_config, extra_config_file)

    # load the extra config
    reload_component("proxy")

    # the new dashboard entrypoint shouldn't require authentication anymore
    resp = send_request(url="http://127.0.0.1:9999/dashboard/", max_sleep=5)
    assert resp.code == 200

    # test extra dynamic config
    resp = send_request(url="http://127.0.0.1/the/hub/runs/here/too",
                        max_sleep=5)
    assert resp.code == 200
    assert resp.effective_url == "http://127.0.0.1/hub/login"

    # cleanup
    os.remove(os.path.join(extra_static_config_dir, "extra.toml"))
    os.remove(os.path.join(dynamic_config_dir, "extra_rules.toml"))
    open(os.path.join(STATE_DIR, "traefik.toml"), "w").close()