engineyard-cloud-client 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. data/lib/engineyard-cloud-client.rb +14 -93
  2. data/lib/engineyard-cloud-client/connection.rb +142 -0
  3. data/lib/engineyard-cloud-client/models/account.rb +1 -1
  4. data/lib/engineyard-cloud-client/models/app.rb +2 -2
  5. data/lib/engineyard-cloud-client/models/app_environment.rb +4 -4
  6. data/lib/engineyard-cloud-client/models/deployment.rb +6 -6
  7. data/lib/engineyard-cloud-client/models/environment.rb +13 -11
  8. data/lib/engineyard-cloud-client/models/keypair.rb +3 -3
  9. data/lib/engineyard-cloud-client/models/recipes.rb +3 -6
  10. data/lib/engineyard-cloud-client/test.rb +3 -3
  11. data/lib/engineyard-cloud-client/test/fake_awsm/config.ru +4 -3
  12. data/lib/engineyard-cloud-client/test/fake_awsm/views/base_app_environment.rabl +1 -1
  13. data/lib/engineyard-cloud-client/test/fake_awsm/views/base_environment.rabl +1 -1
  14. data/lib/engineyard-cloud-client/test/fake_awsm/views/environments.rabl +1 -1
  15. data/lib/engineyard-cloud-client/test/scenario.rb +2 -3
  16. data/lib/engineyard-cloud-client/version.rb +1 -1
  17. data/spec/engineyard-cloud-client/api_spec.rb +15 -33
  18. data/spec/engineyard-cloud-client/integration/account_spec.rb +0 -1
  19. data/spec/engineyard-cloud-client/integration/app_environment_spec.rb +0 -1
  20. data/spec/engineyard-cloud-client/integration/app_spec.rb +0 -1
  21. data/spec/engineyard-cloud-client/integration/deployment_spec.rb +1 -2
  22. data/spec/engineyard-cloud-client/integration/environment_spec.rb +0 -1
  23. data/spec/engineyard-cloud-client/integration/user_spec.rb +6 -9
  24. data/spec/spec_helper.rb +0 -3
  25. data/spec/support/helpers.rb +2 -6
  26. metadata +9 -9
  27. data/lib/engineyard-cloud-client/test/ui.rb +0 -33
@@ -3,6 +3,7 @@ module EY
3
3
  end
4
4
  end
5
5
 
6
+ require 'engineyard-cloud-client/connection'
6
7
  require 'engineyard-cloud-client/model_registry'
7
8
  require 'engineyard-cloud-client/models'
8
9
  require 'engineyard-cloud-client/rest_client_ext'
@@ -11,58 +12,33 @@ require 'engineyard-cloud-client/version'
11
12
  require 'engineyard-cloud-client/errors'
12
13
  require 'multi_json'
13
14
  require 'pp'
15
+ require 'forwardable'
14
16
 
15
17
  module EY
16
18
  class CloudClient
17
- attr_reader :token, :registry
18
- attr_accessor :ui
19
+ extend Forwardable
19
20
 
20
- USER_AGENT_STRING = "EngineYardCloudClient/#{EY::CloudClient::VERSION}"
21
+ def_delegators :connection, :head, :get, :post, :put, :delete, :request, :endpoint, :token, :token=, :authenticate!, :authenticated?
21
22
 
22
- def self.endpoint
23
- @endpoint
24
- end
25
-
26
- def self.endpoint=(endpoint)
27
- @endpoint = URI.parse(endpoint)
28
- unless @endpoint.absolute?
29
- raise BadEndpointError.new(endpoint)
30
- end
31
- @endpoint
32
- end
33
-
34
- def self.default_endpoint!
35
- self.endpoint = "https://cloud.engineyard.com/"
36
- end
37
- default_endpoint!
23
+ attr_reader :connection
38
24
 
39
- def initialize(token, ui)
40
- self.token = token
41
- self.ui = ui
25
+ # Initialize a new EY::CloudClient.
26
+ #
27
+ # Creates and stores a new Connection for communicating with EY Cloud.
28
+ #
29
+ # See EY::CloudClient::Connection for options.
30
+ def initialize(options={})
31
+ @connection = Connection.new(options)
42
32
  end
43
33
 
44
34
  def ==(other)
45
- other.is_a?(self.class) && other.token == token
35
+ other.is_a?(self.class) && other.connection == connection
46
36
  end
47
37
 
48
38
  def registry
49
39
  @registry ||= ModelRegistry.new
50
40
  end
51
41
 
52
- def token=(new_token)
53
- unless new_token
54
- raise ArgumentError, "EY Cloud API token required"
55
- end
56
- @token = new_token
57
- end
58
-
59
- def request(url, opts={})
60
- opts[:headers] ||= {}
61
- opts[:headers]["X-EY-Cloud-Token"] = token
62
- ui.debug("Token", token)
63
- self.class.request(url, ui, opts)
64
- end
65
-
66
42
  def resolve_environments(constraints)
67
43
  EY::CloudClient::Environment.resolve(self, constraints)
68
44
  end
@@ -86,62 +62,7 @@ module EY
86
62
  end
87
63
 
88
64
  def current_user
89
- EY::CloudClient::User.from_hash(self, request('/current_user')['user'])
90
- end
91
-
92
- def self.request(path, ui, opts={})
93
- url = self.endpoint + "api/v2#{path}"
94
- method = (opts.delete(:method) || 'get').to_s.downcase.to_sym
95
- params = opts.delete(:params) || {}
96
- headers = opts.delete(:headers) || {}
97
- headers["Accept"] ||= "application/json"
98
- headers["User-Agent"] = USER_AGENT_STRING
99
-
100
- begin
101
- ui.debug("Request", "#{method.to_s.upcase} #{url}")
102
- ui.debug("Params", params.inspect)
103
- case method
104
- when :get, :delete, :head
105
- unless params.empty?
106
- url.query = RestClient::Payload::UrlEncoded.new(params).to_s
107
- end
108
- resp = RestClient.send(method, url.to_s, headers)
109
- else
110
- resp = RestClient.send(method, url.to_s, params, headers)
111
- end
112
- rescue RestClient::Unauthorized
113
- raise InvalidCredentials
114
- rescue Errno::ECONNREFUSED
115
- raise RequestFailed, "Could not reach the cloud API"
116
- rescue RestClient::ResourceNotFound
117
- raise ResourceNotFound, "The requested resource could not be found"
118
- rescue RestClient::BadGateway
119
- raise RequestFailed, "EY Cloud API is temporarily unavailable. Please try again soon."
120
- rescue RestClient::RequestFailed => e
121
- raise RequestFailed, "#{e.message} #{e.response}"
122
- rescue OpenSSL::SSL::SSLError
123
- raise RequestFailed, "SSL is misconfigured on your cloud"
124
- end
125
-
126
- if resp.body.empty?
127
- data = ''
128
- elsif resp.headers[:content_type] =~ /application\/json/
129
- begin
130
- data = MultiJson.load(resp.body)
131
- ui.debug("Response", "\n" + data.pretty_inspect)
132
- rescue MultiJson::DecodeError
133
- ui.debug("Raw response", resp.body)
134
- raise RequestFailed, "Response was not valid JSON."
135
- end
136
- else
137
- data = resp.body
138
- end
139
-
140
- data
141
- end
142
-
143
- def self.authenticate(email, password, ui)
144
- request("/authenticate", ui, { :method => "post", :params => { :email => email, :password => password }})["api_token"]
65
+ EY::CloudClient::User.from_hash(self, get('/current_user')['user'])
145
66
  end
146
67
 
147
68
  end # API
@@ -0,0 +1,142 @@
1
+ require 'engineyard-cloud-client/rest_client_ext'
2
+ require 'multi_json'
3
+ require 'uri'
4
+
5
+ module EY
6
+ class CloudClient
7
+ class Connection
8
+ attr_reader :token, :output, :user_agent, :endpoint
9
+
10
+ BASE_USER_AGENT = "EngineYardCloudClient/#{EY::CloudClient::VERSION}".freeze
11
+ DEFAULT_ENDPOINT = "https://cloud.engineyard.com/".freeze
12
+
13
+ # Initialize a new EY::CloudClient::Connection with a hash including:
14
+ #
15
+ # :token: (optional) Perform authenticated requests with this token
16
+ # :user_agent: (optional) A user agent name/version pair to add to the User-Agent header. (e.g. EngineYardCLI/2.0.0)
17
+ # :output: (optional) Send output to a stream other than $stdout
18
+ # :endpoint: (optional) An alternate Engine Yard Cloud endpoint URI
19
+ def initialize(options={})
20
+ @output = options[:output] || $stdout
21
+ @user_agent = [options[:user_agent], BASE_USER_AGENT].compact.join(' ').strip
22
+ @endpoint = URI.parse(options[:endpoint] || DEFAULT_ENDPOINT)
23
+ self.token = options[:token]
24
+
25
+ unless @endpoint.absolute?
26
+ raise BadEndpointError.new(@endpoint)
27
+ end
28
+ end
29
+
30
+ def token=(new_token)
31
+ @token = new_token
32
+ end
33
+
34
+ def debug(name, value)
35
+ return unless ENV['DEBUG']
36
+
37
+ indent = 12 # 12 because that's what Thor used.
38
+ unless String === value
39
+ value = value.pretty_inspect.rstrip # remove trailing whitespace
40
+ if value.index("\n") # if the inspect is multi-line
41
+ value.gsub!(/[\r\n]./, "\n" + ' ' * (indent + 2)) # indent it
42
+ end
43
+ end
44
+ @output << "#{name.to_s.rjust(indent)} #{value.rstrip}\n" # just one newline
45
+ end
46
+
47
+ def ==(other)
48
+ other.is_a?(self.class) && [other.token, other.user_agent, other.endpoint] == [token, user_agent, endpoint]
49
+ end
50
+
51
+ %w[ get head post put delete ].each do |meth|
52
+ eval <<-RUBY, binding, __FILE__, __LINE__ + 1
53
+ def #{meth}(path, params=nil, headers=nil, &block)
54
+ request("#{meth}", path, params, headers, &block)
55
+ end
56
+ RUBY
57
+ end
58
+
59
+ def request(meth, path, params=nil, extra_headers=nil)
60
+ url = endpoint + "api/v2#{path}"
61
+ meth ||= 'get'
62
+ meth = meth.to_s.downcase.to_sym
63
+ params ||= {}
64
+
65
+ headers = {
66
+ "User-Agent" => user_agent,
67
+ "Accept" => "application/json",
68
+ }
69
+
70
+ if token
71
+ headers["X-EY-Cloud-Token"] = token
72
+ end
73
+
74
+ if extra_headers
75
+ headers.merge!(extra_headers)
76
+ end
77
+
78
+ debug(meth.to_s.upcase, url.to_s)
79
+ debug("Params", params) if params
80
+ debug("Headers", headers)
81
+
82
+ resp = do_request(meth, url, params, headers)
83
+ data = parse_response(resp)
84
+
85
+ data
86
+ end
87
+
88
+ def authenticate!(email, password)
89
+ response = post("/authenticate", :email => email, :password => password)
90
+ self.token = response["api_token"]
91
+ token
92
+ end
93
+
94
+ def authenticated?
95
+ !token.nil? && !token.empty?
96
+ end
97
+
98
+ private
99
+
100
+ def do_request(meth, url, params, headers)
101
+ case meth
102
+ when :get, :delete, :head
103
+ if params
104
+ url.query = RestClient::Payload::UrlEncoded.new(params).to_s
105
+ end
106
+ RestClient.send(meth, url.to_s, headers)
107
+ else
108
+ RestClient.send(meth, url.to_s, params, headers)
109
+ end
110
+ rescue RestClient::Unauthorized
111
+ raise InvalidCredentials
112
+ rescue Errno::ECONNREFUSED
113
+ raise RequestFailed, "Could not reach the cloud API"
114
+ rescue RestClient::ResourceNotFound
115
+ raise ResourceNotFound, "The requested resource could not be found"
116
+ rescue RestClient::BadGateway
117
+ raise RequestFailed, "EY Cloud API is temporarily unavailable. Please try again soon."
118
+ rescue RestClient::RequestFailed => e
119
+ raise RequestFailed, "#{e.message} #{e.response}"
120
+ rescue OpenSSL::SSL::SSLError
121
+ raise RequestFailed, "SSL is misconfigured on your cloud"
122
+ end
123
+
124
+ def parse_response(resp)
125
+ if resp.body.empty?
126
+ ''
127
+ elsif resp.headers[:content_type] =~ /application\/json/
128
+ begin
129
+ data = MultiJson.load(resp.body)
130
+ debug("Response", data)
131
+ data
132
+ rescue MultiJson::DecodeError
133
+ debug("Response", resp.body)
134
+ raise RequestFailed, "Response was not valid JSON."
135
+ end
136
+ else
137
+ resp.body
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -5,7 +5,7 @@ module EY
5
5
  class Account < ApiStruct.new(:id, :name)
6
6
 
7
7
  def self.all(api)
8
- self.from_array(api, api.request('/accounts')["accounts"])
8
+ self.from_array(api, api.get("/accounts")["accounts"])
9
9
  end
10
10
 
11
11
  def add_app(app)
@@ -9,7 +9,7 @@ module EY
9
9
 
10
10
  # Return list of all Apps linked to all current user's accounts
11
11
  def self.all(api)
12
- self.from_array(api, api.request('/apps?no_instances=true')["apps"])
12
+ self.from_array(api, api.get("/apps", 'no_instances' => 'true')["apps"])
13
13
  end
14
14
 
15
15
  # An everything-you-need helper to create an App
@@ -32,7 +32,7 @@ module EY
32
32
  raise EY::CloudClient::AttributeRequiredError.new("name") unless params["name"]
33
33
  raise EY::CloudClient::AttributeRequiredError.new("repository_uri") unless params["repository_uri"]
34
34
  raise EY::CloudClient::AttributeRequiredError.new("app_type_id") unless params["app_type_id"]
35
- response = api.request("/accounts/#{account.id}/apps", :method => :post, :params => {"app" => params})
35
+ response = api.post("/accounts/#{account.id}/apps", "app" => params)
36
36
  from_hash(api, response['app'])
37
37
  end
38
38
 
@@ -7,15 +7,15 @@ module EY
7
7
 
8
8
  # Return a constrained list of app_environments given a set of constraints like:
9
9
  #
10
- # * app_name
11
- # * account_name
12
- # * environment_name
10
+ # * app_name: app name full or partial match string
11
+ # * account_name: account name full or partial match string
12
+ # * environment_name: environment name full or partial match string
13
13
  # * remotes: An array of git remote URIs
14
14
  #
15
15
  def self.resolve(api, constraints)
16
16
  clean_constraints = constraints.reject { |k,v| v.nil? }
17
17
  params = {'constraints' => clean_constraints}
18
- response = api.request("/app_environments/resolve", :method => :get, :params => params)['resolver']
18
+ response = api.get("/app_environments/resolve", params)['resolver']
19
19
  matches = from_array(api, response['matches'])
20
20
  ResolverResult.new(api, matches, response['errors'], response['suggestions'])
21
21
  end
@@ -14,7 +14,7 @@ module EY
14
14
 
15
15
  def self.get(api, app_environment, id)
16
16
  uri = api_root(app_environment.app.id, app_environment.environment.id) + "/#{id}"
17
- response = api.request(uri, :method => :get)
17
+ response = api.get(uri)
18
18
  load_from_response api, app_environment, response
19
19
  rescue EY::CloudClient::ResourceNotFound
20
20
  nil
@@ -47,16 +47,16 @@ module EY
47
47
  alias deployed_by= user_name=
48
48
 
49
49
  def created_at
50
- super && (@created_at ||= Time.parse(super))
50
+ @created_at ||= super && Time.parse(super)
51
51
  end
52
52
 
53
53
  def finished_at
54
- super && (@finished_at ||= Time.parse(super))
54
+ @finished_at ||= super && Time.parse(super)
55
55
  end
56
56
 
57
57
  def config
58
58
  return {} unless deployed_by # not started yet so not all info is here
59
- @config ||= {'deployed_by' => deployed_by}.merge(extra_config)
59
+ @config ||= {'input_ref' => ref, 'deployed_by' => deployed_by}.merge(extra_config)
60
60
  end
61
61
 
62
62
  def start
@@ -95,11 +95,11 @@ module EY
95
95
  private
96
96
 
97
97
  def post_to_api(params)
98
- update_with_response api.request(collection_uri, :method => :post, :params => {:deployment => params})
98
+ update_with_response api.post(collection_uri, 'deployment' => params)
99
99
  end
100
100
 
101
101
  def put_to_api(params)
102
- update_with_response api.request(member_uri("/finished"), :method => :put, :params => {:deployment => params})
102
+ update_with_response api.put(member_uri("/finished"), 'deployment' => params)
103
103
  end
104
104
 
105
105
  def collection_uri
@@ -4,27 +4,29 @@ require 'engineyard-cloud-client/errors'
4
4
 
5
5
  module EY
6
6
  class CloudClient
7
- class Environment < ApiStruct.new(:id, :name, :framework_env, :instances_count,
7
+ class Environment < ApiStruct.new(:id, :name, :framework_env,
8
+ :instances_count,
9
+ :instance_status,
8
10
  :username, :app_server_stack_name,
9
11
  :load_balancer_ip_address
10
12
  )
11
13
 
12
14
  # Return list of all Environments linked to all current user's accounts
13
15
  def self.all(api)
14
- self.from_array(api, api.request('/environments?no_instances=true')["environments"])
16
+ self.from_array(api, api.get("/environments", "no_instances" => "true")["environments"])
15
17
  end
16
18
 
17
19
  # Return a constrained list of environments given a set of constraints like:
18
20
  #
19
- # * app_name
20
- # * account_name
21
- # * environment_name
21
+ # * app_name: app name full or partial match string
22
+ # * account_name: account name full or partial match string
23
+ # * environment_name: environment name full or partial match string
22
24
  # * remotes: An array of git remote URIs
23
25
  #
24
26
  def self.resolve(api, constraints)
25
27
  clean_constraints = constraints.reject { |k,v| v.nil? }
26
28
  params = {'constraints' => clean_constraints}
27
- response = api.request("/environments/resolve", :method => :get, :params => params)['resolver']
29
+ response = api.get("/environments/resolve", params)['resolver']
28
30
  matches = from_array(api, response['matches'])
29
31
  ResolverResult.new(api, matches, response['errors'], response['suggestions'])
30
32
  end
@@ -52,7 +54,7 @@ module EY
52
54
 
53
55
  params = {"environment" => attrs.dup}
54
56
  unpack_cluster_configuration(params, cluster_configuration)
55
- response = api.request("/apps/#{app.id}/environments", :method => :post, :params => params)
57
+ response = api.post("/apps/#{app.id}/environments", params)
56
58
  self.from_hash(api, response['environment'])
57
59
  end
58
60
  attr_accessor :apps, :account
@@ -99,7 +101,7 @@ module EY
99
101
  end
100
102
 
101
103
  def logs
102
- Log.from_array(api, api.request("/environments/#{id}/logs", :method => :get)["logs"])
104
+ Log.from_array(api, api.get("/environments/#{id}/logs")["logs"])
103
105
  end
104
106
 
105
107
  def deploy_to_instances
@@ -114,13 +116,13 @@ module EY
114
116
  if bridge.nil?
115
117
  raise NoBridgeError.new(name)
116
118
  elsif !ignore_bad_bridge && bridge.status != "running"
117
- raise BadBridgeStatusError.new(bridge.status, EY::CloudClient.endpoint)
119
+ raise BadBridgeStatusError.new(bridge.status, api.endpoint)
118
120
  end
119
121
  bridge
120
122
  end
121
123
 
122
124
  def update
123
- api.request("/environments/#{id}/update_instances", :method => :put)
125
+ api.put("/environments/#{id}/update_instances")
124
126
  true # raises on failure
125
127
  end
126
128
  alias rebuild update
@@ -178,7 +180,7 @@ module EY
178
180
  if instances_count.zero?
179
181
  []
180
182
  else
181
- instances_attrs = api.request("/environments/#{id}/instances")["instances"]
183
+ instances_attrs = api.get("/environments/#{id}/instances")["instances"]
182
184
  load_instances(instances_attrs)
183
185
  end
184
186
  end
@@ -5,7 +5,7 @@ module EY
5
5
  class Keypair < ApiStruct.new(:id, :name, :public_key)
6
6
 
7
7
  def self.all(api)
8
- self.from_array(api, api.request('/keypairs')["keypairs"])
8
+ self.from_array(api, api.get("/keypairs")["keypairs"])
9
9
  end
10
10
 
11
11
  # Create a Keypair with your SSH public key so that you can access your Instances
@@ -24,8 +24,8 @@ module EY
24
24
  params = attrs.dup # no default fields
25
25
  raise EY::CloudClient::AttributeRequiredError.new("name") unless params["name"]
26
26
  raise EY::CloudClient::AttributeRequiredError.new("public_key") unless params["public_key"]
27
- response = api.request("/keypairs", :method => :post, :params => {"keypair" => params})
28
- self.from_hash(api, response['keypair'])
27
+ response = api.post("/keypairs", "keypair" => params)['keypair']
28
+ self.from_hash(api, response)
29
29
  end
30
30
  end
31
31
  end
@@ -12,13 +12,13 @@ module EY
12
12
  end
13
13
 
14
14
  def run
15
- api.request("/environments/#{environment.id}/run_custom_recipes", :method => :put)
15
+ api.put("/environments/#{environment.id}/run_custom_recipes")
16
16
  true
17
17
  end
18
18
 
19
19
  def download
20
20
  tmp = Tempfile.new("recipes")
21
- data = api.request("/environments/#{environment.id}/recipes")
21
+ data = api.get("/environments/#{environment.id}/recipes")
22
22
  tmp.write(data)
23
23
  tmp.flush
24
24
  tmp.close
@@ -37,10 +37,7 @@ module EY
37
37
  # Expects a File object opened for binary reading.
38
38
  # i.e. upload(File.open(recipes_path, 'rb'))
39
39
  def upload(file_to_upload)
40
- api.request("/environments/#{environment.id}/recipes", {
41
- :method => :post,
42
- :params => {:file => file_to_upload}
43
- })
40
+ api.post("/environments/#{environment.id}/recipes", :file => file_to_upload)
44
41
  true
45
42
  end
46
43
 
@@ -15,11 +15,12 @@ rescue LoadError
15
15
  engineyard-cloud-client needs the following gems to run in test mode:
16
16
 
17
17
  group 'engineyard-cloud-client-test' do
18
- gem 'dm-core'
18
+ gem 'dm-core', '~>1.2.0'
19
19
  gem 'dm-migrations'
20
20
  gem 'dm-aggregates'
21
+ gem 'dm-timestamps'
21
22
  gem 'dm-sqlite-adapter'
22
- gem 'ey_resolver', '~>0.2.1'
23
+ gem 'ey_resolver', '~>0.2.1'
23
24
  gem 'rabl'
24
25
  end
25
26
 
@@ -27,5 +28,4 @@ Please add the above to your Gemfile.
27
28
  ERROR
28
29
  end
29
30
 
30
- require 'engineyard-cloud-client/test/ui'
31
31
  require 'engineyard-cloud-client/test/scenario'
@@ -36,9 +36,10 @@ class FakeAwsm < Sinatra::Base
36
36
  before do
37
37
  if env['PATH_INFO'] =~ %r#/api/v2#
38
38
  user_agent = env['HTTP_USER_AGENT']
39
- unless user_agent =~ %r#^EngineYardCloudClient/\d#
40
- $stderr.puts 'No user agent header, expected EngineYardCloudClient/'
41
- halt 400, 'No user agent header, expected EngineYardCloudClient/'
39
+ unless user_agent =~ %r#EngineYardCloudClient/\d#
40
+ msg = "No user agent header, expected EngineYardCloudClient/ got #{user_agent.inspect}"
41
+ $stderr.puts msg
42
+ halt 400, msg
42
43
  end
43
44
  end
44
45
  content_type "application/json"
@@ -1,6 +1,6 @@
1
1
  attributes :id, :domain_name, :uri
2
2
  child :environment do
3
- attributes :id, :ssh_username, :name, :instances_count, :app_server_stack_name, :load_balancer_ip_address, :framework_env
3
+ attributes :id, :ssh_username, :name, :instances_count, :instance_status, :app_server_stack_name, :load_balancer_ip_address, :framework_env
4
4
  child :account do
5
5
  attributes :id, :name
6
6
  end
@@ -1,4 +1,4 @@
1
- attributes :id, :ssh_username, :name, :instances_count, :app_server_stack_name, :load_balancer_ip_address, :framework_env
1
+ attributes :id, :ssh_username, :name, :instances_count, :instance_status, :app_server_stack_name, :load_balancer_ip_address, :framework_env
2
2
  child :account do
3
3
  attributes :id, :name
4
4
  end
@@ -1,5 +1,5 @@
1
1
  collection @environments, :root => :environments, :object_root => false
2
- attributes :id, :ssh_username, :name, :instances_count, :app_server_stack_name, :load_balancer_ip_address, :framework_env
2
+ attributes :id, :ssh_username, :name, :instances_count, :instance_status, :app_server_stack_name, :load_balancer_ip_address, :framework_env
3
3
  child :account do
4
4
  attributes :id, :name
5
5
  end
@@ -2,7 +2,6 @@ require 'multi_json'
2
2
  require 'engineyard-cloud-client/rest_client_ext'
3
3
  require 'engineyard-cloud-client/test'
4
4
  require 'engineyard-cloud-client/test/fake_awsm'
5
- require 'engineyard-cloud-client/test/ui'
6
5
 
7
6
  module EY::CloudClient::Test
8
7
  class Scenario
@@ -32,8 +31,8 @@ module EY::CloudClient::Test
32
31
  @api_token = options['api_token']
33
32
  end
34
33
 
35
- def cloud_client(ui = EY::CloudClient::Test::UI.new)
36
- EY::CloudClient.new(@api_token, ui)
34
+ def cloud_client
35
+ EY::CloudClient.new(:endpoint => EY::CloudClient::Test::FakeAwsm.uri, :token => @api_token)
37
36
  end
38
37
 
39
38
  def inspect
@@ -1,7 +1,7 @@
1
1
  # This file is maintained by a herd of rabid monkeys with Rakes.
2
2
  module EY
3
3
  class CloudClient
4
- VERSION = '1.0.3'
4
+ VERSION = '1.0.4'
5
5
  end
6
6
  end
7
7
  # Please be aware that the monkeys like tho throw poo sometimes.
@@ -2,50 +2,32 @@ require 'spec_helper'
2
2
 
3
3
  describe EY::CloudClient do
4
4
  it "holds an api token" do
5
- EY::CloudClient.new('asdf', test_ui).token.should == "asdf"
5
+ EY::CloudClient.new(:token => 'asdf').connection.token.should == "asdf"
6
6
  end
7
7
 
8
- it "holds a UI" do
9
- EY::CloudClient.new('asdf', test_ui).ui.should == test_ui
8
+ it "uses production EY Cloud by default" do
9
+ FakeWeb.register_uri(:post, "https://cloud.engineyard.com/api/v2/authenticate", :body => %|{"api_token": "cloudtoken"}|, :content_type => 'application/json')
10
+ client = EY::CloudClient.new
11
+ client.authenticate!("a@b.com", "foo")
12
+ client.connection.token.should == "cloudtoken"
10
13
  end
11
14
 
12
- describe ".endpoint" do
13
- after do
14
- EY::CloudClient.default_endpoint!
15
- end
16
-
17
- it "defaults to production EY Cloud" do
18
- EY::CloudClient.endpoint.should == URI.parse('https://cloud.engineyard.com')
19
- end
20
-
21
- it "accepts a valid endpoint" do
22
- EY::CloudClient.endpoint = "http://fake.local/"
23
- EY::CloudClient.endpoint.should == URI.parse('http://fake.local')
24
- end
25
-
26
- it "uses the endpoint to make requests" do
27
- FakeWeb.register_uri(:post, "http://fake.local/api/v2/authenticate", :body => %|{"api_token": "fake.localtoken"}|, :content_type => 'application/json')
28
-
29
- EY::CloudClient.endpoint = "http://fake.local/"
30
- EY::CloudClient.authenticate("a@b.com", "foo", test_ui).should == "fake.localtoken"
31
- end
32
-
33
- it "raises on an invalid endpoint" do
34
- lambda { EY::CloudClient.endpoint = "non/absolute" }.should raise_error(EY::CloudClient::BadEndpointError)
35
- end
15
+ it "uses a custom endpoint to make requests" do
16
+ FakeWeb.register_uri(:post, "http://fake.local/api/v2/authenticate", :body => %|{"api_token": "fake.localtoken"}|, :content_type => 'application/json')
17
+ client = EY::CloudClient.new(:endpoint => "http://fake.local/")
18
+ client.authenticate!("a@b.com", "foo")
19
+ client.connection.token.should == "fake.localtoken"
36
20
  end
37
21
 
38
- it "authenticates with valid credentials and returns the api token" do
39
- FakeWeb.register_uri(:post, "https://cloud.engineyard.com/api/v2/authenticate", :body => %|{"api_token": "asdf"}|, :content_type => 'application/json')
40
-
41
- EY::CloudClient.authenticate("a@b.com", "foo", test_ui).should == "asdf"
22
+ it "raises on an invalid endpoint" do
23
+ lambda { EY::CloudClient.new(:endpoint => "non/absolute") }.should raise_error(EY::CloudClient::BadEndpointError)
42
24
  end
43
25
 
44
26
  it "raises InvalidCredentials when the credentials are invalid" do
45
27
  FakeWeb.register_uri(:post, "https://cloud.engineyard.com/api/v2/authenticate", :status => 401, :content_type => 'application/json')
46
28
 
47
29
  lambda {
48
- EY::CloudClient.authenticate("a@b.com", "foo", test_ui)
30
+ EY::CloudClient.new.authenticate!("a@b.com", "foo")
49
31
  }.should raise_error(EY::CloudClient::InvalidCredentials)
50
32
  end
51
33
 
@@ -53,7 +35,7 @@ describe EY::CloudClient do
53
35
  FakeWeb.register_uri(:post, "https://cloud.engineyard.com/api/v2/authenticate", :status => 502, :content_type => 'text/html')
54
36
 
55
37
  lambda {
56
- EY::CloudClient.authenticate("a@b.com", "foo", test_ui)
38
+ EY::CloudClient.new.authenticate!("a@b.com", "foo")
57
39
  }.should raise_error(EY::CloudClient::RequestFailed, /API is temporarily unavailable/)
58
40
  end
59
41
  end
@@ -3,7 +3,6 @@ require 'spec_helper'
3
3
  describe EY::CloudClient::Account do
4
4
  before do
5
5
  FakeWeb.allow_net_connect = true
6
- EY::CloudClient.endpoint = EY::CloudClient::Test::FakeAwsm.uri
7
6
  end
8
7
 
9
8
  describe ".all" do
@@ -3,7 +3,6 @@ require 'spec_helper'
3
3
  describe EY::CloudClient::AppEnvironment do
4
4
  before(:each) do
5
5
  FakeWeb.allow_net_connect = true
6
- EY::CloudClient.endpoint = EY::CloudClient::Test::FakeAwsm.uri
7
6
  end
8
7
 
9
8
  describe ".resolve" do
@@ -3,7 +3,6 @@ require 'spec_helper'
3
3
  describe EY::CloudClient::App do
4
4
  before(:each) do
5
5
  FakeWeb.allow_net_connect = true
6
- EY::CloudClient.endpoint = EY::CloudClient::Test::FakeAwsm.uri
7
6
  end
8
7
 
9
8
  describe ".all" do
@@ -3,7 +3,6 @@ require 'spec_helper'
3
3
  describe EY::CloudClient::AppEnvironment do
4
4
  before(:each) do
5
5
  FakeWeb.allow_net_connect = true
6
- EY::CloudClient.endpoint = EY::CloudClient::Test::FakeAwsm.uri
7
6
  end
8
7
 
9
8
  describe "deploying" do
@@ -31,7 +30,7 @@ describe EY::CloudClient::AppEnvironment do
31
30
 
32
31
  deployment.created_at.should_not be_nil
33
32
  deployment.finished_at.should be_nil
34
- deployment.config.should == {'deployed_by' => 'Multiple Ambiguous Accounts', 'extra' => 'config'}
33
+ deployment.config.should == {'input_ref' => 'master', 'deployed_by' => 'Multiple Ambiguous Accounts', 'extra' => 'config'}
35
34
  deployment.commit.should =~ /[0-9a-f]{40}/
36
35
  deployment.resolved_ref.should_not be_nil
37
36
  deployment.out << "Test output"
@@ -3,7 +3,6 @@ require 'spec_helper'
3
3
  describe EY::CloudClient::Environment do
4
4
  before(:each) do
5
5
  FakeWeb.allow_net_connect = true
6
- EY::CloudClient.endpoint = EY::CloudClient::Test::FakeAwsm.uri
7
6
  end
8
7
 
9
8
  describe ".all" do
@@ -3,16 +3,13 @@ require 'spec_helper'
3
3
  describe EY::CloudClient::User do
4
4
  before do
5
5
  FakeWeb.allow_net_connect = true
6
- EY::CloudClient.endpoint = EY::CloudClient::Test::FakeAwsm.uri
7
6
  end
8
7
 
9
- describe ".all" do
10
- it "returns all accounts" do
11
- api = scenario_cloud_client "User Name"
12
- user = api.current_user
13
- user.name.should == 'User Name'
14
- user.accounts.size.should == 1
15
- user.accounts.first.name.should == 'main'
16
- end
8
+ it "loads current user and returns all accounts" do
9
+ api = scenario_cloud_client "User Name"
10
+ user = api.current_user
11
+ user.name.should == 'User Name'
12
+ user.accounts.size.should == 1
13
+ user.accounts.first.name.should == 'main'
17
14
  end
18
15
  end
data/spec/spec_helper.rb CHANGED
@@ -44,7 +44,4 @@ RSpec.configure do |config|
44
44
  FakeWeb.allow_net_connect = false
45
45
  end
46
46
 
47
- config.before(:each) do
48
- EY::CloudClient.default_endpoint!
49
- end
50
47
  end
@@ -1,12 +1,8 @@
1
1
  require 'rest_client'
2
2
 
3
3
  module SpecHelpers
4
- def test_ui
5
- @test_ui ||= EY::CloudClient::Test::UI.new
6
- end
7
-
8
- def cloud_client(token = 'asdf', ui = test_ui)
9
- @cloud_client ||= EY::CloudClient.new(token, ui)
4
+ def cloud_client(token = 'asdf')
5
+ @cloud_client ||= EY::CloudClient.new(:token => token)
10
6
  end
11
7
 
12
8
  def scenario_cloud_client(scenario)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: engineyard-cloud-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-13 00:00:00.000000000 Z
12
+ date: 2012-08-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -160,17 +160,17 @@ dependencies:
160
160
  requirement: !ruby/object:Gem::Requirement
161
161
  none: false
162
162
  requirements:
163
- - - ! '>='
163
+ - - ~>
164
164
  - !ruby/object:Gem::Version
165
- version: '0'
165
+ version: 1.2.0
166
166
  type: :development
167
167
  prerelease: false
168
168
  version_requirements: !ruby/object:Gem::Requirement
169
169
  none: false
170
170
  requirements:
171
- - - ! '>='
171
+ - - ~>
172
172
  - !ruby/object:Gem::Version
173
- version: '0'
173
+ version: 1.2.0
174
174
  - !ruby/object:Gem::Dependency
175
175
  name: dm-migrations
176
176
  requirement: !ruby/object:Gem::Requirement
@@ -273,6 +273,7 @@ executables: []
273
273
  extensions: []
274
274
  extra_rdoc_files: []
275
275
  files:
276
+ - lib/engineyard-cloud-client/connection.rb
276
277
  - lib/engineyard-cloud-client/errors.rb
277
278
  - lib/engineyard-cloud-client/model_registry.rb
278
279
  - lib/engineyard-cloud-client/models/account.rb
@@ -312,7 +313,6 @@ files:
312
313
  - lib/engineyard-cloud-client/test/fake_awsm/views/user.rabl
313
314
  - lib/engineyard-cloud-client/test/fake_awsm.rb
314
315
  - lib/engineyard-cloud-client/test/scenario.rb
315
- - lib/engineyard-cloud-client/test/ui.rb
316
316
  - lib/engineyard-cloud-client/test.rb
317
317
  - lib/engineyard-cloud-client/version.rb
318
318
  - lib/engineyard-cloud-client.rb
@@ -348,7 +348,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
348
348
  version: '0'
349
349
  segments:
350
350
  - 0
351
- hash: -4133734354650536829
351
+ hash: 2753056383473924638
352
352
  required_rubygems_version: !ruby/object:Gem::Requirement
353
353
  none: false
354
354
  requirements:
@@ -357,7 +357,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
357
357
  version: '0'
358
358
  segments:
359
359
  - 0
360
- hash: -4133734354650536829
360
+ hash: 2753056383473924638
361
361
  requirements: []
362
362
  rubyforge_project:
363
363
  rubygems_version: 1.8.24
@@ -1,33 +0,0 @@
1
- require 'engineyard-cloud-client/test'
2
-
3
- module EY::CloudClient::Test
4
- class QuietUI
5
- def info(*)
6
- end
7
-
8
- def debug(*)
9
- end
10
- end
11
-
12
- class VerboseUI
13
- def info(name, message = nil)
14
- say name, message
15
- end
16
-
17
- def debug(name, message = nil)
18
- name = name.inspect unless name.nil? or name.is_a?(String)
19
- message = message.inspect unless message.nil? or message.is_a?(String)
20
- say name, message
21
- end
22
-
23
- def say(status, message = nil)
24
- if message
25
- $stdout.puts "#{status.to_s.rjust(12)} #{message}"
26
- else
27
- $stdout.puts status
28
- end
29
- end
30
- end
31
-
32
- UI = ENV['DEBUG'] ? VerboseUI : QuietUI
33
- end