cloudstack_client 1.0.0.rc1 → 1.0.0.rc2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dbdf827427d6082f13e387fb4ac08e1d3ca53a26
4
- data.tar.gz: 62ef06679e1f7cd5ba5e21eb031d7a08902c4b54
3
+ metadata.gz: a01d5f236a8d9221f700202643596f426c820d0d
4
+ data.tar.gz: 37cca417cd8bceb6b49a37089fae0564081a6c25
5
5
  SHA512:
6
- metadata.gz: 1481dfdd002e4d8cca0a286919a38222d29e76e7280050e32169b80daa765ab9a780012ed714f23c5470201d28b23bd15f6240b6b58daa573ab8ab302e21b579
7
- data.tar.gz: 76e25246ad5b51bf3666ff36bac2d680c018a2d0e98961ad6ef1171705a44b34b980a691029ee1d6108083180d1c3cbf17e4c73e731ba6a8ab9f8533389433ae
6
+ metadata.gz: df2b4c3bb08b861705dadbfdcfadd3b1197c45ecbb8d50da1be5fc2427491951117a5df7e10287d0b2305187e7558ba5897ece4d4a07eb2860a0bca5c3713fe5
7
+ data.tar.gz: 5f0daf52f5d581096662935d9c7fc087a08cc04b36c7bff3615e2cba80be699e0a95912306afd0e8a011f7466025b6ebc8fed6ad5b8f7fa32a2cd78df488c492
data/README.md CHANGED
@@ -28,6 +28,38 @@ cs.list_virtual_machines(state: "running").each do |server|
28
28
  end
29
29
  ```
30
30
 
31
+ ## Features
32
+
33
+ - Dynamically builds API methods based on the lisApis function of CloudStack
34
+ - Command names are converted to match Ruby naming conventions (i.e. ListVirtualMachines becomes list_virtual_machines)
35
+ - Accepts Ruby style args passed to commands (i.e. list_all: true becomes listall=true)
36
+ - makes sure all required arguments are passed
37
+ - Removes unsupported arguments and arguments with nil values from commands
38
+
39
+ ## Development
40
+
41
+ ### Generate new API configs
42
+
43
+ New API configs can be genearted using the list_apis command.
44
+
45
+ *Example:*
46
+
47
+ ```bash
48
+ # running against an CloudStack 4.5 API endpoint:
49
+ $ bundle exec bin/cloudstack_client list_apis > config/4.5.msgpack
50
+ ```
51
+
52
+ ### Interactive Console
53
+
54
+ cloudstack_client comes with an interactive shell to test the client.
55
+
56
+ *Example:*
57
+
58
+ ```bash
59
+ $ bundle exec bin/cloudstack_client console -e prod
60
+ prod >> list_virtual_machines
61
+ ```
62
+
31
63
  ## References
32
64
  - [Apache CloudStack API documentation](http://cloudstack.apache.org/docs/api/)
33
65
 
@@ -19,6 +19,8 @@ Gem::Specification.new do |gem|
19
19
  gem.require_paths = ["lib"]
20
20
  gem.rdoc_options = %w[--line-numbers --inline-source]
21
21
 
22
+ gem.add_dependency('msgpack')
23
+
22
24
  gem.add_development_dependency('rdoc')
23
25
  gem.add_development_dependency('rake', '~> 10.0', '>= 10.0.4')
24
26
  gem.add_development_dependency('thor')
Binary file
@@ -1,3 +1,4 @@
1
+ require "msgpack"
1
2
  require "json"
2
3
  require "ostruct"
3
4
 
@@ -9,16 +10,16 @@ module CloudstackClient
9
10
  def initialize(options = {})
10
11
  if options[:api_file]
11
12
  @api_file = options[:api_file]
12
- @api_version = File.basename(@api_file, ".json")
13
+ @api_version = File.basename(@api_file, ".msgpack")
13
14
  else
14
15
  @api_version = options[:api_version] || DEFAULT_API_VERSION
15
- @api_file = File.expand_path("../../../config/#{@api_version}.json", __FILE__)
16
+ @api_file = File.expand_path("../../../config/#{@api_version}.msgpack", __FILE__)
16
17
  end
17
18
  end
18
19
 
19
20
  def commands
20
21
  begin
21
- api = JSON.parse(IO.read @api_file)
22
+ api = MessagePack.unpack(IO.read @api_file)
22
23
  rescue => e
23
24
  raise "Error: Unable to read file '#{@api_file}' : #{e.message}"
24
25
  end
@@ -1,7 +1,20 @@
1
1
  require 'cloudstack_client/client'
2
- require 'thor'
3
2
  require 'yaml'
4
- require 'ripl'
3
+
4
+ begin
5
+ require 'thor'
6
+ require 'ripl'
7
+ rescue LoadError => e
8
+ missing_gem = if e.message =~ /thor/
9
+ "thor"
10
+ elsif e.message =~ /ripl/
11
+ "ripl"
12
+ else
13
+ raise
14
+ end
15
+ puts "Please install the #{missing_gem} gem first ('gem install #{missing_gem}')"
16
+ exit 1
17
+ end
5
18
 
6
19
  module CloudstackClient
7
20
  class Cli < Thor
@@ -27,8 +40,8 @@ module CloudstackClient
27
40
  map %w(-v --version) => :version
28
41
 
29
42
  desc "list_apis", "list api commands using the Cloudstack API Discovery service"
30
- option :format, default: 'json',
31
- enum: %w(json yaml), desc: "output format"
43
+ option :format, default: 'msgpack',
44
+ enum: %w(msgpack json yaml), desc: "output format"
32
45
  option :pretty_print, default: true, type: :boolean,
33
46
  desc: "pretty print json output"
34
47
  option :remove_response, default: true, type: :boolean,
@@ -44,12 +57,15 @@ module CloudstackClient
44
57
  command["params"].each {|param| param.delete("description")}
45
58
  end
46
59
  end
47
- output = if options[:format] == "json"
60
+
61
+ puts case options[:format]
62
+ when "json"
48
63
  options[:pretty_print] ? JSON.pretty_generate(apis) : data.to_json
49
- else
64
+ when "yaml"
50
65
  apis.to_yaml
66
+ else
67
+ apis.to_msgpack
51
68
  end
52
- puts output
53
69
  end
54
70
 
55
71
  desc "console", "Cloudstack Client interactive shell"
@@ -16,7 +16,7 @@ module CloudstackClient
16
16
 
17
17
  def define_api_methods
18
18
  Api.new(api_file: @api_file, api_version: @api_version).commands.each do |command|
19
- method_name = underscore(command.name).to_sym
19
+ method_name = camel_case_to_underscore(command.name).to_sym
20
20
 
21
21
  define_singleton_method(method_name) do |args = {}, options = {}|
22
22
  params = {"command" => command.name}
@@ -28,23 +28,42 @@ module CloudstackClient
28
28
  end
29
29
  end
30
30
 
31
+ unless all_required_args?(command, params)
32
+ raise MissingArgumentsError, missing_args_msg(command)
33
+ end
34
+
31
35
  sync = command.isasync == false || options[:sync]
32
36
  sync ? send_request(params) : send_async_request(params)
33
37
  end
34
38
  end
35
39
  end
36
40
 
41
+ def command_supports_key?(command, key)
42
+ command.params.detect { |p| p["name"] == key }
43
+ end
44
+
45
+ def required_args(command)
46
+ command.params.map do |param|
47
+ param["name"] if param["required"] == true
48
+ end.compact
49
+ end
50
+
51
+ def all_required_args?(command, args)
52
+ required_args(command).all? {|k| args.key? k}
53
+ end
54
+
37
55
  private
38
56
 
39
57
  def normalize_key(key)
40
58
  key.to_s.gsub("_", "")
41
59
  end
42
60
 
43
- def command_supports_key?(command, key)
44
- command.params.detect { |p| p["name"] == key }
61
+ def missing_args_msg(command)
62
+ requ = required_args(command)
63
+ "#{command.name} requires the following argument#{ 's' if requ.size > 1}: #{requ.join(', ')}"
45
64
  end
46
65
 
47
- def underscore(camel_case)
66
+ def camel_case_to_underscore(camel_case)
48
67
  camel_case.gsub(/::/, '/').
49
68
  gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
50
69
  gsub(/([a-z\d])([A-Z])/,'\1_\2').
@@ -6,4 +6,5 @@ module CloudstackClient
6
6
  class ApiError < Error; end
7
7
  class JobError < Error; end
8
8
  class TimeoutError < Error; end
9
+ class MissingArgumentsError < Error; end
9
10
  end
@@ -1,3 +1,3 @@
1
1
  module CloudstackClient
2
- VERSION = "1.0.0.rc1"
2
+ VERSION = "1.0.0.rc2"
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudstack_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 1.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nik Wolfgramm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-24 00:00:00.000000000 Z
11
+ date: 2015-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: msgpack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rdoc
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -86,7 +100,7 @@ files:
86
100
  - Rakefile
87
101
  - bin/cloudstack_client
88
102
  - cloudstack_client.gemspec
89
- - config/4.2.json
103
+ - config/4.2.msgpack
90
104
  - lib/cloudstack_client.rb
91
105
  - lib/cloudstack_client/api.rb
92
106
  - lib/cloudstack_client/cli.rb