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"
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"
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)
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"
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" )
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
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)
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)