deltacloud-client 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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