rancher.rb 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,131 @@
1
+ require 'faraday'
2
+ require 'set'
3
+
4
+ # Adapted from lostisland/faraday_middleware. Trimmed down to just the logic
5
+ # that we need for Rancher.rb.
6
+ #
7
+ # https://github.com/lostisland/faraday_middleware/blob/138766e/lib/faraday_middleware/response/follow_redirects.rb
8
+
9
+ module Rancher
10
+
11
+ module Middleware
12
+
13
+ # Public: Exception thrown when the maximum amount of requests is exceeded.
14
+ class RedirectLimitReached < Faraday::Error::ClientError
15
+ attr_reader :response
16
+
17
+ def initialize(response)
18
+ super "too many redirects; last one to: #{response['location']}"
19
+ @response = response
20
+ end
21
+ end
22
+
23
+ # Public: Follow HTTP 301, 302, 303, and 307 redirects.
24
+ #
25
+ # For HTTP 303, the original GET, POST, PUT, DELETE, or PATCH request gets
26
+ # converted into a GET. For HTTP 301, 302, and 307, the HTTP method remains
27
+ # unchanged.
28
+ #
29
+ # This middleware currently only works with synchronous requests; i.e. it
30
+ # doesn't support parallelism.
31
+ class FollowRedirects < Faraday::Middleware
32
+ # HTTP methods for which 30x redirects can be followed
33
+ ALLOWED_METHODS = Set.new [:head, :options, :get, :post, :put, :patch, :delete]
34
+
35
+ # HTTP redirect status codes that this middleware implements
36
+ REDIRECT_CODES = Set.new [301, 302, 303, 307]
37
+
38
+ # Keys in env hash which will get cleared between requests
39
+ ENV_TO_CLEAR = Set.new [:status, :response, :response_headers]
40
+
41
+ # Default value for max redirects followed
42
+ FOLLOW_LIMIT = 3
43
+
44
+ # Regex that matches characters that need to be escaped in URLs, sans
45
+ # the "%" character which we assume already represents an escaped
46
+ # sequence.
47
+ URI_UNSAFE = /[^\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]%]/
48
+
49
+ # Public: Initialize the middleware.
50
+ #
51
+ # options - An options Hash (default: {}):
52
+ # :limit - A Fixnum redirect limit (default: 3).
53
+ def initialize(app, options = {})
54
+ super(app)
55
+ @options = options
56
+
57
+ @convert_to_get = Set.new [303]
58
+ end
59
+
60
+ def call(env)
61
+ perform_with_redirection(env, follow_limit)
62
+ end
63
+
64
+ private
65
+
66
+ def convert_to_get?(response)
67
+ ![:head, :options].include?(response.env[:method]) &&
68
+ @convert_to_get.include?(response.status)
69
+ end
70
+
71
+ def perform_with_redirection(env, follows)
72
+ request_body = env[:body]
73
+ response = @app.call(env)
74
+
75
+ response.on_complete do |response_env|
76
+ if follow_redirect?(response_env, response)
77
+ raise(RedirectLimitReached, response) if follows.zero?
78
+ new_request_env = update_env(response_env, request_body, response)
79
+ response = perform_with_redirection(new_request_env, follows - 1)
80
+ end
81
+ end
82
+ response
83
+ end
84
+
85
+ def update_env(env, request_body, response)
86
+ original_url = env[:url]
87
+ env[:url] += safe_escape(response["location"])
88
+ unless same_host?(original_url, env[:url])
89
+ env[:request_headers].delete("Authorization")
90
+ end
91
+
92
+ if convert_to_get?(response)
93
+ env[:method] = :get
94
+ env[:body] = nil
95
+ else
96
+ env[:body] = request_body
97
+ end
98
+
99
+ ENV_TO_CLEAR.each { |key| env.delete(key) }
100
+
101
+ env
102
+ end
103
+
104
+ def follow_redirect?(env, response)
105
+ ALLOWED_METHODS.include?(env[:method]) &&
106
+ REDIRECT_CODES.include?(response.status)
107
+ end
108
+
109
+ def follow_limit
110
+ @options.fetch(:limit, FOLLOW_LIMIT)
111
+ end
112
+
113
+ def same_host?(original_url, redirect_url)
114
+ original_uri = Addressable::URI.parse(original_url)
115
+ redirect_uri = Addressable::URI.parse(redirect_url)
116
+
117
+ redirect_uri.host.nil? || original_uri.host == redirect_uri.host
118
+ end
119
+
120
+ # Internal: Escapes unsafe characters from a URL which might be a path
121
+ # component only or a fully-qualified URI so that it can be joined onto a
122
+ # URI:HTTP using the `+` operator. Doesn't escape "%" characters so to not
123
+ # risk double-escaping.
124
+ def safe_escape(uri)
125
+ uri.to_s.gsub(URI_UNSAFE) { |match|
126
+ "%" + match.unpack("H2" * match.bytesize).join("%").upcase
127
+ }
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,94 @@
1
+ module Rancher
2
+ # A Rancher Resource
3
+ class Resource
4
+ @meta = {}
5
+ @links = []
6
+ @actions = []
7
+
8
+ attr_reader :links, :meta
9
+
10
+ def initialize(body = nil)
11
+ @meta = {}
12
+
13
+ return unless body
14
+ body.each do |key, val|
15
+ @links = val if key == :links
16
+ @actions = val if key == :actions
17
+ continue if key == :body
18
+ @meta[key] = val unless key == :links || key == :actions
19
+ end
20
+ end
21
+
22
+ def save!
23
+ Rancher.put get_link('self'), @meta
24
+ end
25
+
26
+ def remove!
27
+ Rancher.delete get_link('self')
28
+ end
29
+
30
+ def get_link(name)
31
+ @links[name.to_sym] if @links[name.to_sym]
32
+ end
33
+
34
+ def action?(name)
35
+ (@actions[name.to_sym])
36
+ end
37
+
38
+ def in_meta?(name)
39
+ (@meta[name.to_sym])
40
+ end
41
+
42
+ def action(name, *args)
43
+ if action?(name)
44
+ opt = args[0] || {}
45
+ link = @actions[name.to_sym]
46
+ return Rancher.post link, opt
47
+ end
48
+ end
49
+
50
+ def method_missing(method_name, *args, &_block)
51
+ str_method_name = method_name.to_s
52
+ if str_method_name.start_with?('fetch')
53
+ name = str_method_name[6..-1]
54
+ do_fetch(name, *args)
55
+ elsif str_method_name.start_with?('get')
56
+ name = str_method_name[4..-1]
57
+ if @meta.key?(name.to_sym)
58
+ ## Todo Handle TS return in seconds
59
+ @meta[name.to_sym]
60
+ else
61
+ field = schema_field(name)
62
+ fail("Attempted to access unknown property '#{name}'") if field.nil?
63
+ nil
64
+ end
65
+ elsif str_method_name.start_with?('set')
66
+ name = str_method_name[4..-1]
67
+ @meta[name.to_sym] = args[0]
68
+ true
69
+ elsif str_method_name.start_with?('do')
70
+ name = str_method_name[3..-1]
71
+ action(name, *args)
72
+ elsif str_method_name.start_with?('can')
73
+ name = str_method_name[4..-1]
74
+ action?(name)
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def do_fetch(name, *args)
81
+ opts = args[0] || {}
82
+ link = Rancher::Type.list_href(get_link(name), opts)
83
+
84
+ Rancher.get link if link
85
+ end
86
+
87
+ def schema_field(name)
88
+ type_name = get_type
89
+ type = Rancher.types[type_name.to_sym]
90
+
91
+ type.resource_field(name) unless type.nil?
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,21 @@
1
+ require 'faraday'
2
+ require 'rancher/error'
3
+
4
+ module Rancher
5
+ # Faraday response middleware
6
+ module Response
7
+
8
+ # This class raises an Rancher-flavored exception based
9
+ # HTTP status codes returned by the API
10
+ class RaiseError < Faraday::Response::Middleware
11
+
12
+ private
13
+
14
+ def on_complete(response)
15
+ if error = Rancher::Error.from_response(response)
16
+ raise error
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,112 @@
1
+ require 'addressable/uri'
2
+
3
+ module Rancher
4
+ # An Object type inside of Rancher
5
+ class Type
6
+ attr_reader :schema
7
+
8
+ def initialize(schema)
9
+ @schema = schema
10
+ end
11
+
12
+ def by_id(id)
13
+ Rancher.get url(id)
14
+ end
15
+
16
+ def query(filters = {}, sort = {}, pagination = {}, include = {})
17
+ opts = {
18
+ filters: filters,
19
+ sort: sort,
20
+ pagination: pagination,
21
+ include: include
22
+ }
23
+
24
+ link = self.class.list_href(url, opts)
25
+
26
+ Rancher.get link
27
+ end
28
+
29
+ def create(attrs)
30
+ attrs = attrs.meta if attrs.is_a?(Rancher::Resource)
31
+
32
+ Rancher.post url attrs
33
+ end
34
+
35
+ def remove!(id_or_obj)
36
+ id = id_or_obj.get_id if id_or_obj.is_a?(Rancher::Resource)
37
+
38
+ Rancher.delete url(id)
39
+ end
40
+
41
+ def resource_field(name)
42
+ if schema.in_meta?('resourceFields')
43
+ fields = schema.get_resourceFields
44
+ else
45
+ fields = schema.get_fields
46
+ end
47
+
48
+ fields[name.to_sym] if fields[name.to_sym]
49
+ end
50
+
51
+ def collection_field(name)
52
+ fields = @schema.get_collectionFields
53
+ fields[name.to_sym] if fields[name.to_sym]
54
+ end
55
+
56
+ def url(id = nil)
57
+ id = "/#{id}" unless id.nil?
58
+ "#{@schema.get_link('collection')}#{id}"
59
+ end
60
+
61
+ def self.list_href(url, opts)
62
+ qs = []
63
+ opts ||= {}
64
+
65
+ uri = Addressable::URI.parse(url) unless url.empty? || url.nil?
66
+ uri.query_values.each do |key, value|
67
+ qs.push("#{key}=#{value}")
68
+ end if uri.query_values
69
+
70
+ if opts[:filters]
71
+ opts[:filters].each do |field, value|
72
+ qs.push("#{field}=#{value}") unless value.is_a?(Array)
73
+
74
+ next unless value.is_a?(Array)
75
+
76
+ qs.concat value.map do |val|
77
+ if val.is_a?(Hash) && (val.key?(:modifier) || val.key?(:value))
78
+ name = "#{field}"
79
+ name += "_#{val[:modifier]}" if val.key?(:modifier) && val[:modifier] != '' && val[:modifier] != 'eq'
80
+
81
+ str = "#{name}="
82
+
83
+ str += "#{val[:value]}" if val.key?(:value)
84
+
85
+ str
86
+ else
87
+ "#{field}=#{val}"
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ if opts[:sort] && opts[:sort].key?(:name)
94
+ qs.push("sort=#{opts[:sort][:name]}")
95
+ qs.push('order=desc') if opts[:sort].key?(:order) && opts[:sort][:order] == 'desc'
96
+ end
97
+
98
+ if opts[:pagination] && opts[:pagination].key?(:limit)
99
+ qs.push("limit=#{opts[:pagination][:limit]}")
100
+ qs.push("marker=#{opts[:pagination][:marker]}") if opts[:pagination].key?(:marker)
101
+ end
102
+
103
+ qs.concat opts[:include].map do |inc|
104
+ "include=#{inc}"
105
+ end if opts[:include] && opts[:include].is_a?(Array)
106
+
107
+ uri.query = qs.join('&') if qs.size > 0
108
+
109
+ uri.to_s
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,18 @@
1
+ # Set the Gem Version
2
+ module Rancher
3
+ # Current major release.
4
+ # @return [Integer]
5
+ MAJOR = 0
6
+
7
+ # Current minor release.
8
+ # @return [Integer]
9
+ MINOR = 1
10
+
11
+ # Current patch level.
12
+ # @return [Integer]
13
+ PATCH = 0
14
+
15
+ # Full release version.
16
+ # @return [String]
17
+ VERSION = [MAJOR, MINOR, PATCH].join('.').freeze
18
+ end
data/rancher.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rancher/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rancher.rb'
8
+ spec.version = Rancher::VERSION.dup
9
+ spec.authors = ['Jon Whitcraft']
10
+ spec.email = ['jwhitcraft@mac.com']
11
+ spec.summary = %q{Ruby API Client for Rancher}
12
+ spec.description = %q{Consume the API from Rancher with Ruby!}
13
+ spec.homepage = 'https://github.com/jwhitcraft/rancher.rb'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+ spec.add_dependency 'sawyer', '>= 0.5.3', '~> 0.6.0'
23
+ end
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"get","uri":"http://docker.dev:8080/zen?foo=bar","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["text/plain"],"User-Agent":["Rancher Ruby Gem 0.1.0"],"Content-Type":["application/json"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Content-Type":["application/json; charset=utf-8"],"Date":["Thu, 10 Sep 2015 15:24:03 GMT"],"Server":["Jetty(9.2.11.v20150529)"],"Vary":["Accept-Encoding, User-Agent"],"X-Api-Account-Id":["1a1"],"X-Api-Client-Ip":["192.168.99.1"],"X-Api-Schemas":["http://docker.dev:8080/v1/schemas"],"Content-Length":["848"]},"body":{"encoding":"ASCII-8BIT","base64_string":"eyJpZCI6InYxIiwidHlwZSI6ImFwaVZlcnNpb24iLCJsaW5rcyI6eyJhY2Nv\ndW50cyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvYWNjb3VudHMiLCJh\nZ2VudHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2FnZW50cyIsImFw\naUtleXMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2FwaWtleXMiLCJj\nZXJ0aWZpY2F0ZXMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2NlcnRp\nZmljYXRlcyIsImNsdXN0ZXJzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92\nMS9jbHVzdGVycyIsImNvbmZpZ0l0ZW1TdGF0dXNlcyI6Imh0dHA6Ly9kb2Nr\nZXIuZGV2OjgwODAvdjEvY29uZmlnaXRlbXN0YXR1c2VzIiwiY29uZmlnSXRl\nbXMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2NvbmZpZ2l0ZW1zIiwi\nY29udGFpbmVyRXZlbnRzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9j\nb250YWluZXJldmVudHMiLCJjb250YWluZXJFeGVjcyI6Imh0dHA6Ly9kb2Nr\nZXIuZGV2OjgwODAvdjEvY29udGFpbmVyZXhlY3MiLCJjb250YWluZXJzIjoi\naHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9jb250YWluZXJzIiwiY3JlZGVu\ndGlhbHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2NyZWRlbnRpYWxz\nIiwiZGF0YWJhc2VjaGFuZ2Vsb2dsb2NrcyI6Imh0dHA6Ly9kb2NrZXIuZGV2\nOjgwODAvdjEvZGF0YWJhc2VjaGFuZ2Vsb2dsb2NrcyIsImRhdGFiYXNlY2hh\nbmdlbG9ncyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvZGF0YWJhc2Vj\naGFuZ2Vsb2dzIiwiZG5zU2VydmljZXMiOiJodHRwOi8vZG9ja2VyLmRldjo4\nMDgwL3YxL2Ruc3NlcnZpY2VzIiwiZG9ja2VyQnVpbGRzIjoiaHR0cDovL2Rv\nY2tlci5kZXY6ODA4MC92MS9kb2NrZXJidWlsZHMiLCJlbnZpcm9ubWVudHMi\nOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2Vudmlyb25tZW50cyIsImV4\ndGVuc2lvblBvaW50cyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvZXh0\nZW5zaW9ucG9pbnRzIiwiZXh0ZXJuYWxIYW5kbGVyRXh0ZXJuYWxIYW5kbGVy\nUHJvY2Vzc01hcHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2V4dGVy\nbmFsaGFuZGxlcmV4dGVybmFsaGFuZGxlcnByb2Nlc3NtYXBzIiwiZXh0ZXJu\nYWxIYW5kbGVyUHJvY2Vzc2VzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92\nMS9leHRlcm5hbGhhbmRsZXJwcm9jZXNzZXMiLCJleHRlcm5hbEhhbmRsZXJz\nIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9leHRlcm5hbGhhbmRsZXJz\nIiwiZXh0ZXJuYWxTZXJ2aWNlcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAv\ndjEvZXh0ZXJuYWxzZXJ2aWNlcyIsImdpdGh1YmNvbmZpZ3MiOiJodHRwOi8v\nZG9ja2VyLmRldjo4MDgwL3YxL2dpdGh1YmNvbmZpZ3MiLCJnbG9iYWxMb2Fk\nQmFsYW5jZXJzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9nbG9iYWxs\nb2FkYmFsYW5jZXJzIiwiaG9zdEFjY2Vzc2VzIjoiaHR0cDovL2RvY2tlci5k\nZXY6ODA4MC92MS9ob3N0YWNjZXNzZXMiLCJob3N0QXBpUHJveHlUb2tlbnMi\nOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2hvc3RhcGlwcm94eXRva2Vu\ncyIsImhvc3RzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9ob3N0cyIs\nImlkZW50aXRpZXMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2lkZW50\naXRpZXMiLCJpbWFnZXMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2lt\nYWdlcyIsImluc3RhbmNlTGlua3MiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL2luc3RhbmNlbGlua3MiLCJpbnN0YW5jZXMiOiJodHRwOi8vZG9ja2Vy\nLmRldjo4MDgwL3YxL2luc3RhbmNlcyIsImlwQWRkcmVzc2VzIjoiaHR0cDov\nL2RvY2tlci5kZXY6ODA4MC92MS9pcGFkZHJlc3NlcyIsImxhYmVscyI6Imh0\ndHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvbGFiZWxzIiwibGRhcGNvbmZpZ3Mi\nOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2xkYXBjb25maWdzIiwibG9h\nZEJhbGFuY2VyQ29uZmlnTGlzdGVuZXJNYXBzIjoiaHR0cDovL2RvY2tlci5k\nZXY6ODA4MC92MS9sb2FkYmFsYW5jZXJjb25maWdsaXN0ZW5lcm1hcHMiLCJs\nb2FkQmFsYW5jZXJDb25maWdzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92\nMS9sb2FkYmFsYW5jZXJjb25maWdzIiwibG9hZEJhbGFuY2VySG9zdE1hcHMi\nOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL2xvYWRiYWxhbmNlcmhvc3Rt\nYXBzIiwibG9hZEJhbGFuY2VyTGlzdGVuZXJzIjoiaHR0cDovL2RvY2tlci5k\nZXY6ODA4MC92MS9sb2FkYmFsYW5jZXJsaXN0ZW5lcnMiLCJsb2FkQmFsYW5j\nZXJTZXJ2aWNlcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvbG9hZGJh\nbGFuY2Vyc2VydmljZXMiLCJsb2FkQmFsYW5jZXJUYXJnZXRzIjoiaHR0cDov\nL2RvY2tlci5kZXY6ODA4MC92MS9sb2FkYmFsYW5jZXJ0YXJnZXRzIiwibG9h\nZEJhbGFuY2VycyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvbG9hZGJh\nbGFuY2VycyIsIm1hY2hpbmVzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92\nMS9tYWNoaW5lcyIsIm1vdW50cyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAv\ndjEvbW91bnRzIiwibmV0d29ya3MiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL25ldHdvcmtzIiwicGh5c2ljYWxIb3N0cyI6Imh0dHA6Ly9kb2NrZXIu\nZGV2OjgwODAvdjEvcGh5c2ljYWxob3N0cyIsInBvcnRzIjoiaHR0cDovL2Rv\nY2tlci5kZXY6ODA4MC92MS9wb3J0cyIsInByb2Nlc3NEZWZpbml0aW9ucyI6\nImh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvY2Vzc2RlZmluaXRpb25z\nIiwicHJvY2Vzc0V4ZWN1dGlvbnMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL3Byb2Nlc3NleGVjdXRpb25zIiwicHJvY2Vzc0luc3RhbmNlcyI6Imh0\ndHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvY2Vzc2luc3RhbmNlcyIsInBy\nb2plY3RNZW1iZXJzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9q\nZWN0bWVtYmVycyIsInByb2plY3RzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4\nMC92MS9wcm9qZWN0cyIsInJlZ2lzdGVyIjoiaHR0cDovL2RvY2tlci5kZXY6\nODA4MC92MS9yZWdpc3RlciIsInJlZ2lzdHJhdGlvblRva2VucyI6Imh0dHA6\nLy9kb2NrZXIuZGV2OjgwODAvdjEvcmVnaXN0cmF0aW9udG9rZW5zIiwicmVn\naXN0cmllcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcmVnaXN0cmll\ncyIsInJlZ2lzdHJ5Q3JlZGVudGlhbHMiOiJodHRwOi8vZG9ja2VyLmRldjo4\nMDgwL3YxL3JlZ2lzdHJ5Y3JlZGVudGlhbHMiLCJyZXNvdXJjZURlZmluaXRp\nb25zIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9yZXNvdXJjZWRlZmlu\naXRpb25zIiwic2NoZW1hcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEv\nc2NoZW1hcyIsInNlbGYiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3plbiIs\nInNlcnZpY2VDb25zdW1lTWFwcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAv\ndjEvc2VydmljZWNvbnN1bWVtYXBzIiwic2VydmljZUV2ZW50cyI6Imh0dHA6\nLy9kb2NrZXIuZGV2OjgwODAvdjEvc2VydmljZWV2ZW50cyIsInNlcnZpY2VF\neHBvc2VNYXBzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9zZXJ2aWNl\nZXhwb3NlbWFwcyIsInNlcnZpY2VzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4\nMC92MS9zZXJ2aWNlcyIsInNldHRpbmdzIjoiaHR0cDovL2RvY2tlci5kZXY6\nODA4MC92MS9zZXR0aW5ncyIsInNuYXBzaG90cyI6Imh0dHA6Ly9kb2NrZXIu\nZGV2OjgwODAvdjEvc25hcHNob3RzIiwic3RhdHNBY2Nlc3NlcyI6Imh0dHA6\nLy9kb2NrZXIuZGV2OjgwODAvdjEvc3RhdHNhY2Nlc3NlcyIsInN0b3JhZ2VQ\nb29scyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvc3RvcmFnZXBvb2xz\nIiwidGFza0luc3RhbmNlcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEv\ndGFza2luc3RhbmNlcyIsInRhc2tzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4\nMC92MS90YXNrcyIsInR5cGVEb2N1bWVudGF0aW9ucyI6Imh0dHA6Ly9kb2Nr\nZXIuZGV2OjgwODAvdjEvdHlwZWRvY3VtZW50YXRpb25zIiwidXNlclByZWZl\ncmVuY2VzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS91c2VycHJlZmVy\nZW5jZXMiLCJ2b2x1bWVzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS92\nb2x1bWVzIn0sImFjdGlvbnMiOnt9fQ==\n"},"http_version":null},"recorded_at":"Thu, 10 Sep 2015 15:24:04 GMT"}],"recorded_with":"VCR 2.9.3"}
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"head","uri":"http://docker.dev:8080/zen?foo=bar","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["text/plain"],"User-Agent":["Rancher Ruby Gem 0.1.0"],"Content-Type":["application/json"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Content-Length":["4162"],"Content-Type":["application/json; charset=utf-8"],"Date":["Thu, 10 Sep 2015 15:24:03 GMT"],"Server":["Jetty(9.2.11.v20150529)"],"X-Api-Account-Id":["1a1"],"X-Api-Client-Ip":["192.168.99.1"],"X-Api-Schemas":["http://docker.dev:8080/v1/schemas"]},"body":{"encoding":"UTF-8","base64_string":""},"http_version":null},"recorded_at":"Thu, 10 Sep 2015 15:24:04 GMT"}],"recorded_with":"VCR 2.9.3"}
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"get","uri":"http://docker.dev:8080/","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["application/json"],"User-Agent":["Rancher Ruby Gem 0.1.0"],"Content-Type":["application/json"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Content-Type":["application/json; charset=utf-8"],"Date":["Thu, 10 Sep 2015 15:24:03 GMT"],"Server":["Jetty(9.2.11.v20150529)"],"Vary":["Accept-Encoding, User-Agent"],"X-Api-Account-Id":["1a1"],"X-Api-Client-Ip":["192.168.99.1"],"X-Api-Schemas":["http://docker.dev:8080/v1/schemas"],"Content-Length":["188"]},"body":{"encoding":"ASCII-8BIT","base64_string":"eyJ0eXBlIjoiY29sbGVjdGlvbiIsInJlc291cmNlVHlwZSI6ImFwaVZlcnNp\nb24iLCJsaW5rcyI6eyJzZWxmIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC8i\nLCJsYXRlc3QiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxIn0sImNyZWF0\nZVR5cGVzIjp7fSwiYWN0aW9ucyI6e30sImRhdGEiOlt7ImlkIjoidjEiLCJ0\neXBlIjoiYXBpVmVyc2lvbiIsImxpbmtzIjp7InNlbGYiOiJodHRwOi8vZG9j\na2VyLmRldjo4MDgwL3YxIn0sImFjdGlvbnMiOnt9fV0sInNvcnRMaW5rcyI6\ne30sInBhZ2luYXRpb24iOm51bGwsInNvcnQiOm51bGwsImZpbHRlcnMiOnt9\nLCJjcmVhdGVEZWZhdWx0cyI6e319\n"},"http_version":null},"recorded_at":"Thu, 10 Sep 2015 15:24:04 GMT"}],"recorded_with":"VCR 2.9.3"}
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"get","uri":"http://docker.dev:8080/v1/projects/1a5/","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["application/json"],"User-Agent":["Rancher Ruby Gem 0.1.0"],"Content-Type":["application/json"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Content-Type":["application/json; charset=utf-8"],"Date":["Thu, 10 Sep 2015 15:24:03 GMT"],"Server":["Jetty(9.2.11.v20150529)"],"Vary":["Accept-Encoding, User-Agent"],"X-Api-Account-Id":["1a1"],"X-Api-Client-Ip":["192.168.99.1"],"X-Api-Schemas":["http://docker.dev:8080/v1/schemas"],"Content-Length":["1090"]},"body":{"encoding":"ASCII-8BIT","base64_string":"eyJpZCI6IjFhNSIsInR5cGUiOiJwcm9qZWN0IiwibGlua3MiOnsic2VsZiI6\nImh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1IiwiYWdl\nbnRzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUv\nYWdlbnRzIiwiY2VydGlmaWNhdGVzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4\nMC92MS9wcm9qZWN0cy8xYTUvY2VydGlmaWNhdGVzIiwiY29uZmlnSXRlbVN0\nYXR1c2VzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8x\nYTUvY29uZmlnaXRlbXN0YXR1c2VzIiwiY29udGFpbmVyRXZlbnRzIjoiaHR0\ncDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvY29udGFpbmVy\nZXZlbnRzIiwiY3JlZGVudGlhbHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL3Byb2plY3RzLzFhNS9jcmVkZW50aWFscyIsImVudmlyb25tZW50cyI6\nImh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1L2Vudmly\nb25tZW50cyIsImdsb2JhbExvYWRCYWxhbmNlcnMiOiJodHRwOi8vZG9ja2Vy\nLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9nbG9iYWxsb2FkYmFsYW5jZXJz\nIiwiaG9zdHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3Rz\nLzFhNS9ob3N0cyIsImltYWdlcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAv\ndjEvcHJvamVjdHMvMWE1L2ltYWdlcyIsImluc3RhbmNlTGlua3MiOiJodHRw\nOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9pbnN0YW5jZWxp\nbmtzIiwiaW5zdGFuY2VzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9w\ncm9qZWN0cy8xYTUvaW5zdGFuY2VzIiwiaXBBZGRyZXNzZXMiOiJodHRwOi8v\nZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9pcGFkZHJlc3NlcyIs\nImxhYmVscyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMv\nMWE1L2xhYmVscyIsImxvYWRCYWxhbmNlckNvbmZpZ0xpc3RlbmVyTWFwcyI6\nImh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1L2xvYWRi\nYWxhbmNlcmNvbmZpZ2xpc3RlbmVybWFwcyIsImxvYWRCYWxhbmNlckNvbmZp\nZ3MiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9s\nb2FkYmFsYW5jZXJjb25maWdzIiwibG9hZEJhbGFuY2VySG9zdE1hcHMiOiJo\ndHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9sb2FkYmFs\nYW5jZXJob3N0bWFwcyIsImxvYWRCYWxhbmNlckxpc3RlbmVycyI6Imh0dHA6\nLy9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1L2xvYWRiYWxhbmNl\ncmxpc3RlbmVycyIsImxvYWRCYWxhbmNlclRhcmdldHMiOiJodHRwOi8vZG9j\na2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9sb2FkYmFsYW5jZXJ0YXJn\nZXRzIiwibG9hZEJhbGFuY2VycyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAv\ndjEvcHJvamVjdHMvMWE1L2xvYWRiYWxhbmNlcnMiLCJtb3VudHMiOiJodHRw\nOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9tb3VudHMiLCJu\nZXR3b3JrcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMv\nMWE1L25ldHdvcmtzIiwicGh5c2ljYWxIb3N0cyI6Imh0dHA6Ly9kb2NrZXIu\nZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1L3BoeXNpY2FsaG9zdHMiLCJwb3J0\ncyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1L3Bv\ncnRzIiwicHJvamVjdE1lbWJlcnMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL3Byb2plY3RzLzFhNS9wcm9qZWN0bWVtYmVycyIsInNlcnZpY2VDb25z\ndW1lTWFwcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMv\nMWE1L3NlcnZpY2Vjb25zdW1lbWFwcyIsInNlcnZpY2VFdmVudHMiOiJodHRw\nOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9zZXJ2aWNlZXZl\nbnRzIiwic2VydmljZUV4cG9zZU1hcHMiOiJodHRwOi8vZG9ja2VyLmRldjo4\nMDgwL3YxL3Byb2plY3RzLzFhNS9zZXJ2aWNlZXhwb3NlbWFwcyIsInNlcnZp\nY2VzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUv\nc2VydmljZXMiLCJzbmFwc2hvdHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL3Byb2plY3RzLzFhNS9zbmFwc2hvdHMiLCJzdG9yYWdlUG9vbHMiOiJo\ndHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9zdG9yYWdl\ncG9vbHMiLCJ1c2VyUHJlZmVyZW5jZXMiOiJodHRwOi8vZG9ja2VyLmRldjo4\nMDgwL3YxL3Byb2plY3RzLzFhNS91c2VycHJlZmVyZW5jZXMiLCJ2b2x1bWVz\nIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvdm9s\ndW1lcyIsImFjY291bnRzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9w\ncm9qZWN0cy8xYTUvYWNjb3VudHMiLCJhcGlLZXlzIjoiaHR0cDovL2RvY2tl\nci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvYXBpa2V5cyIsImNsdXN0ZXJz\nIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvY2x1\nc3RlcnMiLCJjb25maWdJdGVtcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAv\ndjEvcHJvamVjdHMvMWE1L2NvbmZpZ2l0ZW1zIiwiY29udGFpbmVyRXhlY3Mi\nOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9jb250\nYWluZXJleGVjcyIsImNvbnRhaW5lcnMiOiJodHRwOi8vZG9ja2VyLmRldjo4\nMDgwL3YxL3Byb2plY3RzLzFhNS9jb250YWluZXJzIiwiZGF0YWJhc2VjaGFu\nZ2Vsb2dsb2NrcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVj\ndHMvMWE1L2RhdGFiYXNlY2hhbmdlbG9nbG9ja3MiLCJkYXRhYmFzZWNoYW5n\nZWxvZ3MiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFh\nNS9kYXRhYmFzZWNoYW5nZWxvZ3MiLCJkbnNTZXJ2aWNlcyI6Imh0dHA6Ly9k\nb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1L2Ruc3NlcnZpY2VzIiwi\nZG9ja2VyQnVpbGRzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9q\nZWN0cy8xYTUvZG9ja2VyYnVpbGRzIiwiZXh0ZW5zaW9uUG9pbnRzIjoiaHR0\ncDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvZXh0ZW5zaW9u\ncG9pbnRzIiwiZXh0ZXJuYWxIYW5kbGVyRXh0ZXJuYWxIYW5kbGVyUHJvY2Vz\nc01hcHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFh\nNS9leHRlcm5hbGhhbmRsZXJleHRlcm5hbGhhbmRsZXJwcm9jZXNzbWFwcyIs\nImV4dGVybmFsSGFuZGxlclByb2Nlc3NlcyI6Imh0dHA6Ly9kb2NrZXIuZGV2\nOjgwODAvdjEvcHJvamVjdHMvMWE1L2V4dGVybmFsaGFuZGxlcnByb2Nlc3Nl\ncyIsImV4dGVybmFsSGFuZGxlcnMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL3Byb2plY3RzLzFhNS9leHRlcm5hbGhhbmRsZXJzIiwiZXh0ZXJuYWxT\nZXJ2aWNlcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMv\nMWE1L2V4dGVybmFsc2VydmljZXMiLCJnaXRodWJjb25maWdzIjoiaHR0cDov\nL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvZ2l0aHViY29uZmln\ncyIsImhvc3RBY2Nlc3NlcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEv\ncHJvamVjdHMvMWE1L2hvc3RhY2Nlc3NlcyIsImhvc3RBcGlQcm94eVRva2Vu\ncyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1L2hv\nc3RhcGlwcm94eXRva2VucyIsImlkZW50aXRpZXMiOiJodHRwOi8vZG9ja2Vy\nLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9pZGVudGl0aWVzIiwibGRhcGNv\nbmZpZ3MiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFh\nNS9sZGFwY29uZmlncyIsImxvYWRCYWxhbmNlclNlcnZpY2VzIjoiaHR0cDov\nL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvbG9hZGJhbGFuY2Vy\nc2VydmljZXMiLCJtYWNoaW5lcyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAv\ndjEvcHJvamVjdHMvMWE1L21hY2hpbmVzIiwicHJvY2Vzc0RlZmluaXRpb25z\nIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvcHJv\nY2Vzc2RlZmluaXRpb25zIiwicHJvY2Vzc0V4ZWN1dGlvbnMiOiJodHRwOi8v\nZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9wcm9jZXNzZXhlY3V0\naW9ucyIsInByb2Nlc3NJbnN0YW5jZXMiOiJodHRwOi8vZG9ja2VyLmRldjo4\nMDgwL3YxL3Byb2plY3RzLzFhNS9wcm9jZXNzaW5zdGFuY2VzIiwicHJvamVj\ndHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9w\ncm9qZWN0cyIsInJlZ2lzdGVyIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92\nMS9wcm9qZWN0cy8xYTUvcmVnaXN0ZXIiLCJyZWdpc3RyYXRpb25Ub2tlbnMi\nOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS9yZWdp\nc3RyYXRpb250b2tlbnMiLCJyZWdpc3RyaWVzIjoiaHR0cDovL2RvY2tlci5k\nZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvcmVnaXN0cmllcyIsInJlZ2lzdHJ5\nQ3JlZGVudGlhbHMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2pl\nY3RzLzFhNS9yZWdpc3RyeWNyZWRlbnRpYWxzIiwicmVzb3VyY2VEZWZpbml0\naW9ucyI6Imh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1\nL3Jlc291cmNlZGVmaW5pdGlvbnMiLCJzY2hlbWFzIjoiaHR0cDovL2RvY2tl\nci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvc2NoZW1hcyIsInNldHRpbmdz\nIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvc2V0\ndGluZ3MiLCJzdGF0c0FjY2Vzc2VzIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4\nMC92MS9wcm9qZWN0cy8xYTUvc3RhdHNhY2Nlc3NlcyIsInRhc2tJbnN0YW5j\nZXMiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS90\nYXNraW5zdGFuY2VzIiwidGFza3MiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL3Byb2plY3RzLzFhNS90YXNrcyIsInR5cGVEb2N1bWVudGF0aW9ucyI6\nImh0dHA6Ly9kb2NrZXIuZGV2OjgwODAvdjEvcHJvamVjdHMvMWE1L3R5cGVk\nb2N1bWVudGF0aW9ucyIsImhvc3RTdGF0cyI6Imh0dHA6Ly9kb2NrZXIuZGV2\nOjgwODAvdjEvcHJvamVjdHMvMWE1L3Byb2plY3RzLzFhNS9ob3N0c3RhdHMi\nfSwiYWN0aW9ucyI6eyJ1cGRhdGUiOiJodHRwOi8vZG9ja2VyLmRldjo4MDgw\nL3YxL3Byb2plY3RzLzFhNS8/YWN0aW9uPXVwZGF0ZSIsImRlYWN0aXZhdGUi\nOiJodHRwOi8vZG9ja2VyLmRldjo4MDgwL3YxL3Byb2plY3RzLzFhNS8/YWN0\naW9uPWRlYWN0aXZhdGUiLCJzZXRtZW1iZXJzIjoiaHR0cDovL2RvY2tlci5k\nZXY6ODA4MC92MS9wcm9qZWN0cy8xYTUvP2FjdGlvbj1zZXRtZW1iZXJzIiwi\nZGVsZXRlIjoiaHR0cDovL2RvY2tlci5kZXY6ODA4MC92MS9wcm9qZWN0cy8x\nYTUvP2FjdGlvbj1kZWxldGUifSwibmFtZSI6IkRlZmF1bHQiLCJzdGF0ZSI6\nImFjdGl2ZSIsImNyZWF0ZWQiOiIyMDE1LTA5LTEwVDE1OjEzOjIwWiIsImNy\nZWF0ZWRUUyI6MTQ0MTg5ODAwMDAwMCwiZGF0YSI6eyJmaWVsZHMiOnsiZGVm\nYXVsdE5ldHdvcmtJZCI6NSwiY2FwYWJpbGl0aWVzIjpbIm93bmVyIl19fSwi\nZGVzY3JpcHRpb24iOm51bGwsImtpbmQiOiJwcm9qZWN0IiwibWVtYmVycyI6\nbnVsbCwicmVtb3ZlVGltZSI6bnVsbCwicmVtb3ZlZCI6bnVsbCwidHJhbnNp\ndGlvbmluZyI6Im5vIiwidHJhbnNpdGlvbmluZ01lc3NhZ2UiOm51bGwsInRy\nYW5zaXRpb25pbmdQcm9ncmVzcyI6bnVsbCwidXVpZCI6ImFkbWluUHJvamVj\ndCJ9\n"},"http_version":null},"recorded_at":"Thu, 10 Sep 2015 15:24:04 GMT"}],"recorded_with":"VCR 2.9.3"}
data/spec/helper.rb ADDED
@@ -0,0 +1,120 @@
1
+ if RUBY_ENGINE == 'ruby'
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ Coveralls::SimpleCov::Formatter
8
+ ]
9
+ SimpleCov.start
10
+ end
11
+
12
+ require 'json'
13
+ require 'rancher'
14
+ require 'rspec'
15
+ require 'webmock/rspec'
16
+
17
+ WebMock.disable_net_connect!(:allow => 'coveralls.io')
18
+
19
+ RSpec.configure do |config|
20
+ config.raise_errors_for_deprecations!
21
+ end
22
+
23
+ require 'vcr'
24
+ VCR.configure do |c|
25
+ c.configure_rspec_metadata!
26
+
27
+ c.ignore_request do |request|
28
+ !!request.headers['X-Vcr-Test-Repo-Setup']
29
+ end
30
+
31
+ c.default_cassette_options = {
32
+ :serialize_with => :json,
33
+ # TODO: Track down UTF-8 issue and remove
34
+ :preserve_exact_body_bytes => true,
35
+ :decode_compressed_response => true,
36
+ :record => ENV['TRAVIS'] ? :none : :once
37
+ }
38
+ c.cassette_library_dir = 'spec/cassettes'
39
+ c.hook_into :webmock
40
+ end
41
+
42
+ def test_rancher_api_endpoint
43
+ ENV.fetch 'RANCHER_TEST_API_ENDPOINT', 'http://localhost:8080/v1/project/1a5'
44
+ end
45
+
46
+ def test_rancher_access_key
47
+ ENV.fetch 'RANCHER_TEST_ACCESS_KEY', 'x' * 21
48
+ end
49
+
50
+ def test_rancher_secret_key
51
+ ENV.fetch 'RANCHER_TEST_SECRET_KEY', 'x' * 40
52
+ end
53
+
54
+ def test_client
55
+ Rancher::Client.new(
56
+ :api_endpoint => test_rancher_api_endpoint
57
+ )
58
+ end
59
+
60
+ def stub_delete(url)
61
+ stub_request(:delete, rancher_url(url))
62
+ end
63
+
64
+ def stub_get(url)
65
+ stub_request(:get, rancher_url(url))
66
+ end
67
+
68
+ def stub_head(url)
69
+ stub_request(:head, rancher_url(url))
70
+ end
71
+
72
+ def stub_patch(url)
73
+ stub_request(:patch, rancher_url(url))
74
+ end
75
+
76
+ def stub_post(url)
77
+ stub_request(:post, rancher_url(url))
78
+ end
79
+
80
+ def stub_put(url)
81
+ stub_request(:put, rancher_url(url))
82
+ end
83
+
84
+ def fixture_path
85
+ File.expand_path("../fixtures", __FILE__)
86
+ end
87
+
88
+ def fixture(file)
89
+ File.new(fixture_path + '/' + file)
90
+ end
91
+
92
+ def json_response(file)
93
+ {
94
+ :body => fixture(file),
95
+ :headers => {
96
+ :content_type => 'application/json; charset=utf-8'
97
+ }
98
+ }
99
+ end
100
+
101
+ def rancher_url(url)
102
+ return url if url =~ /^http/
103
+ Rancher.configure do |c|
104
+ c.api_endpoint = test_rancher_api_endpoint
105
+ end
106
+
107
+ url = File.join(Rancher.api_endpoint, url)
108
+ uri = Addressable::URI.parse(url)
109
+ uri.path.gsub!("1a5//", "1a5/")
110
+
111
+ uri.to_s
112
+ end
113
+
114
+ def use_vcr_placeholder_for(text, replacement)
115
+ VCR.configure do |c|
116
+ c.define_cassette_placeholder(replacement) do
117
+ text
118
+ end
119
+ end
120
+ end