right_api_provision 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -45,10 +45,7 @@ Example:
45
45
  server_inputs)
46
46
 
47
47
  # wait for server to be ready
48
- state = @rightscale.wait_for_state("operational", 30)
49
- if state != "operational"
50
- raise "Unexpected state. State: #{state}"
51
- end
48
+ state = @rightscale.wait_for_operational
52
49
 
53
50
  # Do stuff with your brand new server...
54
51
 
data/RELEASES.md ADDED
@@ -0,0 +1,14 @@
1
+ Release Notes
2
+ =============
3
+
4
+ 0.2.0
5
+ -----
6
+
7
+ * `wait_for_state` method changed to `wait_for_operational`
8
+ * added `server_ready?` method
9
+ * added `server_info` method
10
+ * ssh_keys_uuids and security groups now supported
11
+
12
+ 0.1.0
13
+ -----
14
+ Initial Release
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Cary Penniman (<cary@rightscale.com>)
3
+ # Copyright:: Copyright (c) 2013 RightScale, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
1
19
  module RightApiProvision
2
20
  class API15
3
21
 
@@ -13,6 +31,9 @@ module RightApiProvision
13
31
  @url = api_url
14
32
  args[:api_url] = @url if @url
15
33
  @connection ||= RightApi::Client.new(args)
34
+ #@logger = Logger.new(STDOUT)
35
+ #@logger.level = Logger::DEBUG
36
+ #@connection.log(@logger)
16
37
  @client = @connection
17
38
  rescue Exception => e
18
39
  args.delete(:password) # don't log password
@@ -23,6 +44,48 @@ module RightApiProvision
23
44
  end
24
45
  end
25
46
 
47
+ # If the cloud reports ssh keys, then we assume it requires them to launch
48
+ # servers.
49
+ def requires_ssh_keys?(cloud)
50
+ begin
51
+ cloud.show.ssh_keys
52
+ true
53
+ rescue RightApi::Exceptions::ApiException => e
54
+ false # assume cloud does not require them
55
+ end
56
+ end
57
+
58
+ # Find SSH key
59
+ #
60
+ # EC2 and Eucalyptus require an SSH key to launch a server. RightScale
61
+ # manages SSH keys for each user so just grabbing the first one is fine,
62
+ # however older configurations might relay on specific keys. You will
63
+ # need to grab the resource UUID from the RightScale dashboard for the key
64
+ # that you want to use.
65
+ def find_ssh_key_by_uuid_or_first(cloud, ssh_uuid = nil)
66
+ ssh_key = nil
67
+ if ssh_uuid
68
+ # grab specific ssh key
69
+ sshkey = find_resource(:ssh_keys, :by_resource_uid, uuid)
70
+ else
71
+ # grab first key found
72
+ keys = cloud.show.ssh_keys
73
+ ssh_key = keys.index.first if keys
74
+ end
75
+ ssh_key
76
+ end
77
+
78
+ # If the cloud reports security groups then we assume it requires them to launch
79
+ # servers.
80
+ def requires_security_groups?(cloud)
81
+ begin
82
+ cloud.show.security_groups
83
+ true
84
+ rescue RightApi::Exceptions::ApiException => e
85
+ false # assume cloud does not require them
86
+ end
87
+ end
88
+
26
89
  def user_data(server)
27
90
  @user_data ||= server.show.current_instance(:view=>"extended").show.user_data
28
91
  end
@@ -36,43 +99,60 @@ module RightApiProvision
36
99
  "#{@url}/servers/data_injection_payload/#{token}"
37
100
  end
38
101
 
39
- def find_server_by_name(name)
40
- server_list = @connection.servers.index(:filter => ["name==#{name}"])
41
- raise "More than one server with the name of '#{name}'. " +
42
- "Please fix via the RightScale dashboard and retry." if server_list.size > 1
43
- server_list.first
102
+ def delete_server(name)
103
+ server = find_server_by_name(name)
104
+ server.terminate
105
+ begin
106
+ server_wait_for_state(server, "terminated")
107
+ rescue Exception => e
108
+
109
+ end
110
+ server.destroy
44
111
  end
45
112
 
46
- def find_deployment_by_name(name)
47
- deployment = nil
48
- deployments_list = @connection.deployments.index(:filter => ["name==#{name}"])
49
- raise "More than one deployment with the name of '#{name}'. " +
50
- "Please fix via the RightScale dashboard and retry." if deployments_list.size > 1
51
- deployment = deployments_list.first unless deployments_list.empty?
52
- deployment
113
+ def list_servers(filter_by, filter_value)
114
+ list_resources(:servers, filter_by, filter_value)
115
+ end
116
+
117
+ def list_deployments(filter_by, filter_value)
118
+ list_resources(:deployments, filter_by, filter_value)
119
+ end
120
+
121
+ def list_clouds(filter_by, filter_value)
122
+ list_resources(:clouds, filter_by, filter_value)
123
+ end
124
+
125
+ def list_servertemplates(filter_by, filter_value)
126
+ list_resources(:server_templates, filter_by, filter_value)
53
127
  end
54
128
 
55
- def list_clouds
56
- @connection.clouds.index
129
+ def list_security_groups(cloud, filter_by, filter_value)
130
+ list_subresources(cloud, :security_groups, filter_by, filter_value)
131
+ end
132
+
133
+ def list_multi_cloud_images(server_template, filter_by, filter_value)
134
+ list_subresources(server_template, :multi_cloud_images, filter_by, filter_value)
135
+ end
136
+
137
+ def find_security_group_by_name(cloud, security_group_name)
138
+ find_cloud_resource(cloud, :security_groups, :by_name, security_group_name)
139
+ end
140
+
141
+ def find_server_by_name(name)
142
+ find_resource(:servers, :by_name, name)
143
+ end
144
+
145
+ def find_deployment_by_name(name)
146
+ find_resource(:deployments, :by_name, name)
57
147
  end
58
148
 
59
149
  # returns:: String if cloud is found, nil if not found
60
150
  def find_cloud_by_name(name)
61
- cloud = nil
62
- cloud_list = @connection.clouds.index(:filter => ["name==#{name}"])
63
- raise "More than one cloud with the name of '#{name}'. " +
64
- "Please fix via the RightScale dashboard and retry." if cloud_list.size > 1
65
- cloud = cloud_list.first unless cloud_list.empty?
66
- cloud
151
+ find_resource(:clouds, :by_name, name)
67
152
  end
68
153
 
69
- def find_mci_by_name(mci_name)
70
- mci = nil
71
- mci_list = @connection.multi_cloud_images.index(:filter => ["name==#{mci_name}"])
72
- raise "More than one MultiCloud image with the name of '#{mci_name}'. " +
73
- "Please fix via the RightScale dashboard and retry." if mci_list.size > 1
74
- mci = mci_list.first unless mci_list.empty?
75
- mci
154
+ def find_mci_by_name(name)
155
+ find_resource(:multi_cloud_images, :by_name, name)
76
156
  end
77
157
 
78
158
  def find_servertemplate(name_or_id)
@@ -88,18 +168,18 @@ module RightApiProvision
88
168
 
89
169
  if name
90
170
  # find ServerTemplate by name
91
- st_list = @connection.server_templates.index(:filter => ["name==#{name}"])
92
- num_matching_sts = 0
93
- st_list.each do |st|
94
- if st.name == name
95
- server_template = st
96
- num_matching_sts += 1
97
- end
98
- end
99
- raise "ERROR: Unable to find ServerTemplate with the name of '#{name}' found " unless server_template
100
- raise "ERROR: More than one ServerTemplate with the name of '#{name}' found " +
101
- "in account. Please fix via the RightScale dashboard and retry." if num_matching_sts > 1
171
+ st_list = list_resources(:server_templates, :by_name, name)
172
+ revisions = st_list.map { |st| st.revision }
173
+
174
+ # check for duplicate revisions
175
+ duplicates = (revisions.size != revisions.uniq.size)
176
+ raise "ERROR: Duplicate ServerTemplate with the name of '#{name}' detected " +
177
+ "in account -- there can be only one. Please fix via the RightScale dashboard and retry." if duplicates
102
178
 
179
+ # always use latest revision
180
+ latest_rev = revisions.sort.last
181
+ server_template = st_list.select { |st| st.revision == latest_rev}.first
182
+ raise "ERROR: Unable to find ServerTemplate with the name of '#{name}' found " unless server_template
103
183
  else
104
184
  # find ServerTemplate by id
105
185
  server_template = @connection.server_templates.index(:id => id)
@@ -116,7 +196,8 @@ module RightApiProvision
116
196
  deployment.destroy
117
197
  end
118
198
 
119
- def create_server(deployment, server_template, mci, cloud, name)
199
+ def create_server(deployment, server_template, mci, cloud, name, ssh_key = nil, groups = nil)
200
+
120
201
  # check params
121
202
  unless st_href = server_template.show.href
122
203
  raise "ERROR: ServerTemplate parameter not initialized properly"
@@ -136,22 +217,44 @@ module RightApiProvision
136
217
  raise "ERROR: Deployment parameter not initialized properly"
137
218
  end
138
219
 
139
- # create server in deployment using specfied ST
140
- create_params = {
141
- :server => {
142
- :name => name,
143
- :decription => "Created by the Vagrant",
144
- :deployment_href => d_href,
145
- :instance => {
146
- :cloud_href => c_href,
147
- :server_template_href => st_href
148
- }
149
- }
220
+ if ssh_key
221
+ unless ssh_key_href = ssh_key.show.href
222
+ raise "ERROR: ssh_key parameter not initialized properly"
223
+ end
224
+ end
225
+
226
+ security_group_hrefs = nil
227
+ if groups
228
+ security_group_hrefs = []
229
+ groups.each do |group|
230
+ unless group_href = group.show.href
231
+ raise "ERROR: ssh_key parameter not initialized properly"
232
+ end
233
+ security_group_hrefs << group_href
234
+ end
235
+ end
236
+
237
+ instance_hash = {
238
+ :cloud_href => c_href,
239
+ :server_template_href => st_href
150
240
  }
241
+ instance_hash[:ssh_key_href] = ssh_key_href if ssh_key
242
+ instance_hash[:security_group_hrefs] = security_group_hrefs if security_group_hrefs
243
+
151
244
  # Use the MCI if provided otherwise let the API choose the default MCI
152
245
  # in the ServerTemplate.
153
- create_params[:server][:instance][:multi_cloud_image_href] = mci_href unless mci_href.nil?
154
- server = @connection.servers.create(create_params)
246
+ instance_hash[:multi_cloud_image_href] = mci_href unless mci_href.nil?
247
+
248
+ # create server in deployment using specfied ST
249
+ server =
250
+ @connection.servers.create({
251
+ :server => {
252
+ :name => name,
253
+ :decription => "Created by the right_provision_api", #TODO: pass this as a param
254
+ :deployment_href => d_href,
255
+ :instance => instance_hash
256
+ }
257
+ })
155
258
  end
156
259
 
157
260
  def is_provisioned?(server)
@@ -204,6 +307,10 @@ module RightApiProvision
204
307
  cloud.show.name
205
308
  end
206
309
 
310
+ def server_info(server)
311
+ server.show.current_instance.show(:view => 'extended')
312
+ end
313
+
207
314
  private
208
315
 
209
316
  def server_state(server)
@@ -213,7 +320,11 @@ module RightApiProvision
213
320
  def instance_from_server(server)
214
321
  server_data = server.show
215
322
  if is_provisioned?(server)
216
- server_data.current_instance
323
+ begin
324
+ server_data.current_instance
325
+ rescue
326
+ server_data.next_instance
327
+ end
217
328
  else
218
329
  server_data.next_instance
219
330
  end
@@ -223,5 +334,47 @@ module RightApiProvision
223
334
  instance.show.cloud
224
335
  end
225
336
 
337
+ def find_resource(api_resource, filter_key, filter_value)
338
+ resource = nil
339
+ list = list_resources(api_resource, filter_key, filter_value)
340
+ raise "More than one #{api_resource} with the #{filter_key} of '#{filter_value}'. " +
341
+ "Please resolve via the RightScale dashboard and retry." if list.size > 1
342
+ resource = list.first unless list.empty?
343
+ resource
344
+ end
345
+
346
+ def list_resources(api_resource, filter_key, filter_value)
347
+ raise ArgumentError.new("api_resource must be a symbol") unless api_resource.kind_of?(Symbol)
348
+ key = filter_key.to_s.delete("by_") # convert :by_name to "name"
349
+ filter = {}
350
+ filter = {:filter => ["#{key}==#{filter_value}"]} if filter_value
351
+ list = @connection.send(api_resource).index(filter)
352
+ list
353
+ end
354
+
355
+ def index_resource(api_resource, index_key, index_value)
356
+ raise ArgumentError.new("api_resource must be a symbol") unless api_resource.kind_of?(Symbol)
357
+ arry = @connection.send(api_resource).index(index_key => index_value)
358
+ arry
359
+ end
360
+
361
+ def find_cloud_resource(cloud, api_resource, filter_key, filter_value)
362
+ resource = nil
363
+ list = list_subresources(cloud, api_resource, filter_key, filter_value)
364
+ raise "More than one #{api_resource} with the #{filter_key} of '#{filter_value}'. " +
365
+ "Please resolve via the RightScale dashboard and retry." if list.size > 1
366
+ resource = list.first unless list.empty?
367
+ resource
368
+ end
369
+
370
+ def list_subresources(api_resource, subresource, filter_key, filter_value)
371
+ raise ArgumentError.new("subresource must be a symbol") unless subresource.kind_of?(Symbol)
372
+ key = filter_key.to_s.delete("by_") # convert :by_name to "name"
373
+ filter = {}
374
+ filter = {:filter => ["#{key}==#{filter_value}"]} if filter_value
375
+ list = api_resource.show.send(subresource).index(filter)
376
+ list
377
+ end
378
+
226
379
  end
227
- end
380
+ end
@@ -31,13 +31,14 @@ module RightApiProvision
31
31
  require "logger"
32
32
 
33
33
  RETRY_DELAY = 10 # seconds
34
+ BAD_STATES_UP = [ "stranded", "terminated"]
34
35
 
35
36
  def initialize(email, password, account_id, api_url = nil)
36
37
  require_relative "exception"
37
38
  require_relative "api15"
38
39
  @logger = ::Logger.new(STDOUT)
39
- @client = RightApiProvision::API15.new
40
- @client.connection(email, password, account_id, api_url)
40
+ @rsapi = RightApiProvision::API15.new
41
+ @rsapi.connection(email, password, account_id, api_url)
41
42
  end
42
43
 
43
44
  def logger(logger)
@@ -48,16 +49,12 @@ module RightApiProvision
48
49
  raise "No server provisioned. No connection URL available." unless @server
49
50
  unless @data_request_url
50
51
  user_data = @server.current_instance.show(:view => "full").user_data
51
- @data_request_url = @client.data_request_url(user_data)
52
+ @data_request_url = @rsapi.data_request_url(user_data)
52
53
  @logger.debug "Data Request URL: #{@data_request_url}"
53
54
  end
54
55
  @data_request_url
55
56
  end
56
57
 
57
- def wait_for_state(desired_state, timeout_sec = RETRY_DELAY)
58
- @client.server_wait_for_state(@server, desired_state, timeout_sec)
59
- end
60
-
61
58
  # Provision a server using RightScale
62
59
  #
63
60
  # @param server_name [String] the name to give the server that will be
@@ -67,7 +64,7 @@ module RightApiProvision
67
64
  # @param cloud_name [String] name of cloud to provision on.
68
65
  # @param deployment_name [String] name of deployment to add the server to.
69
66
  # This will be created if it does not exist.
70
- # @param server_inputs [Array] An array of {Input} objects.
67
+ # @param inputs [Array] An array of {Input} objects.
71
68
  # @param ssh_key_id [String] The resource_uuid of an ssh key from the
72
69
  # RightScale dashboard. Only required on EC2 and Eucalyptus.
73
70
  # @param secgroup_id [Array] An array of security group IDs to place the
@@ -75,20 +72,17 @@ module RightApiProvision
75
72
  #
76
73
  # @raise {RightApiProvisionException} if anything
77
74
  # goes wrong
78
- def provision(
79
- server_name,
80
- server_template,
81
- cloud_name,
82
- deployment_name,
83
- server_inputs,
84
- multi_cloud_image_name,
85
- ssh_key_id = nil, #TODO: support me
86
- secgroup_id = nil, #TODO: support me
87
- datacenter = nil) #TODO: support me
88
-
75
+ def provision(servertemplate,
76
+ server_name = "default",
77
+ cloud_name = "ec2",
78
+ deployment_name = "default",
79
+ inputs = nil,
80
+ multi_cloud_image_name = nil,
81
+ ssh_key_uuid = nil,
82
+ security_groups = nil)
89
83
 
90
84
  # fail if the requested cloud is not registered with RightScale account
91
- @cloud = @client.find_cloud_by_name(cloud_name)
85
+ @cloud = @rsapi.find_cloud_by_name(cloud_name)
92
86
  unless @cloud
93
87
  clouds = @client.list_clouds.inject("") { |str, c| str == "" ? c.name : "#{str}, #{c.name}" }
94
88
  raise RightScaleError, "ERROR: cannot find a cloud named: '#{cloud_name}'. " +
@@ -97,21 +91,36 @@ module RightApiProvision
97
91
  "your RightScale account? Supported clouds: #{clouds}"
98
92
  end
99
93
 
94
+ # Verify ssh key uuid, if required by cloud
95
+ if @rsapi.requires_ssh_keys?(@cloud)
96
+ @ssh_key = @rsapi.find_ssh_key_by_uuid_or_first(@cloud, ssh_key_uuid)
97
+ raise "ERROR: cannot find an ssh_key named: #{ssh_key_uuid}" unless @ssh_key
98
+ end
99
+
100
+ # Verify security group, if required by cloud
101
+ if @rsapi.requires_security_groups?(@cloud)
102
+ @sec_groups = []
103
+ security_groups ||= ["default"]
104
+ security_groups.each do |name|
105
+ group = @rsapi.find_security_group_by_name(@cloud, name)
106
+ raise "ERROR: cannot find an security group named: #{name}" unless group
107
+ @sec_groups << group
108
+ end
109
+ end
110
+
100
111
  # check for existing deployment and server in RightScale account
101
- @deployment = @client.find_deployment_by_name(deployment_name)
112
+ @deployment = @rsapi.find_deployment_by_name(deployment_name)
102
113
  @logger.info "Deployment '#{deployment_name}' #{@deployment ? "found." : "not found."}"
103
- @server = @client.find_server_by_name(server_name) if @deployment
114
+ @server = @rsapi.find_server_by_name(server_name) if @deployment
104
115
  @logger.info "Server '#{server_name}' #{@server ? "found." : "not found."}"
105
116
 
106
- # XXX: fails if the server is not running -- fix me!
107
- # if @server
108
- # # verify existing server is on the cloud we are requesting, if not fail.
109
- # cloud_name ||= Config::VAGRANT_CLOUD_NAME
110
- # actual_cloud_name = @client.server_cloud_name(@server)
111
- # raise RightScaleError, "ERROR: the server is in the '#{actual_cloud_name}' cloud, " +
112
- # "and not in the requested '#{cloud_name}' cloud.\n" +
113
- # "Please delete the server or pick and new server name." if cloud_name != actual_cloud_name
114
- # end
117
+ if @server
118
+ # verify existing server is on the cloud we are requesting, if not fail.
119
+ actual_cloud_name = @rsapi.server_cloud_name(@server)
120
+ raise "ERROR: the server is in the '#{actual_cloud_name}' cloud, " +
121
+ "and not in the requested '#{cloud_name}' cloud.\n" +
122
+ "Please delete the server or pick and new server name." if cloud_name != actual_cloud_name
123
+ end
115
124
 
116
125
  unless @deployment && @server
117
126
  # we need to create a server, can we find the servertemplate?
@@ -120,11 +129,8 @@ module RightApiProvision
120
129
  rescue
121
130
  raise RightScaleError, "ERROR: cannot find ServerTemplate '#{server_template}'. Did you import it?\n" +
122
131
  "Visit http://bit.ly/VnOiA7 for more info.\n\n"
123
- # can we find the MCI?
124
132
  end
125
- end
126
133
 
127
- unless @deployment && @server
128
134
  # We need to find the to be used in the server if the MCI name is given
129
135
  begin
130
136
  @mci =
@@ -142,52 +148,51 @@ module RightApiProvision
142
148
 
143
149
  # create deployment and server as needed
144
150
  unless @deployment
145
- @deployment = @client.create_deployment(deployment_name)
151
+ @deployment = @rsapi.create_deployment(deployment_name)
146
152
  @logger.info "Created deployment."
147
153
  end
148
154
 
149
155
  unless @server
150
- @server = @client.create_server(@deployment, @servertemplate, @mci, @cloud, server_name)
156
+ @server = @rsapi.create_server(@deployment, @servertemplate, @mci, @cloud, server_name, @ssh_key, @sec_groups)
151
157
  @logger.info "Created server."
152
158
  end
153
159
 
154
- unless @client.is_provisioned?(@server)
160
+ unless @rsapi.is_provisioned?(@server)
155
161
 
156
162
  # setup any inputs
157
163
  begin
158
- @client.set_server_inputs(@server, server_inputs) if server_inputs && ! server_inputs.empty?
164
+ @client.set_server_inputs(@server, inputs) if inputs && ! inputs.empty?
159
165
  rescue Exception => e
160
166
  raise RightScaleError, "Problem setting inputs. \n #{e.message}\n\n"
161
- # can we find the MCI?
162
- #TODO: @mci = @client.find_multicloudimage_by_name(@servertemplate, multi_cloud_image_name)
163
167
  end
164
168
 
165
169
  # launch server
166
170
  @logger.info "Launching server..."
167
- @server = @client.launch_server(@server, server_inputs)
168
- @client.server_wait_for_state(@server, "booting")
171
+ @server = @rsapi.launch_server(@server, inputs)
172
+ @rsapi.set_bad_states(BAD_STATES_UP)
173
+ @rsapi.server_wait_for_state(@server, "booting", 30)
169
174
  end
170
175
 
171
176
  end
172
177
 
173
- # Register a custom progress indicator
174
- #
175
- # @example
176
- # do
177
- # @TODO: add an example
178
- # end
179
- # @param progress_block [Block] block to execute before each loop iteration.
180
- # @yield [Logger] A Logger object will be passed as a parameter into
181
- # your block.
182
- def register_progress_indicator(&progress_block)
183
- @progress_indicator = progress_block
178
+ def server_ready?
179
+ @rsapi.server_ready?(@server)
184
180
  end
185
181
 
186
- end
187
- end
188
-
189
-
190
-
191
-
182
+ def wait_for_operational
183
+ @rsapi.set_bad_states(BAD_STATES_UP)
184
+ @rsapi.server_wait_for_state(@server, "operational", 30)
185
+ end
192
186
 
187
+ def server_info
188
+ info = @rsapi.server_info(@server)
189
+ while info.private_ip_addresses.empty?
190
+ @logger.info "Waiting for cloud to provide IP address..."
191
+ sleep 30
192
+ info = @rsapi.server_info(@server)
193
+ end
194
+ info
195
+ end
193
196
 
197
+ end
198
+ end
@@ -1,3 +1,3 @@
1
1
  module RightApiProvision
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -68,7 +68,7 @@ describe "API15 object" do
68
68
  end
69
69
 
70
70
  it "should find servertemplate by name" do
71
- servertemplatesStub = double("servertemplates", :index => [ double("servertemplate", :name => "my_fake_servertemplate") ])
71
+ servertemplatesStub = double("servertemplates", :index => [ double("servertemplate", :name => "my_fake_servertemplate", :revision => [0, 1, 2, 3, 4 ]) ])
72
72
  @api.instance_variable_get("@connection").should_receive(:server_templates).and_return(servertemplatesStub)
73
73
  @api.find_servertemplate("my_fake_servertemplate")
74
74
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_api_provision
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
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: 2014-03-20 00:00:00.000000000 Z
12
+ date: 2014-03-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: right_api_client
@@ -119,6 +119,7 @@ files:
119
119
  - Gemfile
120
120
  - LICENSE.txt
121
121
  - README.md
122
+ - RELEASES.md
122
123
  - Rakefile
123
124
  - lib/right_api_provision.rb
124
125
  - lib/right_api_provision/api15.rb
@@ -145,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
145
146
  version: '0'
146
147
  segments:
147
148
  - 0
148
- hash: -4414243138993754310
149
+ hash: -2827224809426864135
149
150
  required_rubygems_version: !ruby/object:Gem::Requirement
150
151
  none: false
151
152
  requirements:
@@ -154,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
155
  version: '0'
155
156
  segments:
156
157
  - 0
157
- hash: -4414243138993754310
158
+ hash: -2827224809426864135
158
159
  requirements: []
159
160
  rubyforge_project:
160
161
  rubygems_version: 1.8.23