StarkAndWayne/bosh-bootstrap

View on GitHub
lib/bosh-bootstrap/public_stemcells.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'httpclient'
require 'rexml/document'

require 'bosh-bootstrap/public_stemcell'

module Bosh::Bootstrap
  class PublicStemcells
    PUBLIC_STEMCELLS_BASE_URL = 'https://bosh-jenkins-artifacts.s3.amazonaws.com'

    def has_stemcell?(stemcell_filename)
      all.any? { |stemcell| stemcell.name == stemcell_filename }
    end

    def find(stemcell_filename)
      all.detect { |stemcell| stemcell.name == stemcell_filename }
    end

    def all
      response = self.class.http_client.get(PUBLIC_STEMCELLS_BASE_URL, {'prefix' => 'bosh-stemcell'})
      doc = REXML::Document.new(response.body)
      stemcells_tags = parse_document(doc)
      stemcells = parse_stemcells(stemcells_tags)

      while is_truncated(doc)
        response = self.class.http_client.get(PUBLIC_STEMCELLS_BASE_URL, {
          'prefix' => 'bosh-stemcell',
          'marker' => stemcells_tags.last.get_text('Key').value
        })

        doc = REXML::Document.new(response.body)
        stemcells_tags = parse_document(doc)
        stemcells += parse_stemcells(stemcells_tags)
      end

      stemcells
    end

    def recent
      stemcell_varietes = all.reject(&:legacy?).group_by(&:variety).values
      stemcell_varietes.map { |stemcells| stemcells.sort_by(&:version).last }
    end

    private

    def parse_document(doc)
      REXML::XPath.match(doc, "/ListBucketResult/Contents[Key[text()[not(contains(.,'latest'))]]]")
    end

    def parse_stemcells(stemcell_tags)
      stemcell_tags.map do |stemcell_tag|
        stemcell_key = stemcell_tag.get_text('Key').value
        stemcell_size = Integer(stemcell_tag.get_text('Size').value)
        PublicStemcell.new(stemcell_key, stemcell_size)
      end
    end

    def is_truncated(doc)
      REXML::XPath.match(doc, "/ListBucketResult/IsTruncated").first.get_text == 'true'
    end

    def self.http_client
      @http_client ||= HTTPClient.new
    end
  end
end