docker-remote 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f8dcfda8b4cbf58474274964a653f5049f609333bf88d1b9497205a4bb366e6e
4
+ data.tar.gz: 9ec104d6e95619a579b0e8e4049d00d6e1eb68c425f7490a83a12477ca812e21
5
+ SHA512:
6
+ metadata.gz: 96faa086fc0223dc3377c77e57042b806f446923156c46bf6627438d64104c06bcadcda9674901a830f209ab68abb09a79335893df8e9428472d292e62dc8c83
7
+ data.tar.gz: '038eb80f159cc9c1c0a3740923c55a4c351c156b10a1e641aaaf4f3d7ceab790fe03d1ca0001f5b2b150978acf8f3e709654764b1e9ab9e950874d2837b54c59'
@@ -0,0 +1,2 @@
1
+ ## 0.1.0
2
+ * Birthday!
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake'
7
+ end
8
+
9
+ group :test do
10
+ gem 'rspec'
11
+ end
@@ -0,0 +1,14 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubygems/package_task'
4
+
5
+ require 'docker/remote'
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ task default: :spec
10
+
11
+ desc 'Run specs'
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.pattern = './spec/**/*_spec.rb'
14
+ end
@@ -0,0 +1,17 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
2
+ require 'docker/remote/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'docker-remote'
6
+ s.version = ::Docker::Remote::VERSION
7
+ s.authors = ['Cameron Dutro']
8
+ s.email = ['camertron@gmail.com']
9
+ s.homepage = 'http://github.com/getkuby/docker-remote'
10
+
11
+ s.description = s.summary = 'A Ruby client for communicating with the Docker HTTP API v2.'
12
+
13
+ s.platform = Gem::Platform::RUBY
14
+
15
+ s.require_path = 'lib'
16
+ s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'CHANGELOG.md', 'README.md', 'Rakefile', 'docker-remote.gemspec']
17
+ end
@@ -0,0 +1,9 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module Docker
5
+ module Remote
6
+ autoload :Client, 'docker/remote/client'
7
+ autoload :ServerAuth, 'docker/remote/server_auth'
8
+ end
9
+ end
@@ -0,0 +1,114 @@
1
+ require 'json'
2
+
3
+ module Docker
4
+ module Remote
5
+ class ClientError < StandardError; end
6
+ class ServerError < StandardError; end
7
+ class UnauthorizedError < ClientError; end
8
+ class NotFoundError < ClientError; end
9
+
10
+ class Client
11
+ attr_reader :registry_url, :repo, :username, :password
12
+
13
+ def initialize(registry_url, repo, username = nil, password = nil)
14
+ @registry_url = registry_url
15
+ @repo = repo
16
+ @username = username
17
+ @password = password
18
+ end
19
+
20
+ def tags
21
+ request = make_get("/v2/#{repo}/tags/list")
22
+ response = registry_http.request(request)
23
+ potentially_raise_error!(response)
24
+ JSON.parse(response.body)['tags']
25
+ end
26
+
27
+ def manifest_for(reference)
28
+ request = make_get("/v2/#{repo}/manifests/#{reference}")
29
+ response = registry_http.request(request)
30
+ potentially_raise_error!(response)
31
+ JSON.parse(response.body)
32
+ end
33
+
34
+ def catalog
35
+ request = make_get("/v2/_catalog")
36
+ response = registry_http.request(request)
37
+ potentially_raise_error!(response)
38
+ JSON.parse(response.body)
39
+ end
40
+
41
+ private
42
+
43
+ def token
44
+ @token ||= begin
45
+ uri = URI.parse(server_auth.realm)
46
+ http = Net::HTTP.new(uri.host, uri.port)
47
+ http.use_ssl = true if uri.scheme == 'https'
48
+
49
+ request = Net::HTTP::Get.new(
50
+ "#{uri.request_uri}?service=#{server_auth.service}&scope=repository:#{repo}:pull"
51
+ )
52
+
53
+ if username && password
54
+ request.basic_auth(username, password)
55
+ end
56
+
57
+ response = http.request(request)
58
+ potentially_raise_error!(response)
59
+ JSON.parse(response.body)['token']
60
+ end
61
+ end
62
+
63
+ def server_auth
64
+ @server_auth ||= begin
65
+ request = Net::HTTP::Get.new('/v2/')
66
+ response = registry_http.request(request)
67
+ auth = response['www-authenticate']
68
+
69
+ idx = auth.index(' ')
70
+ auth_type = auth[0..idx].strip
71
+
72
+ params = auth[idx..-1].split(',').each_with_object({}) do |param, ret|
73
+ key, value = param.split('=')
74
+ ret[key.strip] = value.strip[1..-2] # remove quotes
75
+ end
76
+
77
+ ServerAuth.new(auth_type, params)
78
+ end
79
+ end
80
+
81
+ def registry_uri
82
+ @registry_uri ||= URI.parse(registry_url)
83
+ end
84
+
85
+ def registry_http
86
+ @registry_http ||= Net::HTTP.new(registry_uri.host, registry_uri.port).tap do |http|
87
+ http.use_ssl = true if registry_uri.scheme == 'https'
88
+ end
89
+ end
90
+
91
+ def make_get(path)
92
+ Net::HTTP::Get.new(path).tap do |request|
93
+ request['Authorization'] = "Bearer #{token}"
94
+ end
95
+ end
96
+
97
+ def potentially_raise_error!(response)
98
+ case response.code.to_i
99
+ when 401
100
+ raise UnauthorizedError, "401 Unauthorized: #{response.message}"
101
+ when 404
102
+ raise NotFoundError, "404 Not Found: #{response.message}"
103
+ end
104
+
105
+ case response.code.to_i / 100
106
+ when 4
107
+ raise ClientError, "#{response.code}: #{response.message}"
108
+ when 5
109
+ raise ServerError, "#{response.code}: #{response.message}"
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,20 @@
1
+ module Docker
2
+ module Remote
3
+ class ServerAuth
4
+ attr_reader :auth_type, :params
5
+
6
+ def initialize(auth_type, params)
7
+ @auth_type = auth_type
8
+ @params = params
9
+ end
10
+
11
+ def realm
12
+ @params['realm']
13
+ end
14
+
15
+ def service
16
+ @params['service']
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module Docker
2
+ module Remote
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: docker-remote
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cameron Dutro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-21 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Ruby client for communicating with the Docker HTTP API v2.
14
+ email:
15
+ - camertron@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - CHANGELOG.md
21
+ - Gemfile
22
+ - Rakefile
23
+ - docker-remote.gemspec
24
+ - lib/docker/remote.rb
25
+ - lib/docker/remote/client.rb
26
+ - lib/docker/remote/server_auth.rb
27
+ - lib/docker/remote/version.rb
28
+ homepage: http://github.com/getkuby/docker-remote
29
+ licenses: []
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.0.6
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: A Ruby client for communicating with the Docker HTTP API v2.
50
+ test_files: []