hyperb 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +12 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +41 -0
  6. data/Dockerfile +7 -0
  7. data/Gemfile +16 -0
  8. data/LICENSE.txt +21 -0
  9. data/Makefile +16 -0
  10. data/README.md +188 -0
  11. data/Rakefile +24 -0
  12. data/circle.yml +13 -0
  13. data/examples/README.md +367 -0
  14. data/examples/auth-gcr-registry.md +19 -0
  15. data/examples/compose.md +75 -0
  16. data/examples/handling-errors.md +54 -0
  17. data/examples/streaming-logs.md +28 -0
  18. data/examples/streaming-stats.md +25 -0
  19. data/hyperb.gemspec +30 -0
  20. data/lib/hyperb.rb +4 -0
  21. data/lib/hyperb/api.rb +22 -0
  22. data/lib/hyperb/auth_object.rb +42 -0
  23. data/lib/hyperb/client.rb +32 -0
  24. data/lib/hyperb/compose/compose.rb +116 -0
  25. data/lib/hyperb/containers/container.rb +27 -0
  26. data/lib/hyperb/containers/containers.rb +251 -0
  27. data/lib/hyperb/error.rb +44 -0
  28. data/lib/hyperb/hyper_version.rb +12 -0
  29. data/lib/hyperb/images/image.rb +13 -0
  30. data/lib/hyperb/images/images.rb +108 -0
  31. data/lib/hyperb/network/fips.rb +102 -0
  32. data/lib/hyperb/request.rb +129 -0
  33. data/lib/hyperb/services/services.rb +59 -0
  34. data/lib/hyperb/snapshots/snapshot.rb +12 -0
  35. data/lib/hyperb/snapshots/snapshots.rb +39 -0
  36. data/lib/hyperb/utils.rb +39 -0
  37. data/lib/hyperb/version.rb +3 -0
  38. data/lib/hyperb/volumes/volume.rb +16 -0
  39. data/lib/hyperb/volumes/volumes.rb +67 -0
  40. data/spec/auth_object_spec.rb +45 -0
  41. data/spec/client_spec.rb +27 -0
  42. data/spec/compose_spec.rb +145 -0
  43. data/spec/container_spec.rb +25 -0
  44. data/spec/containers_spec.rb +442 -0
  45. data/spec/create_snapshot.rb +30 -0
  46. data/spec/error_spec.rb +18 -0
  47. data/spec/fixtures/auth_obj.json +12 -0
  48. data/spec/fixtures/compose_rm.json +1 -0
  49. data/spec/fixtures/compose_up.json +1 -0
  50. data/spec/fixtures/container_stats.json +78 -0
  51. data/spec/fixtures/containers.json +160 -0
  52. data/spec/fixtures/create_container.json +4 -0
  53. data/spec/fixtures/create_image.json +1 -0
  54. data/spec/fixtures/create_service.json +35 -0
  55. data/spec/fixtures/create_snapshot.json +8 -0
  56. data/spec/fixtures/fip_allocate.json +7 -0
  57. data/spec/fixtures/fips_ls.json +14 -0
  58. data/spec/fixtures/images.json +32 -0
  59. data/spec/fixtures/inspect_container.json +159 -0
  60. data/spec/fixtures/inspect_image.json +89 -0
  61. data/spec/fixtures/inspect_volume.json +11 -0
  62. data/spec/fixtures/remove_container.json +1 -0
  63. data/spec/fixtures/remove_image.json +5 -0
  64. data/spec/fixtures/volumes.json +13 -0
  65. data/spec/helper.rb +36 -0
  66. data/spec/image_spec.rb +17 -0
  67. data/spec/images_spec.rb +133 -0
  68. data/spec/network_spec.rb +106 -0
  69. data/spec/request_spec.rb +41 -0
  70. data/spec/services_spec.rb +193 -0
  71. data/spec/version_spec.rb +7 -0
  72. data/spec/volumes_spec.rb +88 -0
  73. metadata +74 -3
@@ -0,0 +1,19 @@
1
+ ## Authenticating in GCR
2
+
3
+ Assuming you already setup google cloud and you have in hands a [service account](https://cloud.google.com/container-registry/docs/advanced-authentication)
4
+
5
+ Example:
6
+
7
+ ```ruby
8
+
9
+ x_registry_auth = {
10
+ username: '_json_key',
11
+ password: File.new('./path/to/service-account.json'),
12
+ email: 'email@email.com',
13
+ serveraddress: 'https://gcr.io'
14
+ }
15
+
16
+ image = client.create_image(from_image: 'gcr.io/private/repo/image', x_registry_auth)
17
+ puts image
18
+
19
+ ```
@@ -0,0 +1,75 @@
1
+ ## Usage examples of compose
2
+
3
+ Assuming you already configured your client.
4
+
5
+ All compose methods returns a streamable [HTTP::Response::Body]() object
6
+
7
+ **Create a Hash representing a [compose file](https://docs.hyper.sh/Reference/compose_file_ref.html) services block**
8
+
9
+ ```ruby
10
+ services = {
11
+ 'db': {
12
+ 'environment': [
13
+ "MYSQL_ROOT_PASSWORD=my-secret-pw"
14
+ ],
15
+ 'external_links': nil,
16
+ 'image': 'mysql:latest'
17
+ },
18
+ 'web': {
19
+ 'depends_on': [
20
+ 'db'
21
+ ],
22
+ 'external_links': nil,
23
+ 'image': 'wordpress:latest',
24
+ 'links': ['db:mysql']
25
+ }
26
+ }
27
+ ```
28
+
29
+ after setting up a service hash, you may use up, or create.
30
+
31
+ ```ruby
32
+ up = client.compose_up project: 'wp', serviceconfigs: services
33
+
34
+ while body = up.readpartial(1024)
35
+ puts body
36
+ end
37
+
38
+ create = client.compose_create project: 'wp2', serviceconfigs: services
39
+ create = client.compose_create project: 'wp2', serviceconfigs: services, norecreate: true
40
+ create = client.compose_create project: 'wp2', serviceconfigs: services, forcerecreate: true
41
+
42
+ while body = create.readpartial(1024)
43
+ puts body
44
+ end
45
+ ```
46
+
47
+ **Stoping and removing a compose project (down)**
48
+
49
+ ```ruby
50
+ client.compose_down project: 'wp'
51
+ ```
52
+
53
+ ```ruby
54
+ client.compose_down project: 'wp', rmi: true
55
+ ```
56
+
57
+ ```ruby
58
+ client.compose_down project: 'wp', rmorphans: true
59
+ ```
60
+
61
+ ```ruby
62
+ client.compose_down project: 'wp', vol: true
63
+ ```
64
+
65
+ **Deleting a compose project**
66
+
67
+ ```ruby
68
+ client.compose_rm project: 'wp'
69
+ ```
70
+
71
+ **remove all attached volumes**
72
+
73
+ ```ruby
74
+ client.compose_rm project: 'wp', rmvol: true
75
+ ```
@@ -0,0 +1,54 @@
1
+ ## Handling errors
2
+
3
+ Hyperb has set of exceptions representing Hyper.sh errors.
4
+
5
+ #### Hyperb::Errors::Unauthorized
6
+
7
+ raised when credentials are invalid
8
+
9
+ #### Hyperb::Errors::NotFound
10
+
11
+ raised when resource can't be found
12
+
13
+ #### Hyperb::Errors::InternalServerError
14
+
15
+ raised when hyper.sh server returns 500
16
+
17
+ #### Hyperb::Errors::Conflict
18
+
19
+ usually when a container or image can't be deleted or stopped for some reason.
20
+
21
+ #### Hyperb::Errors::NotModified
22
+
23
+ usually when a container can't be stopped because it was already stopped.
24
+
25
+ Examples:
26
+
27
+ ```ruby
28
+
29
+ begin
30
+ stats = client.container_stats id: 'nginxy', stream: true
31
+
32
+ while body = stats.readpartial(1024)
33
+ puts body
34
+ end
35
+
36
+ rescue Exception => e
37
+ puts 'got something'
38
+ puts e.message
39
+ end
40
+ ```
41
+
42
+ ```ruby
43
+
44
+ begin
45
+ stats = client.container_stats id: 'nginxy', stream: true
46
+
47
+ while body = stats.readpartial(1024)
48
+ puts body
49
+ end
50
+
51
+ rescue Hyperb::Errors::NotFound => e
52
+ puts 'container not found'
53
+ end
54
+ ```
@@ -0,0 +1,28 @@
1
+ ## Streaming container_logs
2
+
3
+ Assuming you already configured your client, and you have a running container.
4
+
5
+ Hyperb uses [httprb](https://github.com/httprb/http) as the underlying http client, it supports streaming by default,
6
+ by calling the `readpartial`
7
+
8
+ For continuous streaming of the logs, use `follow: true`
9
+
10
+ Example:
11
+
12
+ ```ruby
13
+
14
+ logs = client.container_logs id: 'nginx', stdout: true, stderr: true, follow: true
15
+
16
+ while body = logs.readpartial(1024)
17
+ puts body
18
+ end
19
+
20
+ ```
21
+
22
+ ```ruby
23
+
24
+ logs = client.container_logs id: 'nginx', stdout: true, stderr: true, tail: 30
25
+
26
+ puts logs
27
+
28
+ ```
@@ -0,0 +1,25 @@
1
+ ## Streaming container_stats
2
+
3
+ Assuming you already configured your client, and you have a running container.
4
+
5
+ For continuous streaming of the stats, use `stream: true`
6
+
7
+ Examples:
8
+
9
+ ```ruby
10
+ # stream by default
11
+ stats = client.container_stats id: 'nginx'
12
+
13
+ while body = stats.readpartial(1024)
14
+ puts body
15
+ end
16
+
17
+ ```
18
+
19
+ ```ruby
20
+
21
+ stats = client.container_stats id: 'nginx', stream: false
22
+
23
+ puts stats
24
+
25
+ ```
data/hyperb.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hyperb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'hyperb'
8
+ spec.version = Hyperb::VERSION
9
+ spec.authors = ['drish']
10
+ spec.email = ['carlosderich@gmail.com']
11
+
12
+ spec.description = %q{The Hyper.sh Ruby Gem}
13
+ spec.homepage = 'https://github.com/drish/hyperb'
14
+ spec.summary = spec.description
15
+ spec.license = 'MIT'
16
+
17
+ spec.require_paths = ['lib']
18
+ spec.files = `git ls-files`.split("\n")
19
+
20
+ spec.add_dependency 'http', '~> 2.0'
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.8'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'webmock', '~> 3.0', '>= 3.0.1'
25
+ spec.add_development_dependency 'simplecov', '~> 0.9'
26
+ spec.add_development_dependency 'rspec', '~> 3.0'
27
+ spec.add_development_dependency 'pry', '~> 0.10.4'
28
+
29
+ spec.required_ruby_version = '>= 2.2'
30
+ end
data/lib/hyperb.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'hyperb/version'
2
+ require 'hyperb/client'
3
+ require 'hyperb/auth_object'
4
+ require 'hyperb/hyper_version'
data/lib/hyperb/api.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'hyperb/images/images'
2
+ require 'hyperb/containers/containers'
3
+ require 'hyperb/snapshots/snapshots'
4
+ require 'hyperb/services/services'
5
+ require 'hyperb/volumes/volumes'
6
+ require 'hyperb/network/fips'
7
+ require 'hyperb/compose/compose'
8
+ require 'hyperb/hyper_version'
9
+
10
+ module Hyperb
11
+ # wrapper for apis
12
+ module API
13
+ include Hyperb::Images
14
+ include Hyperb::Containers
15
+ include Hyperb::Volumes
16
+ include Hyperb::HyperVersion
17
+ include Hyperb::Network
18
+ include Hyperb::Snapshots
19
+ include Hyperb::Services
20
+ include Hyperb::Compose
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ require 'base64'
2
+
3
+ module Hyperb
4
+ # helper for managing auth objects
5
+ # used to authenticate into third party docker registries
6
+ class AuthObject
7
+ attr_accessor :username, :password, :email, :serveraddress
8
+
9
+ def initialize(options = {})
10
+ @username = options[:username] || ''
11
+ @email = options[:email] || ''
12
+ @serveraddress = options[:serveraddress] || ''
13
+ @password = options[:password].is_a?(File) ? options[:password].read : options[:password]
14
+ end
15
+
16
+ # preserve this order
17
+ def attrs
18
+ {
19
+ username: username,
20
+ password: password,
21
+ email: email,
22
+ serveraddress: serveraddress
23
+ }
24
+ end
25
+
26
+ def valid?
27
+ attrs.values.none? { |atr| blank?(atr) }
28
+ end
29
+
30
+ def blank?(val)
31
+ val.respond_to?(:empty?) ? val.empty? : !val
32
+ end
33
+
34
+ def encode
35
+ Base64.urlsafe_encode64(attrs.to_json)
36
+ end
37
+
38
+ def build
39
+ { x_registry_auth: encode }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,32 @@
1
+ require 'hyperb/api'
2
+
3
+ module Hyperb
4
+ # client class
5
+ class Client
6
+ include Hyperb::API
7
+
8
+ attr_accessor :secret_key, :access_key
9
+
10
+ def initialize(options = {})
11
+ options.each do |key, value|
12
+ instance_variable_set("@#{key}", value)
13
+ end
14
+ yield(self) if block_given?
15
+ end
16
+
17
+ def credentials
18
+ {
19
+ secret_key: secret_key,
20
+ access_key: access_key
21
+ }
22
+ end
23
+
24
+ def credentials?
25
+ credentials.values.none? { |cred| blank?(cred) }
26
+ end
27
+
28
+ def blank?(val)
29
+ val.respond_to?(:empty?) ? val.empty? : !val
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,116 @@
1
+ require 'hyperb/request'
2
+ require 'hyperb/utils'
3
+ require 'hyperb/auth_object'
4
+ require 'json'
5
+ require 'uri'
6
+ require 'base64'
7
+
8
+ module Hyperb
9
+ # compose api wrapper
10
+ module Compose
11
+ include Hyperb::Utils
12
+
13
+ # stop and remove a compose project
14
+ #
15
+ # @see https://docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/Compose/compose_down.html
16
+ #
17
+ # @raise [Hyperb::Error::Unauthorized] raised when credentials are not valid.
18
+ # @raise [Hyperb::Error::NotFound] raised ips are not found.
19
+ #
20
+ # @returns [HTTP::Response::Body] a streamable response object
21
+ #
22
+ # @param params [Hash] A customizable set of params.
23
+ # @option params [String] :project project name
24
+ # @option params [Boolean] :rmorphans rm containers for services not defined in the compose file
25
+ # @option params [String] :rmi remove images, all/local
26
+ # @option params [Boolean] :vol remove data volumes
27
+ def compose_down(params = {})
28
+ raise ArgumentError, 'Invalid arguments.' unless check_arguments(params, 'project')
29
+ path = '/compose/down'
30
+ query = {}
31
+ query[:project] = params[:project] if params.key?(:project)
32
+ query[:vol] = params[:vol] if params.key?(:vol)
33
+ query[:rmi] = params[:rmi] if params.key?(:rmi)
34
+ query[:rmorphans] = params[:rmorphans] if params.key?(:rmorphans)
35
+ Hyperb::Request.new(self, path, query, 'post').perform
36
+ end
37
+
38
+ # remove a compose project
39
+ #
40
+ # @see https://docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/Compose/compose_rm.html
41
+ #
42
+ # @raise [Hyperb::Error::Unauthorized] raised when credentials are not valid.
43
+ # @raise [Hyperb::Error::NotFound] raised ips are not found.
44
+ #
45
+ # @returns [HTTP::Response::Body] a streamable response object
46
+ #
47
+ # @param params [Hash] A customizable set of params.
48
+ # @option params [String] :project project name
49
+ # @option params [String] :rmvol project name
50
+ def compose_rm(params = {})
51
+ raise ArgumentError, 'Invalid arguments.' unless check_arguments(params, 'project')
52
+ path = '/compose/rm'
53
+ query = {}
54
+ query[:project] = params[:project] if params.key?(:project)
55
+ query[:rmvol] = params[:rmvol] if params.key?(:rmvol)
56
+ Hyperb::Request.new(self, path, query, 'post').perform
57
+ end
58
+
59
+ # create and run a compose project
60
+ #
61
+ # @see https://docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/Compose/compose_up.html
62
+ #
63
+ # @raise [Hyperb::Error::Unauthorized] raised when credentials are not valid.
64
+ # @raise [Hyperb::Error::NotFound] raised ips are not found.
65
+ #
66
+ # @returns [HTTP::Response::Body] a streamable response object
67
+ #
68
+ # @param params [Hash] A customizable set of params.
69
+ # @option params [String] :project project name
70
+ # @option params [Hash] :serviceconfigs a hash representing a docker compose file services block
71
+ # @option params [Hash] :networkconfigs
72
+ # @option params [Hash] :volumeconfigs
73
+ def compose_up(params = {})
74
+ raise ArgumentError, 'Invalid arguments.' unless check_arguments(params, 'project')
75
+ path = '/compose/up'
76
+ query = {}
77
+ body = {}
78
+ query[:project] = params[:project] if params.key?(:project)
79
+
80
+ body[:serviceconfigs] = { 'M': {} } # inherited from libcompose
81
+ body[:serviceconfigs][:M] = params[:serviceconfigs] if params.key?(:serviceconfigs)
82
+ params.delete(:serviceconfigs)
83
+ body.merge!(params)
84
+ Hyperb::Request.new(self, path, query, 'post', body).perform
85
+ end
86
+
87
+ # create a compose project
88
+ #
89
+ # @see https://docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/
90
+ # Compose/compose_create.html
91
+ #
92
+ # @raise [Hyperb::Error::Unauthorized] raised when credentials are not valid.
93
+ # @raise [Hyperb::Error::NotFound] raised ips are not found.
94
+ #
95
+ # @returns [HTTP::Response::Body] a streamable response object
96
+ #
97
+ # @param params [Hash] A customizable set of params.
98
+ # @option params [String] :project project name
99
+ # @option params [Hash] :serviceconfigs a hash representing a docker compose file services block
100
+ # @option params [Hash] :networkconfigs
101
+ # @option params [Hash] :volumeconfigs
102
+ def compose_create(params = {})
103
+ raise ArgumentError, 'Invalid arguments.' unless check_arguments(params, 'project')
104
+ path = '/compose/create'
105
+ query = {}
106
+ body = {}
107
+ query[:project] = params[:project] if params.key?(:project)
108
+
109
+ body[:serviceconfigs] = { 'M': {} } # inherited from libcompose
110
+ body[:serviceconfigs][:M] = params[:serviceconfigs]
111
+ params.delete(:serviceconfigs)
112
+ body.merge!(params)
113
+ Hyperb::Request.new(self, path, query, 'post', body).perform
114
+ end
115
+ end
116
+ end