Beispiel #1
0
def test_manual_ssl_config(tljh_dir):
    state_dir = config.STATE_DIR
    config.set_config_value(config.CONFIG_FILE, "https.enabled", True)
    config.set_config_value(config.CONFIG_FILE, "https.tls.key",
                            "/path/to/ssl.key")
    config.set_config_value(config.CONFIG_FILE, "https.tls.cert",
                            "/path/to/ssl.cert")
    traefik.ensure_traefik_config(str(state_dir))
    traefik_toml = os.path.join(state_dir, "traefik.toml")
    with open(traefik_toml) as f:
        toml_cfg = f.read()
        # print config for debugging on failure
        print(config.CONFIG_FILE)
        print(toml_cfg)
        cfg = toml.loads(toml_cfg)
    assert cfg["defaultEntryPoints"] == ["http", "https"]
    assert "acme" not in cfg
    assert cfg["entryPoints"] == {
        "http": {
            "address": ":80",
            "redirect": {
                "entryPoint": "https"
            }
        },
        "https": {
            "address": ":443",
            "backend": "jupyterhub",
            "tls": {
                "certificates": [{
                    "certFile": "/path/to/ssl.cert",
                    "keyFile": "/path/to/ssl.key"
                }]
            },
        },
    }
def test_default_config(tmpdir, tljh_dir):
    state_dir = tmpdir.mkdir("state")
    traefik.ensure_traefik_config(str(state_dir))
    assert state_dir.join("traefik.toml").exists()
    traefik_toml = os.path.join(state_dir, "traefik.toml")
    with open(traefik_toml) as f:
        toml_cfg = f.read()
        # print config for debugging on failure
        print(config.CONFIG_FILE)
        print(toml_cfg)
        cfg = toml.loads(toml_cfg)
    assert cfg["defaultEntryPoints"] == ["http"]
    assert len(cfg["entryPoints"]["auth_api"]["auth"]["basic"]["users"]) == 1
    # runtime generated entry, value not testable
    cfg["entryPoints"]["auth_api"]["auth"]["basic"]["users"] = [""]

    assert cfg["entryPoints"] == {
        "http": {
            "address": ":80"
        },
        "auth_api": {
            "address": "127.0.0.1:8099",
            "auth": {
                "basic": {
                    "users": [""]
                }
            },
            "whiteList": {
                "sourceRange": ["127.0.0.1"]
            },
        },
    }
Beispiel #3
0
def test_default_config(tmpdir, tljh_dir):
    state_dir = tmpdir.mkdir("state")
    traefik.ensure_traefik_config(str(state_dir))
    assert state_dir.join("traefik.toml").exists()
    traefik_toml = os.path.join(state_dir, "traefik.toml")
    with open(traefik_toml) as f:
        toml_cfg = f.read()
        # print config for debugging on failure
        print(config.CONFIG_FILE)
        print(toml_cfg)
        cfg = toml.loads(toml_cfg)
    assert cfg["defaultEntryPoints"] == ["http"]
    assert cfg["entryPoints"] == {"http": {"address": ":80"}}
    assert cfg["frontends"] == {
        "jupyterhub": {
            "backend": "jupyterhub",
            "passHostHeader": True
        }
    }
    assert cfg["backends"] == {
        "jupyterhub": {
            "servers": {
                "chp": {
                    "url": "http://127.0.0.1:15003"
                }
            }
        }
    }
def test_letsencrypt_config(tljh_dir):
    state_dir = config.STATE_DIR
    config.set_config_value(config.CONFIG_FILE, "https.enabled", True)
    config.set_config_value(config.CONFIG_FILE, "https.letsencrypt.email",
                            "*****@*****.**")
    config.set_config_value(config.CONFIG_FILE, "https.letsencrypt.domains",
                            ["testing.jovyan.org"])
    traefik.ensure_traefik_config(str(state_dir))
    traefik_toml = os.path.join(state_dir, "traefik.toml")
    with open(traefik_toml) as f:
        toml_cfg = f.read()
        # print config for debugging on failure
        print(config.CONFIG_FILE)
        print(toml_cfg)
        cfg = toml.loads(toml_cfg)
    assert cfg["defaultEntryPoints"] == ["http", "https"]
    assert "acme" in cfg
    assert len(cfg["entryPoints"]["auth_api"]["auth"]["basic"]["users"]) == 1
    # runtime generated entry, value not testable
    cfg["entryPoints"]["auth_api"]["auth"]["basic"]["users"] = [""]

    assert cfg["entryPoints"] == {
        "http": {
            "address": ":80",
            "redirect": {
                "entryPoint": "https"
            }
        },
        "https": {
            "address": ":443",
            "tls": {
                "minVersion": "VersionTLS12"
            }
        },
        "auth_api": {
            "address": "127.0.0.1:8099",
            "auth": {
                "basic": {
                    "users": [""]
                }
            },
            "whiteList": {
                "sourceRange": ["127.0.0.1"]
            },
        },
    }
    assert cfg["acme"] == {
        "email": "*****@*****.**",
        "storage": "acme.json",
        "entryPoint": "https",
        "httpChallenge": {
            "entryPoint": "http"
        },
        "domains": [{
            "main": "testing.jovyan.org"
        }],
    }
def ensure_jupyterhub_service(prefix):
    """
    Ensure JupyterHub Services are set up properly
    """

    os.makedirs(STATE_DIR, mode=0o700, exist_ok=True)

    with open(os.path.join(HERE, 'systemd-units', 'jupyterhub.service')) as f:
        hub_unit_template = f.read()

    with open(
            os.path.join(HERE, 'systemd-units',
                         'configurable-http-proxy.service')) as f:
        proxy_unit_template = f.read()

    with open(os.path.join(HERE, 'systemd-units', 'traefik.service')) as f:
        traefik_unit_template = f.read()

    traefik.ensure_traefik_config(STATE_DIR)

    unit_params = dict(
        python_interpreter_path=sys.executable,
        jupyterhub_config_path=os.path.join(HERE, 'jupyterhub_config.py'),
        install_prefix=INSTALL_PREFIX,
    )
    systemd.install_unit('configurable-http-proxy.service',
                         proxy_unit_template.format(**unit_params))
    systemd.install_unit('jupyterhub.service',
                         hub_unit_template.format(**unit_params))
    systemd.install_unit('traefik.service',
                         traefik_unit_template.format(**unit_params))
    systemd.reload_daemon()

    # Set up proxy / hub secret oken if it is not already setup
    proxy_secret_path = os.path.join(STATE_DIR,
                                     'configurable-http-proxy.secret')
    if not os.path.exists(proxy_secret_path):
        with open(proxy_secret_path, 'w') as f:
            f.write('CONFIGPROXY_AUTH_TOKEN=' +
                    '0123456789abcdef0123456789abcdef')


#            f.write('CONFIGPROXY_AUTH_TOKEN=' + secrets.token_hex(32))
# If we are changing CONFIGPROXY_AUTH_TOKEN, restart configurable-http-proxy!
        systemd.restart_service('configurable-http-proxy')

    # Start CHP if it has already not been started
    systemd.start_service('configurable-http-proxy')
    # If JupyterHub is running, we want to restart it.
    systemd.restart_service('jupyterhub')
    systemd.restart_service('traefik')

    # Mark JupyterHub & CHP to start at boot time
    systemd.enable_service('jupyterhub')
    systemd.enable_service('configurable-http-proxy')
    systemd.enable_service('traefik')
def test_manual_ssl_config(tljh_dir):
    state_dir = config.STATE_DIR
    config.set_config_value(config.CONFIG_FILE, "https.enabled", True)
    config.set_config_value(config.CONFIG_FILE, "https.tls.key",
                            "/path/to/ssl.key")
    config.set_config_value(config.CONFIG_FILE, "https.tls.cert",
                            "/path/to/ssl.cert")
    traefik.ensure_traefik_config(str(state_dir))
    traefik_toml = os.path.join(state_dir, "traefik.toml")
    with open(traefik_toml) as f:
        toml_cfg = f.read()
        # print config for debugging on failure
        print(config.CONFIG_FILE)
        print(toml_cfg)
        cfg = toml.loads(toml_cfg)
    assert cfg["defaultEntryPoints"] == ["http", "https"]
    assert "acme" not in cfg
    assert len(cfg["entryPoints"]["auth_api"]["auth"]["basic"]["users"]) == 1
    # runtime generated entry, value not testable
    cfg["entryPoints"]["auth_api"]["auth"]["basic"]["users"] = [""]
    assert cfg["entryPoints"] == {
        "http": {
            "address": ":80",
            "redirect": {
                "entryPoint": "https"
            }
        },
        "https": {
            "address": ":443",
            "tls": {
                "minVersion":
                "VersionTLS12",
                "certificates": [{
                    "certFile": "/path/to/ssl.cert",
                    "keyFile": "/path/to/ssl.key"
                }],
            },
        },
        "auth_api": {
            "address": "127.0.0.1:8099",
            "auth": {
                "basic": {
                    "users": [""]
                }
            },
            "whiteList": {
                "sourceRange": ["127.0.0.1"]
            },
        },
    }
Beispiel #7
0
def reload_component(component):
    """
    Reload a TLJH component.

    component can be 'hub' or 'proxy'.
    """
    # import here to avoid circular imports
    from tljh import systemd, traefik
    if component == 'hub':
        systemd.restart_service('jupyterhub')
        # FIXME: Verify hub is back up?
        print('Hub reload with new configuration complete')
    elif component == 'proxy':
        traefik.ensure_traefik_config(STATE_DIR)
        systemd.restart_service('configurable-http-proxy')
        systemd.restart_service('traefik')
        print('Proxy reload with new configuration complete')
def test_extra_config(tmpdir, tljh_dir):
    extra_config_dir = os.path.join(tljh_dir, config.CONFIG_DIR,
                                    "traefik_config.d")
    state_dir = tmpdir.mkdir("state")
    traefik_toml = os.path.join(state_dir, "traefik.toml")

    # Generate default config
    traefik.ensure_traefik_config(str(state_dir))

    # Read the default config
    toml_cfg = toml.load(traefik_toml)

    # Make sure the defaults are what we expect
    assert toml_cfg["logLevel"] == "INFO"
    with pytest.raises(KeyError):
        toml_cfg["checkNewVersion"]
    assert toml_cfg["entryPoints"]["auth_api"]["address"] == "127.0.0.1:8099"

    extra_config = {
        # modify existing value
        "logLevel": "ERROR",
        # modify existing value with multiple levels
        "entryPoints": {
            "auth_api": {
                "address": "127.0.0.1:9999"
            }
        },
        # add new setting
        "checkNewVersion": False,
    }

    with open(os.path.join(extra_config_dir, "extra.toml"),
              "w+") as extra_config_file:
        toml.dump(extra_config, extra_config_file)

    # Merge the extra config with the defaults
    traefik.ensure_traefik_config(str(state_dir))

    # Read back the merged config
    toml_cfg = toml.load(traefik_toml)

    # Check that the defaults were updated by the extra config
    assert toml_cfg["logLevel"] == "ERROR"
    assert toml_cfg["checkNewVersion"] == False
    assert toml_cfg["entryPoints"]["auth_api"]["address"] == "127.0.0.1:9999"
def ensure_jupyterhub_service(prefix):
    """
    Ensure JupyterHub Services are set up properly
    """

    os.makedirs(STATE_DIR, mode=0o700, exist_ok=True)

    remove_chp()
    systemd.reload_daemon()

    with open(os.path.join(HERE, 'systemd-units', 'jupyterhub.service')) as f:
        hub_unit_template = f.read()

    with open(os.path.join(HERE, 'systemd-units', 'traefik.service')) as f:
        traefik_unit_template = f.read()

    #Set up proxy / hub secret token if it is not already setup
    proxy_secret_path = os.path.join(STATE_DIR, 'traefik-api.secret')
    if not os.path.exists(proxy_secret_path):
        with open(proxy_secret_path, 'w') as f:
            f.write(secrets.token_hex(32))

    traefik.ensure_traefik_config(STATE_DIR)

    unit_params = dict(
        python_interpreter_path=sys.executable,
        jupyterhub_config_path=os.path.join(HERE, 'jupyterhub_config.py'),
        install_prefix=INSTALL_PREFIX,
    )
    systemd.install_unit('jupyterhub.service',
                         hub_unit_template.format(**unit_params))
    systemd.install_unit('traefik.service',
                         traefik_unit_template.format(**unit_params))
    systemd.reload_daemon()

    # If JupyterHub is running, we want to restart it.
    systemd.restart_service('jupyterhub')
    systemd.restart_service('traefik')

    # Mark JupyterHub & traefik to start at boot time
    systemd.enable_service('jupyterhub')
    systemd.enable_service('traefik')
Beispiel #10
0
def test_letsencrypt_config(tljh_dir):
    state_dir = config.STATE_DIR
    config.set_config_value(config.CONFIG_FILE, "https.enabled", True)
    config.set_config_value(config.CONFIG_FILE, "https.letsencrypt.email",
                            "*****@*****.**")
    config.set_config_value(config.CONFIG_FILE, "https.letsencrypt.domains",
                            ["testing.jovyan.org"])
    traefik.ensure_traefik_config(str(state_dir))
    traefik_toml = os.path.join(state_dir, "traefik.toml")
    with open(traefik_toml) as f:
        toml_cfg = f.read()
        # print config for debugging on failure
        print(config.CONFIG_FILE)
        print(toml_cfg)
        cfg = toml.loads(toml_cfg)
    assert cfg["defaultEntryPoints"] == ["http", "https"]
    assert "acme" in cfg
    assert cfg["entryPoints"] == {
        "http": {
            "address": ":80",
            "redirect": {
                "entryPoint": "https"
            }
        },
        "https": {
            "address": ":443",
            "backend": "jupyterhub",
            "tls": {}
        },
    }
    assert cfg["acme"] == {
        "email": "*****@*****.**",
        "storage": "acme.json",
        "entryPoint": "https",
        "httpChallenge": {
            "entryPoint": "http"
        },
        "domains": [{
            "main": "testing.jovyan.org"
        }],
    }
def ensure_jupyterhub_service(prefix):
    """
    Ensure JupyterHub Services are set up properly
    """

    remove_chp()
    systemd.reload_daemon()

    with open(os.path.join(HERE, "systemd-units", "jupyterhub.service")) as f:
        hub_unit_template = f.read()

    with open(os.path.join(HERE, "systemd-units", "traefik.service")) as f:
        traefik_unit_template = f.read()

    # Set up proxy / hub secret token if it is not already setup
    proxy_secret_path = os.path.join(STATE_DIR, "traefik-api.secret")
    if not os.path.exists(proxy_secret_path):
        with open(proxy_secret_path, "w") as f:
            f.write(secrets.token_hex(32))

    traefik.ensure_traefik_config(STATE_DIR)

    unit_params = dict(
        python_interpreter_path=sys.executable,
        jupyterhub_config_path=os.path.join(HERE, "jupyterhub_config.py"),
        install_prefix=INSTALL_PREFIX,
    )
    systemd.install_unit("jupyterhub.service",
                         hub_unit_template.format(**unit_params))
    systemd.install_unit("traefik.service",
                         traefik_unit_template.format(**unit_params))
    systemd.reload_daemon()

    # If JupyterHub is running, we want to restart it.
    systemd.restart_service("jupyterhub")
    systemd.restart_service("traefik")

    # Mark JupyterHub & traefik to start at boot time
    systemd.enable_service("jupyterhub")
    systemd.enable_service("traefik")
def reload_component(component):
    """
    Reload a TLJH component.

    component can be 'hub' or 'proxy'.
    """
    # import here to avoid circular imports
    from tljh import systemd, traefik

    if component == 'hub':
        systemd.restart_service('jupyterhub')
        # Ensure hub is back up
        while not systemd.check_service_active('jupyterhub'):
            time.sleep(1)
        while not check_hub_ready():
            time.sleep(1)
        print('Hub reload with new configuration complete')
    elif component == 'proxy':
        traefik.ensure_traefik_config(STATE_DIR)
        systemd.restart_service('traefik')
        while not systemd.check_service_active('traefik'):
            time.sleep(1)
        print('Proxy reload with new configuration complete')