deltacloud-client 0.0.2 → 0.0.3

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.
data/bin/deltacloudc ADDED
@@ -0,0 +1,152 @@
1
+ #!/bin/env ruby
2
+ #
3
+ # Copyright (C) 2009 Red Hat, Inc.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+
19
+ require 'rubygems'
20
+ require 'optparse'
21
+ require 'uri'
22
+ require 'deltacloud'
23
+
24
+ options = {
25
+ :verbose => false
26
+ }
27
+
28
+ @optparse = OptionParser.new do |opts|
29
+
30
+ opts.banner = <<BANNER
31
+ Usage:
32
+ deltacloudc collection operation [options]
33
+
34
+ URL format:
35
+ API_URL=http://[user]:[password]@[api_url][port][/uri]
36
+
37
+ Options:
38
+ BANNER
39
+ opts.on( '-i', '--id ID', 'ID for operation') { |id| options[:id] = id }
40
+ opts.on( '-d', '--image-id ID', 'Image ID') { |id| options[:image_id] = id }
41
+ opts.on( '-a', '--arch ARCH', 'Architecture (x86, x86_64)') { |id| options[:architecture] = id }
42
+ opts.on( '-f', '--flavor_id FLAVOR', 'Flavor') { |id| options[:flavor_id] = id }
43
+ opts.on( '-n', '--name NAME', 'Name (for instance eg.)') { |name| options[:name] = name }
44
+ opts.on( '-s', '--state STATE', 'Instance state (RUNNING, STOPPED)') { |state| options[:state] = state }
45
+ opts.on( '-u', '--url URL', 'API url ($API_URL variable)') { |url| options[:api_url] = url }
46
+ opts.on( '-l', '--list', 'List collections/operations') { |id| options[:list] = true }
47
+ opts.on( '-h', '--help', 'Display this screen' ) { puts opts ; exit }
48
+ opts.on( '-v', '--version', 'Display API version' ) { options[:version]=true }
49
+ opts.on( '-V', '--verbose', 'Print verbose messages' ) { options[:verbose]=true }
50
+ end
51
+
52
+ def invalid_usage(error_msg='')
53
+ puts "ERROR: #{error_msg}"
54
+ exit(1)
55
+ end
56
+
57
+ @optparse.parse!
58
+
59
+ # First try to get API_URL from environment
60
+ options[:api_url] = ENV['API_URL'] if options[:api_url].nil?
61
+
62
+ url = URI.parse(options[:api_url])
63
+ api_url = "http://#{url.host}#{url.port ? ":#{url.port}" : ''}#{url.path}"
64
+
65
+ options[:collection] = ARGV[0]
66
+ options[:operation] = ARGV[1]
67
+
68
+ # Connect to Deltacloud API and fetch all entry points
69
+ client = DeltaCloud.new(url.user, url.password, api_url, { :verbose => options[:verbose] })
70
+ collections = client.entry_points.keys
71
+
72
+ # Exclude collection which don't have methods in client library yet
73
+ collections.delete(:hardware_profiles)
74
+ collections.delete(:instance_states)
75
+
76
+ # If list parameter passed print out available collection
77
+ # with API documentation
78
+ if options[:list] and options[:collection].nil?
79
+ collections.each do |c|
80
+ doc = client.fetch_documentation(c.to_s)
81
+ puts sprintf("%-22s: %s", c.to_s[0, 22], doc[:description])
82
+ end
83
+ exit(0)
84
+ end
85
+
86
+ # If collection parameter is present and user requested list
87
+ # print all operation defined for collection with API documentation
88
+ if options[:list] and options[:collection]
89
+ doc = client.fetch_documentation(options[:collection])
90
+ doc[:operations].each do |c|
91
+ puts sprintf("%-20s: %s", c[:name][0, 20], c[:description])
92
+ end
93
+ exit(0)
94
+ end
95
+
96
+ if options[:version]
97
+ puts "Deltacloud API(#{client.driver_name}) 0.1"
98
+ exit(0)
99
+ end
100
+
101
+ # List items from collection (typically /flavors)
102
+ # Do same if 'index' operation is set
103
+ if options[:collection] and ( options[:operation].nil? or options[:operation].eql?('index') )
104
+ invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)
105
+ params = {}
106
+ params.merge!(:architecture => options[:architecture]) if options[:architecture]
107
+ params.merge!(:id => options[:id]) if options[:id]
108
+ params.merge!(:state => options[:state]) if options[:state]
109
+ client.send(options[:collection].to_s, params).each do |model|
110
+ puts model.to_plain
111
+ end
112
+ exit(0)
113
+ end
114
+
115
+ if options[:collection] and options[:operation]
116
+
117
+ invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)
118
+
119
+ params = {}
120
+ params.merge!(:id => options[:id]) if options[:id]
121
+
122
+ # If collection is set and requested operation is 'show' just 'singularize'
123
+ # collection name and print item with specified id (-i parameter)
124
+ if options[:operation].eql?('show')
125
+ puts client.send(options[:collection].gsub(/s$/, ''), options[:id] ).to_plain
126
+ exit(0)
127
+ end
128
+
129
+ # If collection is set and requested operation is create new instance,
130
+ # --image-id, --flavor-id and --name parameters are used
131
+ # Returns created instance in plain form
132
+ if options[:collection].eql?('instances') and options[:operation].eql?('create')
133
+ params.merge!(:name => options[:name]) if options[:name]
134
+ params.merge!(:image_id => options[:image_id]) if options[:image_id]
135
+ params.merge!(:flavor_id => options[:flavor_id]) if options[:flavor_id]
136
+ instance = client.create_instance(options[:image_id], params)
137
+ puts instance.to_plain
138
+ exit(0)
139
+ end
140
+
141
+ # All other operations above collections is done there:
142
+ if options[:collection].eql?('instances')
143
+ instance = client.instance(options[:id])
144
+ instance.send("#{options[:operation]}!".to_s)
145
+ instance = client.instance(options[:id])
146
+ puts instance.to_plain
147
+ exit(0)
148
+ end
149
+ end
150
+
151
+ # If all above passed (eg. no parameters)
152
+ puts @optparse
data/lib/dcloud/flavor.rb CHANGED
@@ -39,5 +39,11 @@ module DCloud
39
39
  @architecture = xml.text( 'architecture' )
40
40
  end
41
41
  end
42
+
43
+ def to_plain
44
+ sprintf("%-15s | %-6s | %10s GB | %10s GB", self.id[0, 15], self.architecture[0,6],
45
+ self.memory.to_s[0,10], self.storage.to_s[0,10])
46
+ end
47
+
42
48
  end
43
49
  end
data/lib/dcloud/image.rb CHANGED
@@ -42,5 +42,15 @@ module DCloud
42
42
  end
43
43
  end
44
44
 
45
+ def to_plain
46
+ sprintf("%-10s | %-20s | %-6s | %-20s | %15s",
47
+ self.id[0,10],
48
+ self.name ? self.name[0, 20]: 'unknown',
49
+ self.architecture[0,6],
50
+ self.description[0,20],
51
+ self.owner_id[0,15]
52
+ )
53
+ end
54
+
45
55
  end
46
56
  end
@@ -39,6 +39,17 @@ module DCloud
39
39
  super( client, uri, xml )
40
40
  end
41
41
 
42
+ def to_plain
43
+ sprintf("%-15s | %-15s | %-15s | %10s | %32s | %32s",
44
+ self.id ? self.id[0,15] : '-',
45
+ self.name ? self.name[0,15] : 'unknown',
46
+ self.image.name ? self.image.name[0,15] : 'unknown',
47
+ self.state ? self.state.to_s[0,10] : 'unknown',
48
+ self.public_addresses.join(',')[0,32],
49
+ self.private_addresses.join(',')[0,32]
50
+ )
51
+ end
52
+
42
53
  def start!()
43
54
  url = action_urls['start']
44
55
  throw Exception.new( "Unable to start" ) unless url
data/lib/dcloud/realm.rb CHANGED
@@ -43,5 +43,15 @@ module DCloud
43
43
  end
44
44
  end
45
45
  end
46
+
47
+ def to_plain
48
+ sprintf("%-10s | %-15s | %-5s | %10s GB",
49
+ self.id[0, 10],
50
+ self.name[0, 15],
51
+ self.state[0,5],
52
+ self.limit.to_s[0,10]
53
+ )
54
+ end
55
+
46
56
  end
47
57
  end
@@ -27,6 +27,15 @@ module DCloud
27
27
  attribute :state
28
28
  attribute :storage_volume
29
29
 
30
+ def to_plain
31
+ sprintf("%-10s | %-15s | %-6s | %15s",
32
+ self.id[0,10],
33
+ self.storage_volume.name ? self.storage_volume.name[0, 15] : 'unknown',
34
+ self.state ? self.state[0,6] : 'unknown',
35
+ self.created ? self.created[0,15] : 'unknown'
36
+ )
37
+ end
38
+
30
39
  def initialize(client, uri, xml=nil)
31
40
  super( client, uri, xml )
32
41
  end
@@ -32,6 +32,16 @@ module DCloud
32
32
  super( client, uri, xml )
33
33
  end
34
34
 
35
+ def to_plain
36
+ sprintf("%-10s | %15s GB | %-10s | %-10s | %-15s",
37
+ self.id[0,10],
38
+ self.capacity ? self.capacity.to_s[0,15] : 'unknown',
39
+ self.device ? self.device[0,10] : 'unknown',
40
+ self.state ? self.state[0,10] : 'unknown',
41
+ self.instance ? self.instance.name[0,15] : 'unknown'
42
+ )
43
+ end
44
+
35
45
  def load_payload(xml=nil)
36
46
  super(xml)
37
47
  unless xml.nil?
data/lib/deltacloud.rb CHANGED
@@ -28,20 +28,13 @@ require 'dcloud/state'
28
28
  require 'dcloud/transition'
29
29
  require 'base64'
30
30
 
31
- module RestClient
32
- class Response
33
- def body
34
- self.to_s
35
- end
36
- end
37
- end
38
-
39
31
  class DeltaCloud
40
32
 
41
33
  attr_accessor :logger
42
34
  attr_reader :api_uri
43
35
  attr_reader :entry_points
44
36
  attr_reader :driver_name
37
+ attr_reader :last_request_xml
45
38
 
46
39
  def self.driver_name(url)
47
40
  DeltaCloud.new( nil, nil, url) do |client|
@@ -49,12 +42,13 @@ class DeltaCloud
49
42
  end
50
43
  end
51
44
 
52
- def initialize(name, password, api_uri, &block)
45
+ def initialize(name, password, api_uri, opts={}, &block)
53
46
  @logger = Logger.new( STDERR )
54
47
  @name = name
55
48
  @password = password
56
49
  @api_uri = URI.parse( api_uri )
57
50
  @entry_points = {}
51
+ @verbose = opts[:verbose]
58
52
  discover_entry_points
59
53
  connect( &block )
60
54
  self
@@ -94,7 +88,7 @@ class DeltaCloud
94
88
 
95
89
  def flavor(id)
96
90
  request( entry_points[:flavors], :get, {:id=>id } ) do |response|
97
- doc = REXML::Document.new( response.body )
91
+ doc = REXML::Document.new( response )
98
92
  doc.get_elements( '/flavor' ).each do |flavor|
99
93
  uri = flavor.attributes['href']
100
94
  return DCloud::Flavor.new( self, uri, flavor )
@@ -110,7 +104,7 @@ class DeltaCloud
110
104
 
111
105
  def fetch_resource(type, uri)
112
106
  request( uri ) do |response|
113
- doc = REXML::Document.new( response.body )
107
+ doc = REXML::Document.new( response )
114
108
  if ( doc.root && ( doc.root.name == type.to_s.gsub( /_/, '-' ) ) )
115
109
  return doc.root
116
110
  end
@@ -118,10 +112,42 @@ class DeltaCloud
118
112
  nil
119
113
  end
120
114
 
115
+ def fetch_documentation(collection, operation=nil)
116
+ response = @http["docs/#{collection}#{operation ? "/#{operation}" : ''}"].get(:accept => "application/xml")
117
+ doc = REXML::Document.new( response.to_s )
118
+ if operation.nil?
119
+ docs = {
120
+ :name => doc.get_elements('docs/collection').first.attributes['name'],
121
+ :description => doc.get_elements('docs/collection/description').first.text,
122
+ :operations => []
123
+ }
124
+ doc.get_elements('docs/collection/operations/operation').each do |operation|
125
+ p = {}
126
+ p[:name] = operation.attributes['name']
127
+ p[:description] = operation.get_elements('description').first.text
128
+ p[:parameters] = []
129
+ operation.get_elements('parameter').each do |param|
130
+ p[:parameters] << param.attributes['name']
131
+ end
132
+ docs[:operations] << p
133
+ end
134
+ else
135
+ docs = {
136
+ :name => doc.get_elements('docs/operation').attributes['name'],
137
+ :description => doc.get_elements('docs/operation/description').first.text,
138
+ :parameters => []
139
+ }
140
+ doc.get_elements('docs/operation/parameter').each do |param|
141
+ docs[:parameters] << param.attributes['name']
142
+ end
143
+ end
144
+ docs
145
+ end
146
+
121
147
  def instance_states
122
148
  states = []
123
149
  request( entry_points[:instance_states] ) do |response|
124
- doc = REXML::Document.new( response.body )
150
+ doc = REXML::Document.new( response )
125
151
  doc.get_elements( 'states/state' ).each do |state_elem|
126
152
  state = DCloud::State.new( state_elem.attributes['name'] )
127
153
  state_elem.get_elements( 'transition' ).each do |transition_elem|
@@ -144,7 +170,7 @@ class DeltaCloud
144
170
  def realms(opts={})
145
171
  realms = []
146
172
  request( entry_points[:realms], :get, opts ) do |response|
147
- doc = REXML::Document.new( response.body )
173
+ doc = REXML::Document.new( response )
148
174
  doc.get_elements( 'realms/realm' ).each do |realm|
149
175
  uri = realm.attributes['href']
150
176
  realms << DCloud::Realm.new( self, uri, realm )
@@ -155,7 +181,7 @@ class DeltaCloud
155
181
 
156
182
  def realm(id)
157
183
  request( entry_points[:realms], :get, {:id=>id } ) do |response|
158
- doc = REXML::Document.new( response.body )
184
+ doc = REXML::Document.new( response )
159
185
  doc.get_elements( 'realm' ).each do |realm|
160
186
  uri = realm.attributes['href']
161
187
  return DCloud::Realm.new( self, uri, realm )
@@ -174,7 +200,7 @@ class DeltaCloud
174
200
  images = []
175
201
  request_path = entry_points[:images]
176
202
  request( request_path, :get, opts ) do |response|
177
- doc = REXML::Document.new( response.body )
203
+ doc = REXML::Document.new( response )
178
204
  doc.get_elements( 'images/image' ).each do |image|
179
205
  uri = image.attributes['href']
180
206
  images << DCloud::Image.new( self, uri, image )
@@ -185,7 +211,7 @@ class DeltaCloud
185
211
 
186
212
  def image(id)
187
213
  request( entry_points[:images], :get, {:id=>id } ) do |response|
188
- doc = REXML::Document.new( response.body )
214
+ doc = REXML::Document.new( response )
189
215
  doc.get_elements( 'image' ).each do |instance|
190
216
  uri = instance.attributes['href']
191
217
  return DCloud::Image.new( self, uri, instance )
@@ -194,10 +220,10 @@ class DeltaCloud
194
220
  nil
195
221
  end
196
222
 
197
- def instances
223
+ def instances(opts={})
198
224
  instances = []
199
- request( entry_points[:instances] ) do |response|
200
- doc = REXML::Document.new( response.body )
225
+ request( entry_points[:instances], :get, opts ) do |response|
226
+ doc = REXML::Document.new( response )
201
227
  doc.get_elements( 'instances/instance' ).each do |instance|
202
228
  uri = instance.attributes['href']
203
229
  instances << DCloud::Instance.new( self, uri, instance )
@@ -208,7 +234,7 @@ class DeltaCloud
208
234
 
209
235
  def instance(id)
210
236
  request( entry_points[:instances], :get, {:id=>id } ) do |response|
211
- doc = REXML::Document.new( response.body )
237
+ doc = REXML::Document.new( response )
212
238
  doc.get_elements( 'instance' ).each do |instance|
213
239
  uri = instance.attributes['href']
214
240
  return DCloud::Instance.new( self, uri, instance )
@@ -242,17 +268,17 @@ class DeltaCloud
242
268
 
243
269
  params[:image_id] = image_id
244
270
  request( entry_points[:instances], :post, {}, params ) do |response|
245
- doc = REXML::Document.new( response.body )
271
+ doc = REXML::Document.new( response )
246
272
  instance = doc.root
247
273
  uri = instance.attributes['href']
248
274
  return DCloud::Instance.new( self, uri, instance )
249
275
  end
250
276
  end
251
277
 
252
- def storage_volumes
278
+ def storage_volumes(opts={})
253
279
  storage_volumes = []
254
280
  request( entry_points[:storage_volumes] ) do |response|
255
- doc = REXML::Document.new( response.body )
281
+ doc = REXML::Document.new( response )
256
282
  doc.get_elements( 'storage-volumes/storage-volume' ).each do |instance|
257
283
  uri = instance.attributes['href']
258
284
  storage_volumes << DCloud::StorageVolume.new( self, uri, instance )
@@ -263,7 +289,7 @@ class DeltaCloud
263
289
 
264
290
  def storage_volume(id)
265
291
  request( entry_points[:storage_volumes], :get, {:id=>id } ) do |response|
266
- doc = REXML::Document.new( response.body )
292
+ doc = REXML::Document.new( response )
267
293
  doc.get_elements( 'storage-volume' ).each do |storage_volume|
268
294
  uri = storage_volume.attributes['href']
269
295
  return DCloud::StorageVolume.new( self, uri, storage_volume )
@@ -278,10 +304,10 @@ class DeltaCloud
278
304
  nil
279
305
  end
280
306
 
281
- def storage_snapshots()
307
+ def storage_snapshots(opts={})
282
308
  storage_snapshots = []
283
309
  request( entry_points[:storage_snapshots] ) do |response|
284
- doc = REXML::Document.new( response.body )
310
+ doc = REXML::Document.new( response )
285
311
  doc.get_elements( 'storage-snapshots/storage-snapshot' ).each do |instance|
286
312
  uri = instance.attributes['href']
287
313
  storage_snapshots << DCloud::StorageSnapshot.new( self, uri, instance )
@@ -292,7 +318,7 @@ class DeltaCloud
292
318
 
293
319
  def storage_snapshot(id)
294
320
  request( entry_points[:storage_snapshots], :get, {:id=>id } ) do |response|
295
- doc = REXML::Document.new( response.body )
321
+ doc = REXML::Document.new( response )
296
322
  doc.get_elements( 'storage-snapshot' ).each do |storage_snapshot|
297
323
  uri = storage_snapshot.attributes['href']
298
324
  return DCloud::StorageSnapshot.new( self, uri, storage_snapshot )
@@ -319,7 +345,7 @@ class DeltaCloud
319
345
 
320
346
  def discover_entry_points
321
347
  request(api_uri.to_s) do |response|
322
- doc = REXML::Document.new( response.body )
348
+ doc = REXML::Document.new( response )
323
349
  @driver_name = doc.root.attributes['driver']
324
350
  doc.get_elements( 'api/link' ).each do |link|
325
351
  rel = link.attributes['rel']
@@ -345,11 +371,19 @@ class DeltaCloud
345
371
  :authorization => "Basic "+Base64.encode64("#{@name}:#{@password}"),
346
372
  :accept => "application/xml"
347
373
  }
348
- logger << "Request [#{method.to_s.upcase}] #{request_path}]\n"
374
+
375
+ logger << "Request [#{method.to_s.upcase}] #{request_path}]\n" if @verbose
376
+
349
377
  if method.eql?(:get)
350
- RestClient.send(method, request_path, headers, &block)
378
+ RestClient.send(method, request_path, headers) do |response|
379
+ @last_request_xml = response
380
+ yield response.to_s
381
+ end
351
382
  else
352
- RestClient.send(method, request_path, form_data, headers, &block)
383
+ RestClient.send(method, request_path, form_data, headers) do |response|
384
+ @last_request_xml = response
385
+ yield response.to_s
386
+ end
353
387
  end
354
388
  end
355
389
 
@@ -81,8 +81,8 @@ describe "instances" do
81
81
  DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
82
82
  instance = client.create_instance( 'img1', :name=>'TestInstance' )
83
83
  instance.should_not be_nil
84
- instance.uri.should eql( API_URL + '/instances/inst3' )
85
- instance.id.should eql( 'inst3' )
84
+ instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
85
+ instance.id.should match( /inst[0-9]+/ )
86
86
  instance.name.should eql( 'TestInstance' )
87
87
  instance.image.id.should eql( 'img1' )
88
88
  instance.flavor.id.should eql( 'm1-large' )
@@ -94,8 +94,8 @@ describe "instances" do
94
94
  DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
95
95
  instance = client.create_instance( 'img1', :realm=>'eu' )
96
96
  instance.should_not be_nil
97
- instance.uri.should eql( API_URL + '/instances/inst3' )
98
- instance.id.should eql( 'inst3' )
97
+ instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
98
+ instance.id.should match( /inst[0-9]+/ )
99
99
  instance.image.id.should eql( 'img1' )
100
100
  instance.flavor.id.should eql( 'm1-large' )
101
101
  instance.realm.id.should eql( 'eu' )
@@ -106,8 +106,8 @@ describe "instances" do
106
106
  DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
107
107
  instance = client.create_instance( 'img1', :flavor=>'m1-xlarge' )
108
108
  instance.should_not be_nil
109
- instance.uri.should eql( API_URL + '/instances/inst3' )
110
- instance.id.should eql( 'inst3' )
109
+ instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
110
+ instance.id.should match( /inst[0-9]+/ )
111
111
  instance.image.id.should eql( 'img1' )
112
112
  instance.flavor.id.should eql( 'm1-xlarge' )
113
113
  instance.realm.id.should eql( 'us' )
@@ -118,8 +118,8 @@ describe "instances" do
118
118
  DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
119
119
  instance = client.create_instance( 'img1', :realm=>'eu', :flavor=>'m1-xlarge' )
120
120
  instance.should_not be_nil
121
- instance.uri.should eql( API_URL + '/instances/inst3' )
122
- instance.id.should eql( 'inst3' )
121
+ instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
122
+ instance.id.should match( /inst[0-9]+/ )
123
123
  instance.image.id.should eql( 'img1' )
124
124
  instance.flavor.id.should eql( 'm1-xlarge' )
125
125
  instance.realm.id.should eql( 'eu' )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deltacloud-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Red Hat, Inc.
@@ -9,8 +9,8 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-16 00:00:00 -05:00
13
- default_executable:
12
+ date: 2010-03-04 00:00:00 -05:00
13
+ default_executable: deltacloudc
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client
@@ -22,10 +22,10 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.3.1
24
24
  version:
25
- description: Deltacloud REST Client
25
+ description: Deltacloud REST Client for API
26
26
  email: deltacloud-users@lists.fedorahosted.org
27
- executables: []
28
-
27
+ executables:
28
+ - deltacloudc
29
29
  extensions: []
30
30
 
31
31
  extra_rdoc_files:
@@ -44,6 +44,7 @@ files:
44
44
  - lib/dcloud/transition.rb
45
45
  - lib/deltacloud.rb
46
46
  - init.rb
47
+ - bin/deltacloudc
47
48
  - COPYING
48
49
  has_rdoc: true
49
50
  homepage: http://www.deltacloud.org