lib/docker/remote/client.rb in docker-remote-0.1.0 vs lib/docker/remote/client.rb in docker-remote-0.2.0
- old
+ new
@@ -1,69 +1,48 @@
require 'json'
+require 'net/http'
+require 'uri'
module Docker
module Remote
- class ClientError < StandardError; end
- class ServerError < StandardError; end
- class UnauthorizedError < ClientError; end
- class NotFoundError < ClientError; end
-
class Client
+ include Utils
+
attr_reader :registry_url, :repo, :username, :password
def initialize(registry_url, repo, username = nil, password = nil)
@registry_url = registry_url
@repo = repo
@username = username
@password = password
end
def tags
- request = make_get("/v2/#{repo}/tags/list")
+ request = auth.make_get("/v2/#{repo}/tags/list")
response = registry_http.request(request)
potentially_raise_error!(response)
JSON.parse(response.body)['tags']
end
def manifest_for(reference)
- request = make_get("/v2/#{repo}/manifests/#{reference}")
+ request = auth.make_get("/v2/#{repo}/manifests/#{reference}")
response = registry_http.request(request)
potentially_raise_error!(response)
JSON.parse(response.body)
end
def catalog
- request = make_get("/v2/_catalog")
+ request = auth.make_get("/v2/_catalog")
response = registry_http.request(request)
potentially_raise_error!(response)
JSON.parse(response.body)
end
private
- def token
- @token ||= begin
- uri = URI.parse(server_auth.realm)
- http = Net::HTTP.new(uri.host, uri.port)
- http.use_ssl = true if uri.scheme == 'https'
-
- request = Net::HTTP::Get.new(
- "#{uri.request_uri}?service=#{server_auth.service}&scope=repository:#{repo}:pull"
- )
-
- if username && password
- request.basic_auth(username, password)
- end
-
- response = http.request(request)
- potentially_raise_error!(response)
- JSON.parse(response.body)['token']
- end
- end
-
- def server_auth
- @server_auth ||= begin
+ def auth
+ @auth ||= begin
request = Net::HTTP::Get.new('/v2/')
response = registry_http.request(request)
auth = response['www-authenticate']
idx = auth.index(' ')
@@ -72,42 +51,27 @@
params = auth[idx..-1].split(',').each_with_object({}) do |param, ret|
key, value = param.split('=')
ret[key.strip] = value.strip[1..-2] # remove quotes
end
- ServerAuth.new(auth_type, params)
+ case auth_type.downcase
+ when 'bearer'
+ BearerAuth.new(params, repo, username, password)
+ when 'basic'
+ BasicAuth.new(username, password)
+ else
+ raise UnsupportedAuthTypeError, "unsupported Docker auth type '#{auth_type}'"
+ end
end
end
def registry_uri
@registry_uri ||= URI.parse(registry_url)
end
def registry_http
@registry_http ||= Net::HTTP.new(registry_uri.host, registry_uri.port).tap do |http|
http.use_ssl = true if registry_uri.scheme == 'https'
- end
- end
-
- def make_get(path)
- Net::HTTP::Get.new(path).tap do |request|
- request['Authorization'] = "Bearer #{token}"
- end
- end
-
- def potentially_raise_error!(response)
- case response.code.to_i
- when 401
- raise UnauthorizedError, "401 Unauthorized: #{response.message}"
- when 404
- raise NotFoundError, "404 Not Found: #{response.message}"
- end
-
- case response.code.to_i / 100
- when 4
- raise ClientError, "#{response.code}: #{response.message}"
- when 5
- raise ServerError, "#{response.code}: #{response.message}"
end
end
end
end
end