engineyard-cloud-client 1.0.14 → 1.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NGMzOTBkZDIxYjQyYTAwNjVmNThmZDkxMDJkZmM2NWIxYTA0MzUwZg==
4
+ OWRmNTExNmI5NjU0NGY2ODFjYjhjMDk3MDJhYzIwMzY4MjI1ZDVjYw==
5
5
  data.tar.gz: !binary |-
6
- NDA2NmJlZjk0MjhjMDczYjU4NDBiNzlmMzJlZmIxOTQzMzhlMWFhNA==
7
- !binary "U0hBNTEy":
6
+ OTg3NjBjZmM4ZGU4OTc2YzVkMmJhZjA3YWNjMmYwZGM0NGI5NzE1Yg==
7
+ SHA512:
8
8
  metadata.gz: !binary |-
9
- M2FiNTY5Y2Y2NWVkZDQ2N2YzMzc2N2IzZDA5MDQ1Y2UzY2NhMzg3NDhmOTc5
10
- NWRjOGU4Yjc1NDNkYWNjMjcyYjg4OTIzY2FiNDMyNWQxNTRhNmUzOGQyZjVj
11
- M2YwZWFhOGZiY2QwNTgxYjMxZjgwODVmYjIyZWRkNDg5NTZmZTQ=
9
+ MTY1ODg3MTY2M2ZlNGVhMTUyYTRkMGM0MzRhYTUwMTFmOTIwY2QxNDk2ZTg1
10
+ MGRjNmEwNDhjMWE3YTJjOTdkYTBlZDIyZGYxZmY0MTM5ODY2YWRjZjI0OWZi
11
+ MGM4YzE3NWNjYTJiYjEzOTZjOWRiYzQ2MmZhYTA0ODAwOGMyZWM=
12
12
  data.tar.gz: !binary |-
13
- YjFiYmE5YTg1ODA3ZjM1YmQwNTg3NmUyYjAxMWQwNWRhYzgxYjAyNGMyNzMx
14
- NmU0ZjQwZGI1ZWQ1NDdmNGNmZDFhYWFmNTg4ZTk1MjliYmQxNzUxOWIyNGVk
15
- NWUzZjVjMGU1MmYyMTIyNmQ3NWRmYzEwM2EyNjhjOGYwMzFmMzg=
13
+ ZmJlMGU5MTkyYzkyNDdlNzBlZGM4OTZhOWU4OWMzNjQ2NDRmZjE2YTNmMmE4
14
+ NGQ4MjgyNmZhYWYwNzE1N2JhZTU4YmZjZjU0MjYwZDI0NDk5Y2M5YzMwMjRj
15
+ ZDE4MDY4Njk2NWJkYTg2ZGY0ZjBjMTA1N2ZiODFiMzI5M2M5NzA=
@@ -4,6 +4,10 @@
4
4
 
5
5
  *
6
6
 
7
+ ## v1.0.15 (2013-11-15)
8
+
9
+ *
10
+
7
11
  ## v1.0.14 (2013-09-04)
8
12
 
9
13
  * Add sorting comparator spaceship (<=>) to each of the models.
@@ -7,7 +7,8 @@ require 'uri'
7
7
  module EY
8
8
  class CloudClient
9
9
  class Connection
10
- attr_reader :token, :output, :user_agent, :endpoint
10
+ attr_reader :output, :user_agent, :endpoint
11
+ attr_accessor :token
11
12
 
12
13
  BASE_USER_AGENT = "EngineYardCloudClient/#{EY::CloudClient::VERSION}".freeze
13
14
  DEFAULT_ENDPOINT = "https://cloud.engineyard.com/".freeze
@@ -22,17 +23,13 @@ module EY
22
23
  @output = options[:output] || $stdout
23
24
  @user_agent = [options[:user_agent], BASE_USER_AGENT].compact.join(' ').strip
24
25
  @endpoint = URI.parse(options[:endpoint] || DEFAULT_ENDPOINT)
25
- self.token = options[:token]
26
+ @token = options[:token]
26
27
 
27
28
  unless @endpoint.absolute?
28
29
  raise BadEndpointError.new(@endpoint)
29
30
  end
30
31
  end
31
32
 
32
- def token=(new_token)
33
- @token = new_token
34
- end
35
-
36
33
  def debug(name, value)
37
34
  return unless ENV['DEBUG']
38
35
 
@@ -9,6 +9,7 @@ module EY
9
9
  class InvalidInstanceRole < Error; end
10
10
  class InstanceNotProvisioned < Error; end
11
11
  class MultipleMatchesError < RequestFailed; end
12
+ class InvalidInstanceName < Error; end
12
13
 
13
14
  class BadEndpointError < Error
14
15
  def initialize(endpoint)
@@ -23,6 +23,38 @@ module EY
23
23
  ResolverResult.new(api, matches, response['errors'], response['suggestions'])
24
24
  end
25
25
 
26
+ # Accepts an api object, environment name and optional account name
27
+ # and returns the best matching environment for the given constraints.
28
+ #
29
+ # This is a shortcut for resolve_environments.
30
+ # Raises if nothing is found or if more than one environment is found.
31
+ def self.resolve_one(api, constraints)
32
+ resolver = resolve(api, constraints)
33
+
34
+ resolver.one_match { |match| return match }
35
+
36
+ resolver.no_matches do |errors, suggestions|
37
+ message = nil
38
+ if suggestions.any?
39
+ message = "Suggestions found:\n"
40
+ suggestions.sourt_by{|suggest| [suggest['account_name'], suggest['app_name']] }.each do |suggest|
41
+ message << "\t#{suggest['account_name']}/#{suggest['app_name']}/#{suggest['env_name']}\n"
42
+ end
43
+ end
44
+
45
+ raise ResourceNotFound.new([errors,message].compact.join("\n").strip)
46
+ end
47
+
48
+ resolver.many_matches do |matches|
49
+ message = "Multiple app_environments possible, please be more specific:\n"
50
+ matches.sort_by {|ae| ae.app}.each do |ae|
51
+ message << "\t#{ae.hierarchy_name}\n"
52
+ end
53
+ raise MultipleMatchesError.new(message)
54
+ end
55
+ end
56
+
57
+
26
58
  def initialize(api, attrs)
27
59
  super
28
60
 
@@ -219,12 +219,26 @@ module EY
219
219
  # Note that the role for an instance MUST be either "app" or "util".
220
220
  # No other value is acceptable. The "name" parameter can be anything,
221
221
  # but it only applies to utility instances.
222
+ #
223
+ # Note also that if you add a util instance, you *must* specify a
224
+ # name. This method will raise if you don't.
222
225
  def add_instance(opts)
223
226
  unless %w[app util].include?(opts[:role].to_s)
224
227
  # Fail immediately because we don't have valid arguments.
225
228
  raise InvalidInstanceRole, "Instance role must be one of: app, util"
226
229
  end
227
230
 
231
+ # Sanitize the name to remove whitespace if there is any
232
+ if opts[:name]
233
+ name = opts[:name].gsub(/\s+/, '')
234
+ end
235
+
236
+ if opts[:role] == 'util'
237
+ unless name && name.length > 0
238
+ raise InvalidInstanceName, "When specifying a util instance you must also specify a name."
239
+ end
240
+ end
241
+
228
242
  # We know opts[:role] is right, name can be passed straight to the API.
229
243
  # Return the response body for error output, logging, etc.
230
244
  return api.post("/environments/#{id}/add_instances", :request => {
@@ -308,7 +322,8 @@ module EY
308
322
 
309
323
  response = api.post("/environments/#{id}/remove_instances", :request => {
310
324
  :provisioned_id => instance.amazon_id,
311
- :role => instance.role
325
+ :role => instance.role,
326
+ :name => instance.name
312
327
  })
313
328
 
314
329
  # Reset instances so they are fresh if they are requested again.
@@ -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.14'
4
+ VERSION = '1.0.15'
5
5
  end
6
6
  end
7
7
  # Please be aware that the monkeys like tho throw poo sometimes.
@@ -6,12 +6,18 @@ describe EY::CloudClient::AppEnvironment do
6
6
  end
7
7
 
8
8
  describe ".resolve" do
9
- it "finds an environment" do
9
+ it "finds an app environment" do
10
10
  api = scenario_cloud_client "Multiple Ambiguous Accounts"
11
11
  result = api.resolve_app_environments('app_name' => 'rails232app', 'environment_name' => 'giblets', 'account_name' => 'main')
12
12
  result.should be_one_match
13
13
  end
14
14
 
15
+ it "finds an app environment" do
16
+ api = scenario_cloud_client "Multiple Ambiguous Accounts"
17
+ result = EY::CloudClient::AppEnvironment.resolve_one(api, 'app_name' => 'rails232app', 'environment_name' => 'giblets', 'account_name' => 'main')
18
+ result.should be_a(EY::CloudClient::AppEnvironment)
19
+ end
20
+
15
21
  it "returns multiple matches with ambiguous query" do
16
22
  api = scenario_cloud_client "Multiple Ambiguous Accounts"
17
23
  result = EY::CloudClient::AppEnvironment.resolve(api, 'app_name' => 'rails232app', 'environment_name' => 'giblets')
@@ -305,7 +305,8 @@ describe EY::CloudClient::Environment do
305
305
  'role' => 'util',
306
306
  'public_hostname' => 'some-hostname',
307
307
  'status' => 'running',
308
- 'amazon_id' => 'i-xxxxxxx'
308
+ 'amazon_id' => 'i-xxxxxxx',
309
+ 'name' => 'foo'
309
310
  },
310
311
  {
311
312
  'id' => 8675309,
@@ -382,6 +383,14 @@ describe EY::CloudClient::Environment do
382
383
  :content_type => "application/json", :body => MultiJson.dump('instances' => @instances_response))
383
384
  FakeWeb.should have_requested(:get, "https://cloud.engineyard.com/api/v2/environments/#{@env.id}/instances?")
384
385
  end
386
+
387
+ it "removes a util instance when name is supplied" do
388
+ i = @env.instance_by_id(54321) # util name "foo"
389
+ expect {
390
+ @env.remove_instance(i)
391
+ }.to_not raise_error
392
+ FakeWeb.should have_requested(:post, "https://cloud.engineyard.com/api/v2/environments/#{@env.id}/remove_instances")
393
+ end
385
394
  end
386
395
 
387
396
  describe "#add_instances(name: 'foo', role: 'app')" do
@@ -419,6 +428,18 @@ describe EY::CloudClient::Environment do
419
428
  FakeWeb.should_not have_requested(:post, "https://cloud.engineyard.com/api/v2/environments/#{@env.id}/add_instances")
420
429
  end
421
430
 
431
+ it "will raise if you specify util, but not name" do
432
+ expect {
433
+ @env.add_instance(:role => "util")
434
+ }.to raise_error EY::CloudClient::InvalidInstanceName
435
+ end
436
+
437
+ it "will raise with a blank name for util" do
438
+ expect {
439
+ @env.add_instance(:role => "util", :name => " ") # a space isn't a valid name, so test that too
440
+ }.to raise_error EY::CloudClient::InvalidInstanceName
441
+ end
442
+
422
443
  it "sends a POST request to the API" do
423
444
  @env.add_instance(:role => "app")
424
445
  FakeWeb.should have_requested(:post, "https://cloud.engineyard.com/api/v2/environments/#{@env.id}/add_instances")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: engineyard-cloud-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.14
4
+ version: 1.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - EY Cloud Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-05 00:00:00.000000000 Z
11
+ date: 2013-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.0
19
+ version: 1.6.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.0
26
+ version: 1.6.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: multi_json
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -355,7 +355,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
355
355
  version: '0'
356
356
  requirements: []
357
357
  rubyforge_project:
358
- rubygems_version: 2.0.6
358
+ rubygems_version: 2.1.10
359
359
  signing_key:
360
360
  specification_version: 4
361
361
  summary: EY Cloud API Client