def test_get_docker_repository():
    c = Component("service/test-service")
    c.image_prefix = ""
    assert c.get_docker_repository() == f"service-test-service"

    c = Component("service/test-service")
    c.image_prefix = "myproj-"
    assert c.get_docker_repository() == f"myproj-service-test-service"
def test_get_full_docker_name():
    c = Component("service/test-service")
    c.image_prefix = ""
    assert c._get_full_docker_name() == "service-test-service:latest"

    c = Component("service/test-service")
    c.image_prefix = "myproj-"
    c.tag = "v1.2.3"
    assert c._get_full_docker_name() == "myproj-service-test-service:v1.2.3"
def test_patch_replicas():
    deploy = get_deployment()
    c = Component("service/test-service")
    c.replicas = 77
    c._patch_replicas(deploy)

    assert deploy["spec"]["replicas"] == 77
def test_patch_image_pull_secrets():
    deploy = get_deployment()
    c = Component("service/test-service")
    c.image_pull_secrets = {"imagined.registry.tld": "secret"}
    c._patch_image_pull_secrets(deploy)
    spec = deploy["spec"]["template"]["spec"]
    assert spec["imagePullSecrets"][0]["name"] == "secret"
Example #5
0
def build_images(ctx, components, dry_run=False, docker_args=None):
    big_label(
        logger.info,
        f"Building images{f' with args: {docker_args}' if docker_args else ''}",
    )
    for c in components:
        component = Component(c)
        component.build(ctx, dry_run, docker_args)
def test_handling_long_nested_image_name():
    deploy = get_deployment()
    c = Component("service/test-service")
    c.image = "gcr.io/google-containers/etcd-amd64:3.3.10-1"
    c.image_pull_secrets = {"gcr.io": "secret"}

    c._patch_image_pull_secrets(deploy)
    spec = deploy["spec"]["template"]["spec"]
    assert spec["imagePullSecrets"][0]["name"] == "secret"
def test_patch_containers():
    deploy = get_deployment()
    c = Component("service/test-service")
    c.image_prefix = ""
    c.image = "test-image"
    c.tag = "v6.6.6"
    c._patch_containers(deploy)

    container = deploy["spec"]["template"]["spec"]["containers"][0]
    assert container["image"] == "test-image:v6.6.6"
Example #8
0
def validate_release_configs(ctx):
    envs = list_envs()
    for env in envs:
        logger.info("Validating configs for {} environment".format(env))
        settings = load_env_settings(env)
        components = settings.COMPONENTS

        for path in components:
            component = Component(path)
            component.validate(ctx)
            component.patch_from_env(env)
            component.validate(ctx)
Example #9
0
def update_from_templates(ctx):
    envs = list_envs()

    rendered_files = []
    for env in envs:
        settings = load_env_settings(env)
        components = settings.COMPONENTS

        for path in components:
            component = Component(path)
            rendered_files.extend(component.render_templates(env, settings))

    return rendered_files
def test_patch_cronjob():
    cronjob = get_cronjob()
    c = Component("service/test-cronjob")
    c.image_pull_secrets = {"imagined.registry.tld": "secret"}
    c.image_prefix = ""
    c.image = "imagined.registry.tld/test-image"
    c.tag = "v6.6.7"

    c._patch_cronjob(cronjob)
    # Assert image
    spec = cronjob["spec"]["jobTemplate"]["spec"]["template"]["spec"]
    cronjob_image = spec["containers"][0]["image"]
    assert cronjob_image == "imagined.registry.tld/test-image:v6.6.7"
    # Assert imagePullSecrets
    assert spec["imagePullSecrets"][0]["name"] == "secret"
Example #11
0
def test_patch_containers_with_default_tag():
    deploy = get_deployment()
    c = Component("service/test-service")
    c.image_prefix = ""

    c._patch_containers(deploy)
    container = deploy["spec"]["template"]["spec"]["containers"][0]
    assert (
        container["image"] == "imagined.registry.tld/myproj-service-test-deployment:v1"
    )

    c.tag = "v2"
    c._patch_containers(deploy)
    container = deploy["spec"]["template"]["spec"]["containers"][0]
    assert (
        container["image"] == "imagined.registry.tld/myproj-service-test-deployment:v2"
    )
Example #12
0
def update_from_templates():
    envs = list_envs()

    rendered_files = []
    for env in envs:
        settings = load_env_settings(env)
        enabled_components = set(settings.COMPONENTS)

        components_in_filesystem = {
            p.parent.relative_to("envs", env, "merges").as_posix()
            for p in Path("envs", env, "merges").glob("**/kube")
        }
        components_in_filesystem |= {
            p.parent.relative_to("envs", env, "overrides").as_posix()
            for p in Path("envs", env, "overrides").glob("**/kube")
        }

        for path in enabled_components | components_in_filesystem:
            component = Component(path)
            rendered_files.extend(component.render_templates(env, settings))

    return rendered_files
Example #13
0
def release(
    ctx,
    env,
    component=None,
    image=None,
    tag=None,
    replicas=None,
    dry_run=False,
    keep_configs=False,
    no_rollout_wait=False,
):
    tags: dict = {}
    images: dict = {}
    replica_counts: dict = {}
    components: List[str] = []

    if image:
        for i in image:
            path, value = i.split("=")
            images[path] = value

    if tag:
        for t in tag:
            path, value = t.split("=")
            tags[path] = value

    if replicas:
        for r in replicas:
            path, value = r.split("=")
            replica_counts[path] = value

    rel_id = generate_release_id()
    big_label(logger.info, f"Release {rel_id} to {env} environment starting")
    settings = load_env_settings(env)

    if component:
        components = component
    else:
        components = settings.COMPONENTS

    # Override env settings for replicas
    if replica_counts:
        for path in replica_counts:
            settings.REPLICAS[path] = replica_counts[path]

    rel_path = RELEASE_TMP / rel_id

    logger.info("")
    logger.info("Releasing components:")
    for component in components:
        logger.info(f" - {component}")

    logger.info("")
    logger.info("Setting images and tags:")
    for path in components:
        tag = "(default)"
        image = "(default)"

        if path in tags:
            tag = tags[path]
        if path in images:
            image = images[path]

        logger.info(f" - {path} = {image}:{tag}")
    logger.info("")

    ensure_context(settings.KUBE_CONTEXT)
    ensure_namespace(settings.KUBE_NAMESPACE)
    release_env(ctx, env, dry_run)

    for path in components:
        logger.info("")
        label(logger.info, f"Releasing component {path}")

        component = Component(path)
        if path in images:
            component.image = images[path]
            images.pop(path)
        if path in tags:
            component.tag = tags[path]
            tags.pop(path)
        if path in settings.REPLICAS:
            component.replicas = settings.REPLICAS[path]
            replica_counts.pop(path, None)

        component.namespace = settings.KUBE_NAMESPACE
        component.context = settings.KUBE_CONTEXT
        component.image_pull_secrets = settings.IMAGE_PULL_SECRETS

        component.patch_from_env(env)
        component.validate(ctx)

        component.release(ctx, rel_path, dry_run, no_rollout_wait)

    if images:
        logger.error("Unprocessed image configurations:")
        for path in images:
            logger.error(f" - {path}={images[path]}")

    if tags:
        logger.error("Unprocessed tag configurations:")
        for path in tags:
            logger.error(f" - {path}={tags[path]}")

    if replica_counts:
        logger.error("Unprocessed replica configurations:")
        for path in replica_counts:
            logger.error(f" - {path}={replica_counts[path]}")

    if not keep_configs:
        logger.info(f"Removing temporary configurations from {rel_path}")
        if rel_path.exists():
            rmtree(rel_path)
Example #14
0
def build_images(ctx, components, dry_run=False):
    big_label(logger.info, "Building images")
    for c in components:
        component = Component(c)
        component.build(ctx, dry_run)