cft_smartcloud 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/README.md +26 -28
- data/VERSION +1 -1
- data/bin/cft_smartcloud +33 -8
- data/bin/smartcloud +33 -8
- data/cft_smartcloud.gemspec +3 -2
- data/lib/config/config.yml +2 -2
- data/lib/curl_client.rb +3 -1
- data/lib/dynamic_help_generator.rb +88 -0
- data/lib/smartcloud.rb +24 -59
- metadata +4 -3
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,7 @@ smartcloud
|
|
3
3
|
|
4
4
|
Provides support for interacting with IBM SmartCloud API and CLI tools
|
5
5
|
|
6
|
-
|
6
|
+
Installation
|
7
7
|
===
|
8
8
|
|
9
9
|
from rubygems.org:
|
@@ -15,7 +15,7 @@ locally:
|
|
15
15
|
rake build
|
16
16
|
gem install pkg/[name of generated gem]
|
17
17
|
|
18
|
-
|
18
|
+
Setup
|
19
19
|
===
|
20
20
|
|
21
21
|
Please set up SMARTCLOUD_USERNAME and SMARTCLOUD_PASSWORD in your .bash_profile
|
@@ -26,12 +26,8 @@ Please set up SMARTCLOUD_USERNAME and SMARTCLOUD_PASSWORD in your .bash_profile
|
|
26
26
|
You can now also supply the username and password on the command line using -u and -p
|
27
27
|
Use `smartcloud help` to get a list of all optoins.
|
28
28
|
|
29
|
-
screencast
|
30
|
-
===
|
31
|
-
|
32
|
-
http://www.youtube.com/cohesiveft#p/u/0/-WdSHP2iwDM (somewhat outdated)
|
33
29
|
|
34
|
-
|
30
|
+
Using the console
|
35
31
|
==
|
36
32
|
|
37
33
|
script/console
|
@@ -44,43 +40,36 @@ using the console
|
|
44
40
|
from the environment variables SMARTCLOUD_USERNAME and SMARTCLOUD_PASSWORD
|
45
41
|
automatically (it's created at the bottom of smartcloud.rb)
|
46
42
|
|
47
|
-
|
43
|
+
Using the commandline
|
48
44
|
==
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
to see a list of methods:
|
46
|
+
To see a list of methods:
|
53
47
|
|
54
48
|
smartcloud help
|
55
49
|
|
56
|
-
|
50
|
+
Examples:
|
57
51
|
|
58
52
|
smartcloud display_volumes
|
53
|
+
smartcloud display_volumes Location=82 State=MOUNTED
|
59
54
|
smartcloud display_instances
|
60
|
-
smartcloud display_instance 12345
|
61
55
|
smartcloud delete_instances 12345 12346 12347
|
62
|
-
smartcloud "
|
63
|
-
smartcloud
|
56
|
+
smartcloud display_images Name="Red Hat"
|
57
|
+
smartcloud display_instances Name="Red Hat" Location=82
|
64
58
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
will return pretty-formatted hashes, or singular values.
|
69
|
-
|
70
|
-
smartcloud display_volumes
|
59
|
+
The 'display_*' methods are intended to generate pretty human readable
|
60
|
+
displays, while the describe methods will return pretty-formatted hashes,
|
61
|
+
or singular values.
|
71
62
|
|
72
|
-
|
73
|
-
|
63
|
+
To save time when dealing with large responses, such as the describe_images
|
64
|
+
call, you can save a response in its native XML format:
|
74
65
|
|
75
|
-
|
66
|
+
smartcloud display_images -S /tmp/images.xml
|
76
67
|
|
77
|
-
|
68
|
+
You can then replay the response, using filters on it
|
78
69
|
|
79
|
-
|
70
|
+
smartcloud display_images Name='Red Hat' -R /tmp/images.xml
|
80
71
|
|
81
|
-
> smartcloud help
|
82
72
|
|
83
|
-
These won't tell you the arguments, you have to look at smartcloud.rb for the args.
|
84
73
|
|
85
74
|
RestClient vs CurlHttpClient
|
86
75
|
===
|
@@ -100,6 +89,15 @@ This project uses the jeweler gem for packaging. See the tasks:
|
|
100
89
|
rake version:bump:...
|
101
90
|
rake build
|
102
91
|
|
92
|
+
To publish to RubyForge
|
93
|
+
|
94
|
+
rake gemcutter:release
|
95
|
+
|
96
|
+
Screencast
|
97
|
+
===
|
98
|
+
|
99
|
+
http://www.youtube.com/cohesiveft#p/u/0/-WdSHP2iwDM (somewhat outdated)
|
100
|
+
|
103
101
|
Copyright
|
104
102
|
==
|
105
103
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/bin/cft_smartcloud
CHANGED
@@ -18,7 +18,7 @@ opts = Slop.new do
|
|
18
18
|
on :U, :api_url=, "URL of api endpoint"
|
19
19
|
on :d, :debug, "Enable debug logging"
|
20
20
|
on :R, :simulated_response_file=, "Pass in a file containing the response (do not hit cloud)"
|
21
|
-
on :S, :save_response
|
21
|
+
on :S, :save_response=, "Save the response (supply filename) as xml, for later use with -R response file"
|
22
22
|
end
|
23
23
|
|
24
24
|
# These are the actual commands appearing after the script name,
|
@@ -31,11 +31,8 @@ end
|
|
31
31
|
|
32
32
|
if commands.size == 1
|
33
33
|
if commands[0] == 'help'
|
34
|
-
puts "#{opts.help}\n\
|
34
|
+
puts "#{opts.help}\n\n"
|
35
35
|
end
|
36
|
-
@cmd=commands[0]
|
37
|
-
elsif commands.size == 2
|
38
|
-
@cmd="#{commands[0]}('#{commands[1]}')"
|
39
36
|
elsif commands.size == 0
|
40
37
|
puts %{
|
41
38
|
#{opts.help}
|
@@ -50,17 +47,45 @@ elsif commands.size == 0
|
|
50
47
|
smartcloud "delete_instance(12345)"
|
51
48
|
smartcloud delete_instance 12345
|
52
49
|
smartcloud delete_instances 12345 12346 12347
|
53
|
-
smartcloud "delete_instances(12345,12346,12347)"
|
54
50
|
smartcloud display_instances
|
51
|
+
smartcloud display_images name="Red Hat"
|
55
52
|
}
|
56
53
|
exit(0)
|
54
|
+
end
|
55
|
+
|
56
|
+
# parse out foo=bar values and turn them into a hash
|
57
|
+
params=[]
|
58
|
+
param_hash={}
|
59
|
+
commands[1..-1].each do |item|
|
60
|
+
if item =~ /=/
|
61
|
+
key,val = item.split('=')
|
62
|
+
param_hash[key]=val
|
63
|
+
else
|
64
|
+
params << item
|
65
|
+
end
|
66
|
+
end
|
67
|
+
params = params.map {|param| "'#{param}'" }.join(',')
|
68
|
+
|
69
|
+
method_invocation = if params.empty? && param_hash.empty?
|
70
|
+
commands[0]
|
71
|
+
elsif !params.empty? && param_hash.empty?
|
72
|
+
"#{commands[0]}(#{params})"
|
73
|
+
elsif params.empty? && !param_hash.empty?
|
74
|
+
"#{commands[0]}(#{param_hash.inspect})"
|
57
75
|
else
|
58
|
-
|
76
|
+
"#{commands[0]}(#{params}, #{param_hash.inspect})"
|
59
77
|
end
|
60
78
|
|
79
|
+
puts "Invoking: #{method_invocation}"
|
61
80
|
# allows us to send arbitrary commands like
|
62
81
|
# smartcloud username password describe_instance("122345")
|
63
|
-
|
82
|
+
begin
|
83
|
+
result = eval("@sc.#{method_invocation}")
|
84
|
+
|
85
|
+
rescue ArgumentError => e
|
86
|
+
puts e.message
|
87
|
+
puts "\nPlease use the following command for more information:\nsmartcloud help #{commands[0]}\n\n"
|
88
|
+
end
|
64
89
|
|
65
90
|
if result == true || result.nil?
|
66
91
|
# do nothing, the command already logged
|
data/bin/smartcloud
CHANGED
@@ -18,7 +18,7 @@ opts = Slop.new do
|
|
18
18
|
on :U, :api_url=, "URL of api endpoint"
|
19
19
|
on :d, :debug, "Enable debug logging"
|
20
20
|
on :R, :simulated_response_file=, "Pass in a file containing the response (do not hit cloud)"
|
21
|
-
on :S, :save_response
|
21
|
+
on :S, :save_response=, "Save the response (supply filename) as xml, for later use with -R response file"
|
22
22
|
end
|
23
23
|
|
24
24
|
# These are the actual commands appearing after the script name,
|
@@ -31,11 +31,8 @@ end
|
|
31
31
|
|
32
32
|
if commands.size == 1
|
33
33
|
if commands[0] == 'help'
|
34
|
-
puts "#{opts.help}\n\
|
34
|
+
puts "#{opts.help}\n\n"
|
35
35
|
end
|
36
|
-
@cmd=commands[0]
|
37
|
-
elsif commands.size == 2
|
38
|
-
@cmd="#{commands[0]}('#{commands[1]}')"
|
39
36
|
elsif commands.size == 0
|
40
37
|
puts %{
|
41
38
|
#{opts.help}
|
@@ -50,17 +47,45 @@ elsif commands.size == 0
|
|
50
47
|
smartcloud "delete_instance(12345)"
|
51
48
|
smartcloud delete_instance 12345
|
52
49
|
smartcloud delete_instances 12345 12346 12347
|
53
|
-
smartcloud "delete_instances(12345,12346,12347)"
|
54
50
|
smartcloud display_instances
|
51
|
+
smartcloud display_images name="Red Hat"
|
55
52
|
}
|
56
53
|
exit(0)
|
54
|
+
end
|
55
|
+
|
56
|
+
# parse out foo=bar values and turn them into a hash
|
57
|
+
params=[]
|
58
|
+
param_hash={}
|
59
|
+
commands[1..-1].each do |item|
|
60
|
+
if item =~ /=/
|
61
|
+
key,val = item.split('=')
|
62
|
+
param_hash[key]=val
|
63
|
+
else
|
64
|
+
params << item
|
65
|
+
end
|
66
|
+
end
|
67
|
+
params = params.map {|param| "'#{param}'" }.join(',')
|
68
|
+
|
69
|
+
method_invocation = if params.empty? && param_hash.empty?
|
70
|
+
commands[0]
|
71
|
+
elsif !params.empty? && param_hash.empty?
|
72
|
+
"#{commands[0]}(#{params})"
|
73
|
+
elsif params.empty? && !param_hash.empty?
|
74
|
+
"#{commands[0]}(#{param_hash.inspect})"
|
57
75
|
else
|
58
|
-
|
76
|
+
"#{commands[0]}(#{params}, #{param_hash.inspect})"
|
59
77
|
end
|
60
78
|
|
79
|
+
puts "Invoking: #{method_invocation}"
|
61
80
|
# allows us to send arbitrary commands like
|
62
81
|
# smartcloud username password describe_instance("122345")
|
63
|
-
|
82
|
+
begin
|
83
|
+
result = eval("@sc.#{method_invocation}")
|
84
|
+
|
85
|
+
rescue ArgumentError => e
|
86
|
+
puts e.message
|
87
|
+
puts "\nPlease use the following command for more information:\nsmartcloud help #{commands[0]}\n\n"
|
88
|
+
end
|
64
89
|
|
65
90
|
if result == true || result.nil?
|
66
91
|
# do nothing, the command already logged
|
data/cft_smartcloud.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{cft_smartcloud}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["yan", "cohesive"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2012-03-12}
|
13
13
|
s.description = %q{CohesiveFT Ruby Interface for IBM SmartCloud and 'smartcloud' command line helper.}
|
14
14
|
s.email = %q{yan.pritzker@cohesiveft.com}
|
15
15
|
s.executables = ["cft_smartcloud", "smartcloud"]
|
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
"cft_smartcloud.gemspec",
|
30
30
|
"lib/config/config.yml",
|
31
31
|
"lib/curl_client.rb",
|
32
|
+
"lib/dynamic_help_generator.rb",
|
32
33
|
"lib/hash_fix.rb",
|
33
34
|
"lib/mime-types-1.16/History.txt",
|
34
35
|
"lib/mime-types-1.16/Install.txt",
|
data/lib/config/config.yml
CHANGED
data/lib/curl_client.rb
CHANGED
@@ -9,7 +9,9 @@ class CurlHttpClient
|
|
9
9
|
|
10
10
|
def self.logger; @logger ||= Logger.new(STDOUT); end
|
11
11
|
|
12
|
-
|
12
|
+
# Even though we don't need the options, the REST client does.
|
13
|
+
# So we have this for consistency.
|
14
|
+
def self.get(url, options={})
|
13
15
|
handle_output(curl(url))
|
14
16
|
end
|
15
17
|
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module DynamicHelpGenerator
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def help_for(method, args, extra_help="")
|
9
|
+
@method_help||={}
|
10
|
+
@method_help_supplemental||={}
|
11
|
+
@method_help[method.to_s] = args
|
12
|
+
@method_help_supplemental[method.to_s] = extra_help
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :method_help
|
16
|
+
attr_reader :method_help_supplemental
|
17
|
+
end
|
18
|
+
|
19
|
+
def help(method=nil)
|
20
|
+
|
21
|
+
if method
|
22
|
+
args = (self.class.method_help[method.to_s])
|
23
|
+
if !(self.respond_to?(method))
|
24
|
+
return "Sorry, I don't know method: #{method}"
|
25
|
+
end
|
26
|
+
|
27
|
+
args = args && args.map do |arg|
|
28
|
+
if arg.is_a?(Hash)
|
29
|
+
# If an argument is required, just list it
|
30
|
+
if arg.values.first==:req
|
31
|
+
arg.keys.first.to_s
|
32
|
+
# If it's optional, list it in brackets
|
33
|
+
elsif arg.values.first==:opt
|
34
|
+
"[#{arg.keys.first.to_s}]"
|
35
|
+
# If there is an array of options, list them
|
36
|
+
else
|
37
|
+
"#{arg.keys.first.to_s}=>#{arg.values.first.inspect}"
|
38
|
+
end
|
39
|
+
else
|
40
|
+
arg
|
41
|
+
end
|
42
|
+
end.join(", ")
|
43
|
+
|
44
|
+
extra_help = self.class.method_help_supplemental[method.to_s] || ""
|
45
|
+
|
46
|
+
puts %{ * #{method.to_s}#{'(' + args + ')' if args}#{extra_help}}
|
47
|
+
else
|
48
|
+
# These verbs help us figure out what 'group' the method belongs to
|
49
|
+
verbs = %w(describe display create get allocate clone export attach detach delete generate update remove restart rename)
|
50
|
+
verb_noun = /(#{verbs.join('|')})_(.*)(s|es)?/ # we're going to remove the verb and trailing 's'
|
51
|
+
|
52
|
+
methods = public_methods - Object.public_methods - ['post','get','put','delete','logger','logger=','help']
|
53
|
+
|
54
|
+
# Group methods by the noun they operate on
|
55
|
+
methods_grouped_by_noun = methods.inject({}) do |h, method|
|
56
|
+
method_name, verb, noun = *(method.match(verb_noun))
|
57
|
+
if method_name.nil?
|
58
|
+
# match failed
|
59
|
+
method_name = method
|
60
|
+
noun = "misc"
|
61
|
+
end
|
62
|
+
synonyms = {
|
63
|
+
:keypair => :key,
|
64
|
+
:address_offering => :address,
|
65
|
+
:location_by_name => :location,
|
66
|
+
:storage_offering => :storage,
|
67
|
+
:volume => :storage,
|
68
|
+
:volume_offering => :storage,
|
69
|
+
}
|
70
|
+
noun.gsub!(/s$/,'') unless noun =~ /address/
|
71
|
+
if synonyms.keys.include?(noun.to_sym)
|
72
|
+
noun = synonyms[noun.to_sym].to_s
|
73
|
+
end
|
74
|
+
h[noun] ||= []
|
75
|
+
h[noun] << method_name
|
76
|
+
h
|
77
|
+
end
|
78
|
+
methods_grouped_by_noun.keys.sort.each do |noun|
|
79
|
+
methods = methods_grouped_by_noun[noun]
|
80
|
+
next unless methods
|
81
|
+
puts "== #{noun.capitalize} ==\n\n"
|
82
|
+
methods.sort.each {|m| help(m)}
|
83
|
+
puts
|
84
|
+
end
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/smartcloud.rb
CHANGED
@@ -24,13 +24,14 @@ require 'xmlsimple'
|
|
24
24
|
require 'smartcloud_logger'
|
25
25
|
require 'curl_client'
|
26
26
|
require 'terminal-table'
|
27
|
+
require "dynamic_help_generator"
|
27
28
|
|
28
29
|
IBM_TOOLS_HOME=File.join(File.dirname(__FILE__), "cli_tools") unless defined?(IBM_TOOLS_HOME)
|
29
30
|
|
30
31
|
# Encapsulates communications with IBM SmartCloud via REST
|
31
32
|
|
32
33
|
class IBMSmartCloud
|
33
|
-
|
34
|
+
include DynamicHelpGenerator
|
34
35
|
attr_accessor :logger
|
35
36
|
|
36
37
|
def initialize(opts={})
|
@@ -59,57 +60,22 @@ class IBMSmartCloud
|
|
59
60
|
|
60
61
|
class << self
|
61
62
|
@config = YAML.load_file(File.join(File.dirname(__FILE__), "config/config.yml"))
|
62
|
-
attr_reader :method_help
|
63
|
-
attr_reader :method_help_supplemental
|
64
63
|
attr_reader :config
|
65
64
|
end
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
if method
|
76
|
-
args = (self.class.method_help[method.to_s])
|
77
|
-
if !(self.respond_to?(method))
|
78
|
-
return "Sorry, I don't know method: #{method}"
|
79
|
-
end
|
80
|
-
|
81
|
-
args = args && args.map do |arg|
|
82
|
-
if arg.is_a?(Hash)
|
83
|
-
# If an argument is required, just list it
|
84
|
-
if arg.values.first==:req
|
85
|
-
arg.keys.first.to_s
|
86
|
-
# If it's optional, list it in brackets
|
87
|
-
elsif arg.values.first==:opt
|
88
|
-
"[#{arg.keys.first.to_s}]"
|
89
|
-
# If there is an array of options, list them
|
90
|
-
else
|
91
|
-
"#{arg.keys.first.to_s}=>#{arg.values.first.inspect}"
|
92
|
-
end
|
93
|
-
else
|
94
|
-
arg
|
95
|
-
end
|
96
|
-
end.join(", ")
|
97
|
-
|
98
|
-
extra_help = self.class.method_help_supplemental[method.to_s] || ""
|
99
|
-
|
100
|
-
puts %{ * #{method.to_s}#{'(' + args + ')' if args}#{extra_help + "\n" if extra_help}}
|
66
|
+
# Get a list of data centers
|
67
|
+
help_for :describe_locations, [{:name => :opt}], %{
|
68
|
+
If name is given, will find the location by name
|
69
|
+
}
|
70
|
+
def describe_locations(name=nil)
|
71
|
+
locations = get("/locations").Location
|
72
|
+
if name
|
73
|
+
locations.detect {|loc| loc.Name =~ /#{name}/}
|
101
74
|
else
|
102
|
-
|
103
|
-
methods.sort.each {|m| help(m)}
|
104
|
-
nil
|
75
|
+
locations
|
105
76
|
end
|
106
77
|
end
|
107
78
|
|
108
|
-
# Get a list of data centers
|
109
|
-
def describe_locations
|
110
|
-
get("/locations").Location
|
111
|
-
end
|
112
|
-
|
113
79
|
def describe_location(location_id)
|
114
80
|
get("/locations/#{location_id}").Location
|
115
81
|
end
|
@@ -214,21 +180,26 @@ class IBMSmartCloud
|
|
214
180
|
post("/offerings/image/#{image_id}", :name => name, :description => description).ImageID
|
215
181
|
end
|
216
182
|
|
217
|
-
# Export an image to a volume
|
183
|
+
# Export an image to a volume - create the volume first
|
218
184
|
help_for :export_image, [{:name=>:req}, {:size => ['Small','Medium','Large']}, {:image_id => :req}, {:location => :req}]
|
219
185
|
def export_image(name, size, image_id, location)
|
220
186
|
# Note we figure out the correct size based on the name and location
|
221
187
|
storage_offering=describe_storage_offerings(location, size)
|
222
188
|
|
223
|
-
response = post("/storage", :name => name, :size => storage_offering.Capacity, :format => 'EXT3', :offeringID => storage_offering.ID, :location => location
|
189
|
+
response = post("/storage", :name => name, :size => storage_offering.Capacity, :format => 'EXT3', :offeringID => storage_offering.ID, :location => location)
|
190
|
+
volumeID = response.Volume.ID
|
191
|
+
|
192
|
+
poll_for_volume_state(volumeID, :unmounted)
|
193
|
+
|
194
|
+
response = put("/storage/#{volumeID}", :imageId => image_id)
|
224
195
|
response.Volume.ID
|
225
196
|
end
|
226
197
|
|
227
198
|
help_for :import_image, [{:name=>:req, :volume_id => :req}]
|
228
199
|
def import_image(name, volume_id)
|
229
200
|
# TODO: this is a complete guess as we have no info from IBM as to the URL for this api, only the parameters
|
230
|
-
response = post("/offerings/image", :
|
231
|
-
response.
|
201
|
+
response = post("/offerings/image", :volumeId => volume_id, :name => name)
|
202
|
+
response.Image.ID
|
232
203
|
end
|
233
204
|
|
234
205
|
# Launches a clone request and returns ID of new volume
|
@@ -289,8 +260,6 @@ class IBMSmartCloud
|
|
289
260
|
delete("/keys/#{name}")
|
290
261
|
true
|
291
262
|
end
|
292
|
-
alias remove_key remove_keypair
|
293
|
-
alias delete_key remove_keypair
|
294
263
|
|
295
264
|
help_for :describe_key, [:name]
|
296
265
|
def describe_key(name)
|
@@ -341,10 +310,6 @@ class IBMSmartCloud
|
|
341
310
|
arrayize(get("/keys").PublicKey)
|
342
311
|
end
|
343
312
|
|
344
|
-
def describe_unused_keys
|
345
|
-
describe_keys.select {|key| key.Instances == {}}
|
346
|
-
end
|
347
|
-
|
348
313
|
def display_keys
|
349
314
|
keys = describe_keys
|
350
315
|
|
@@ -638,14 +603,13 @@ class IBMSmartCloud
|
|
638
603
|
output = if @simulated_response
|
639
604
|
@simulated_response
|
640
605
|
else
|
641
|
-
@http_client.get File.join(@api_url, path)
|
606
|
+
@http_client.get File.join(@api_url, path), :accept => :response, :headers => "User-Agent: cloudapi"
|
642
607
|
end
|
643
608
|
|
644
609
|
# Save Response for posterity
|
645
610
|
if @save_response && !output.empty?
|
646
|
-
|
647
|
-
|
648
|
-
File.open(response_file,'w') {|f| f.write(output)}
|
611
|
+
logger.info "Saving response to: #{@save_response}"
|
612
|
+
File.open(@save_response,'w') {|f| f.write(output)}
|
649
613
|
end
|
650
614
|
|
651
615
|
if output && !output.empty?
|
@@ -723,6 +687,7 @@ class IBMSmartCloud
|
|
723
687
|
order_by = filters.delete(:order)
|
724
688
|
|
725
689
|
filters.each do |filter, value|
|
690
|
+
filter = filter.to_sym
|
726
691
|
value = value.to_s.upcase if (filter==:status || filter==:state)
|
727
692
|
if filter == :name || filter == :Name
|
728
693
|
instances = instances.select {|inst| inst.send(filter.to_s.capitalize) =~ /#{value}/}
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- yan
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-03-12 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- cft_smartcloud.gemspec
|
42
42
|
- lib/config/config.yml
|
43
43
|
- lib/curl_client.rb
|
44
|
+
- lib/dynamic_help_generator.rb
|
44
45
|
- lib/hash_fix.rb
|
45
46
|
- lib/mime-types-1.16/History.txt
|
46
47
|
- lib/mime-types-1.16/Install.txt
|