class KubeDeployTools::ImageRegistry::Driver::Aws

Public Class Methods

new(h) click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 12
def initialize(h)
  super(h)

  check_and_err(
    @registry.config&.has_key?('region'),
    "Expected .image_registries['#{@name}'] to have .config.region to be set "\
    "for the AWS image registry driver, but .config.region is not set "\
    "e.g. .config.region = 'us-west-2'"
  )
end

Public Instance Methods

authorize_command() click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 28
def authorize_command
  login_cmd = get_docker_login
  raise "Unexpected login command: #{login_cmd}" if login_cmd.first(2) != ['docker', 'login']
  login_cmd
end
delete_image(image, dryrun) click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 37
def delete_image(image, dryrun)
  # In the AWS driver, the 'delete many' primitive is the primary one.
  delete_images([image], dryrun)
end
delete_images(images, dryrun) click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 42
def delete_images(images, dryrun)
  # Aggregate images by repository and call aws ecr batch-delete-image
  # once per repository.
  ids_by_repository = {}
  images.each do |image|
    repository, tag = split_full_image_id(image)
    item = {'imageTag': tag}
    if ids_by_repository[repository].nil?
      ids_by_repository[repository] = [item]
    else
      ids_by_repository[repository].push(item)
    end
  end

  # JSON format documented here:
  # https://docs.aws.amazon.com/cli/latest/reference/ecr/batch-delete-image.html
  ids_by_repository.each do |repository, image_ids|
    # batch-delete-image has a threshold of 100 image_ids at a time
    image_chunks = image_ids.each_slice(100).to_a

    image_chunks.each do |images|
      cmd = [
        'aws', 'ecr', 'batch-delete-image',
        '--repository-name', repository,
        '--region', @registry.config.fetch('region'),
        '--image-ids', images.to_json,
      ]

      if dryrun
        Logger.info("Would run: #{cmd}")
      else
        Shellrunner.check_call(*cmd)
      end
    end
  end
end
push_image(image) click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 23
def push_image(image)
  create_repository(image.repository) unless repository_exists?(image.repository)
  super(image)
end
unauthorize() click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 34
def unauthorize
end

Private Instance Methods

create_repository(repository) click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 102
def create_repository(repository)
  Shellrunner.check_call('aws', 'ecr', 'create-repository', '--repository-name', repository, '--region', @registry.config.fetch('region'))
end
get_docker_login() click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 80
def get_docker_login
  args = Shellrunner.check_call('aws', 'ecr', 'get-login', '--region', @registry.config.fetch('region')).split

  # Remove '-e' and subsequent argument
  # This compensates for --no-include-email not being recognized in the Ubuntu packaged awscli
  # and not usable unless you upgrade
  i = args.index('-e')
  if !i.nil?
    # delete '-e'
    args.delete_at(i)
    # delete whatever value is after (usually 'none')
    args.delete_at(i)
  end

  args
end
repository_exists?(repository) click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 97
def repository_exists?(repository)
  _, _, status = Shellrunner.run_call('aws', 'ecr', 'describe-repositories', '--repository-names', repository, '--region', @registry.config.fetch('region'))
  status.success?
end
split_full_image_id(image_id) click to toggle source
# File lib/kube_deploy_tools/image_registry/driver/aws.rb, line 106
def split_full_image_id(image_id)
  # Create syntax suitable for aws ecr subcommand.
  # Example: 12345678.dkr.ecr.amazonaws.com/my_app:deadbeef-123
  # splits into ('my_app', 'deadbeef-123') after verifying that the
  # prefix is the expected one for this driver instance.
  repo_with_prefix, tag = image_id.split(':', 2)
  prefix, repository = repo_with_prefix.split('/', 2)

  # Sanity check, as the resultant command line uses the region to specify
  # the prefix implicitly.
  raise "This driver can't delete images from #{prefix}, only #{@registry.prefix}" unless prefix == @registry.prefix

  return repository, tag
end