Exemplo n.º 1
0
def cluster_auth(deployment):
    """
    Do appropriate cluster authentication for given deployment
    """
    config = get_config(deployment)

    if 'cluster' in config:
        cluster = config['cluster']
        provider = cluster.get('provider')

        # Temporarily kubeconfig file
        temp_kubeconfig = tempfile.NamedTemporaryFile()
        orig_kubeconfig = os.environ.get("KUBECONFIG", None)

        try:
            os.environ["KUBECONFIG"] = temp_kubeconfig.name

            if provider == 'gcloud':
                yield from cluster_auth_gcloud(deployment, **cluster['gcloud'])
            elif provider == 'aws':
                yield from cluster_auth_aws(deployment, **cluster['aws'])
            elif provider == 'azure':
                yield from cluster_auth_azure(deployment, **cluster['azure'])
            else:
                raise ValueError(
                    f'Unknown provider {provider} found in hubploy.yaml')
        finally:
            unset_env_var("KUBECONFIG", orig_kubeconfig)
Exemplo n.º 2
0
def registry_auth(deployment, push, check_registry):
    """
    Do appropriate registry authentication for given deployment
    """

    if push or check_registry:

        config = get_config(deployment)

        if 'images' in config and 'registry' in config['images']:
            registry = config['images']['registry']
            provider = registry.get('provider')
            if provider == 'gcloud':
                yield from registry_auth_gcloud(
                    deployment, **registry['gcloud']
                )
            elif provider == 'aws':
                yield from registry_auth_aws(
                    deployment, **registry['aws']
                )
            elif provider == 'azure':
                yield from registry_auth_azure(
                    deployment, **registry['azure']
                )
            elif provider == 'dockerconfig':
                yield from registry_auth_dockercfg(
                    deployment, **registry['dockerconfig']
                )
            else:
                raise ValueError(
                    f'Unknown provider {provider} found in hubploy.yaml')
    else:
        # We actually don't need to auth, but we are yielding anyway
        # contextlib.contextmanager does not like it when you don't yield
        yield
Exemplo n.º 3
0
def deploy(deployment,
           chart,
           environment,
           namespace=None,
           helm_config_overrides=None,
           version=None,
           timeout=None,
           force=False):
    """
    Deploy a JupyterHub.

    Expects the following files to exist in current directory

    {chart}/ (Helm deployment chart)
    deployments/
    - {deployment}
        - image/
        - secrets/
            - {environment}.yaml
        - config/
          - common.yaml
          - {environment}.yaml

    A docker image from deployments/{deployment}/image is expected to be
    already built and available with imagebuilder.
    `jupyterhub.singleuser.image.tag` will be automatically set to this image
    tag.
    """
    if helm_config_overrides is None:
        helm_config_overrides = []

    config = get_config(deployment)

    name = f'{deployment}-{environment}'

    if namespace is None:
        namespace = name
    helm_config_files = [
        f for f in [
            os.path.join('deployments', deployment, 'config', 'common.yaml'),
            os.path.join('deployments', deployment, 'config',
                         f'{environment}.yaml'),
            os.path.join('deployments', deployment, 'secrets',
                         f'{environment}.yaml'),
        ] if os.path.exists(f)
    ]

    for image in config['images']['images']:
        # We can support other charts that wrap z2jh by allowing various
        # config paths where we set image tags and names.
        # We default to one sublevel, but we can do multiple levels.
        # With the PANGEO chart, we this could be set to `pangeo.jupyterhub.singleuser.image`
        helm_config_overrides.append(
            f'{image.helm_substitution_path}.tag={image.tag}')
        helm_config_overrides.append(
            f'{image.helm_substitution_path}.name={image.name}')

    helm_upgrade(name, namespace, chart, helm_config_files,
                 helm_config_overrides, version, timeout, force)
Exemplo n.º 4
0
def build_deployment(client, deployment, commit_range, push=False):
    config = get_config(deployment)

    image_path = os.path.abspath(
        os.path.join('deployments', deployment, 'image'))
    image_name = config['images']['image_name']

    build_if_needed(client, image_path, image_name, commit_range, push)
Exemplo n.º 5
0
def registry_auth(deployment):
    """
    Do appropriate registry authentication for given deployment
    """
    config = get_config(deployment)

    if 'images' in config and 'registry' in config['images']:
        registry = config['images']['registry']
        provider = registry.get('provider')
        if provider == 'gcloud':
            registry_auth_gcloud(deployment, **registry['gcloud'])
        else:
            raise ValueError(
                f'Unknown provider {provider} found in hubploy.yaml')
Exemplo n.º 6
0
def cluster_auth(deployment):
    """
    Do appropriate cluster authentication for given deployment
    """
    config = get_config(deployment)

    if 'cluster' in config:
        cluster = config['cluster']
        provider = cluster.get('provider')
        if provider == 'gcloud':
            cluster_auth_gcloud(deployment, **cluster['gcloud'])
        else:
            raise ValueError(
                f'Unknown provider {provider} found in hubploy.yaml')
Exemplo n.º 7
0
def cluster_auth(deployment):
    """
    Do appropriate cluster authentication for given deployment
    """
    config = get_config(deployment)

    if 'cluster' in config:
        cluster = config['cluster']
        provider = cluster.get('provider')
        orig_kubeconfig = os.environ.get("KUBECONFIG", None)
        try:
            if provider == 'kubeconfig':
                encrypted_kubeconfig_path = os.path.join(
                    'deployments', deployment, 'secrets', cluster['kubeconfig']['filename']
                )
                with decrypt_file(encrypted_kubeconfig_path) as kubeconfig_path:
                    os.environ["KUBECONFIG"] = kubeconfig_path
                    yield
            else:

                # Temporarily kubeconfig file
                with tempfile.NamedTemporaryFile() as temp_kubeconfig:
                    os.environ["KUBECONFIG"] = temp_kubeconfig.name

                    if provider == 'gcloud':
                        yield from cluster_auth_gcloud(
                            deployment, **cluster['gcloud']
                        )
                    elif provider == 'aws':
                        yield from cluster_auth_aws(
                            deployment, **cluster['aws']
                        )
                    elif provider == 'azure':
                        yield from cluster_auth_azure(
                            deployment, **cluster['azure']
                        )
                    else:
                        raise ValueError(
                            f'Unknown provider {provider} found in hubploy.yaml')
        finally:
            unset_env_var("KUBECONFIG", orig_kubeconfig)
Exemplo n.º 8
0
def deploy(deployment,
           chart,
           environment,
           namespace=None,
           helm_config_overrides_implicit=None,
           helm_config_overrides_string=None,
           version=None,
           timeout=None,
           force=False,
           atomic=False,
           cleanup_on_fail=False):
    """
    Deploy a JupyterHub.

    Expects the following files to exist in current directory

    {chart}/ (Helm deployment chart)
    deployments/
    - {deployment}
        - image/ (optional)
        - secrets/
            - {environment}.yaml
        - config/
          - common.yaml
          - {environment}.yaml

    A docker image from deployments/{deployment}/image is expected to be
    already built and available with imagebuilder.
    `jupyterhub.singleuser.image.tag` will be automatically set to this image
    tag.
    """
    if helm_config_overrides_implicit is None:
        helm_config_overrides_implicit = []
    if helm_config_overrides_string is None:
        helm_config_overrides_string = []

    config = get_config(deployment)

    name = f'{deployment}-{environment}'

    if namespace is None:
        namespace = name
    helm_config_files = [
        f for f in [
            os.path.join('deployments', deployment, 'config', 'common.yaml'),
            os.path.join('deployments', deployment, 'config',
                         f'{environment}.yaml'),
        ] if os.path.exists(f)
    ]

    helm_secret_files = [
        f for f in [
            # Support for secrets in same repo
            os.path.join('deployments', deployment, 'secrets',
                         f'{environment}.yaml'),
            # Support for secrets in a submodule repo
            os.path.join('secrets', 'deployments', deployment, 'secrets',
                         f'{environment}.yaml'),
        ] if os.path.exists(f)
    ]

    if config.get('images'):
        for image in config['images']['images']:
            # We can support other charts that wrap z2jh by allowing various
            # config paths where we set image tags and names.
            # We default to one sublevel, but we can do multiple levels.
            # With the PANGEO chart, we this could be set to `pangeo.jupyterhub.singleuser.image`
            helm_config_overrides_string.append(
                f'{image.helm_substitution_path}.tag={image.tag}')
            helm_config_overrides_string.append(
                f'{image.helm_substitution_path}.name={image.name}')

    with ExitStack() as stack:
        decrypted_secret_files = [
            stack.enter_context(decrypt_file(f)) for f in helm_secret_files
        ]

        # Just in time for k8s access, activate the cluster credentials
        stack.enter_context(cluster_auth(deployment))
        helm_upgrade(
            name,
            namespace,
            chart,
            helm_config_files + decrypted_secret_files,
            helm_config_overrides_implicit,
            helm_config_overrides_string,
            version,
            timeout,
            force,
            atomic,
            cleanup_on_fail,
        )