cloud_stack_client 0.0.1
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/.gitignore +18 -0
- data/.hgignore +19 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE.txt +20 -0
- data/README.md +70 -0
- data/Rakefile +1 -0
- data/assets/cacert.pem +3825 -0
- data/bin/cloud-stack.rb +6 -0
- data/cloud_stack_client.gemspec +23 -0
- data/lib/cloud_stack_client.rb +8 -0
- data/lib/cloud_stack_client/api.rb +325 -0
- data/lib/cloud_stack_client/cli.rb +239 -0
- data/lib/cloud_stack_client/connector.rb +155 -0
- data/lib/cloud_stack_client/definitions.rb +29 -0
- data/lib/cloud_stack_client/helpers.rb +7 -0
- data/lib/cloud_stack_client/version.rb +4 -0
- metadata +66 -0
@@ -0,0 +1,155 @@
|
|
1
|
+
# The Connector assists in the interaction with the CloudStack API using a simple interface.
|
2
|
+
|
3
|
+
require "cloud_stack_client/api.rb"
|
4
|
+
|
5
|
+
# Simple class to interact with the CloudStack API
|
6
|
+
#
|
7
|
+
# @example The server URI is passed on instance creation
|
8
|
+
# connector = CloudStackClient::Connector.new('http://example.com/client/api')
|
9
|
+
# # or
|
10
|
+
# connector = CloudStackClient::Connector.new(:api_uri => 'https://example.com/client/api', :api_key => 'MyKeY', :secret_key => 'mYsEcReT')
|
11
|
+
# @example Login with Username, Passwort and Domain if API Key and Secret Key are not available
|
12
|
+
# connector.login('MyUser', 'MyPassword', 'MyDomain') # => true or false
|
13
|
+
# @example Execute an arbitrary command
|
14
|
+
# connector.listVirtualMachines # => Raw result record as REXML::Document
|
15
|
+
# connector.listVirtualMachines(:response => :json, :state => :running) # => Hash with result record
|
16
|
+
class CloudStackClient::Connector
|
17
|
+
# Connection credentials and settings. Defaults to {CloudStackClient::API_DEFAULTS}.
|
18
|
+
# @return [Hash]
|
19
|
+
attr_accessor :config
|
20
|
+
|
21
|
+
# Create API Connector.
|
22
|
+
#
|
23
|
+
# Configuration can passed as configuration Hash or as String containing the API URL.
|
24
|
+
#
|
25
|
+
# @param config [String, Hash] URI of the Service API or Hash with configuration parameters
|
26
|
+
# @see CloudStackClient::API_DEFAULTS
|
27
|
+
def initialize(config = {})
|
28
|
+
if config.is_a? String
|
29
|
+
if config.length > 0
|
30
|
+
config = {:api_uri => config}
|
31
|
+
if config[:api_uri].index("/api")
|
32
|
+
config[:web_uri] = config[:api_uri].sub("/api", "")
|
33
|
+
end
|
34
|
+
else
|
35
|
+
config = {}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
@config = CloudStackClient::API_DEFAULTS.dup
|
39
|
+
config.each {|key, value| @config[key.to_sym] = value}
|
40
|
+
@credentials = {}
|
41
|
+
@credentials[:api_key] = @config[:api_key] if @config[:api_key]
|
42
|
+
@credentials[:secret_key] = @config[:secret_key] if @config[:secret_key]
|
43
|
+
end
|
44
|
+
|
45
|
+
# Login with username and plain text password
|
46
|
+
#
|
47
|
+
# @param username [String]
|
48
|
+
# @param password [String] Plain text password
|
49
|
+
# @param domain [String] Login Domain. The / prefix can be omitted
|
50
|
+
# @return [Boolean] true if successful
|
51
|
+
def login(username, password, domain = "")
|
52
|
+
password ||= ""
|
53
|
+
login_hashed username, CloudStackClient::Helpers::hash_password(password), domain
|
54
|
+
end
|
55
|
+
|
56
|
+
# Login with username and hashed password
|
57
|
+
#
|
58
|
+
# @param username [String]
|
59
|
+
# @param password_hash [String] Password hash
|
60
|
+
# @param domain [String] Login Domain. The / prefix can be omitted
|
61
|
+
# @return [Boolean] true if successful
|
62
|
+
# @see CloudStackClient::Helpers::hash_password
|
63
|
+
def login_hashed(username, password_hash, domain = "")
|
64
|
+
result = CloudStackClient::API::get_credentials @config[:api_uri], username, password_hash, domain, @config[:http_method], @config[:ssl_check]
|
65
|
+
if result
|
66
|
+
@credentials = result
|
67
|
+
true
|
68
|
+
else
|
69
|
+
false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Login with API Key and Secret Key
|
74
|
+
#
|
75
|
+
# @param api_key [String]
|
76
|
+
# @param secret_key [String]
|
77
|
+
# @return [Boolean] true if successful
|
78
|
+
def login_with_keys(api_key, secret_key)
|
79
|
+
if CloudStackClient::API::verify_keys(@config[:api_uri], api_key, secret_key, @config[:http_method], @config[:ssl_check])
|
80
|
+
@credentials[:api_key] = api_key
|
81
|
+
@credentials[:secret_key] = secret_key
|
82
|
+
true
|
83
|
+
else
|
84
|
+
false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Check whether valid login credentials are present
|
89
|
+
#
|
90
|
+
# @return [Boolean]
|
91
|
+
def authenticated?
|
92
|
+
if @credentials.any? && query({:command => "listCapabilities"})
|
93
|
+
true
|
94
|
+
else
|
95
|
+
false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Send a command
|
100
|
+
#
|
101
|
+
# @param parameters [Hash, Array] Hash or Array of [Key, Value] pairs containing all query parameters
|
102
|
+
# @return [REXML::Document, Hash, String] The query result depending on the HTTP response content type
|
103
|
+
def query(parameters)
|
104
|
+
CloudStackClient::API::query(@config[:api_uri], parameters, @credentials, @config[:http_method], @config[:ssl_check])
|
105
|
+
end
|
106
|
+
|
107
|
+
# Send a command and merge all result pages
|
108
|
+
#
|
109
|
+
# If the result spans multiple pages, multiple calls are executed to retrieve all pages. These will be returned as one.
|
110
|
+
#
|
111
|
+
# @param parameters [Hash, Array] Hash or Array of [Key, Value] pairs containing all query parameters
|
112
|
+
# @return [REXML::Document, Hash, String] The query result depending on the HTTP response content type
|
113
|
+
def query_all_pages(parameters)
|
114
|
+
CloudStackClient::API::query_with_auto_paging(@config[:api_uri], parameters, @credentials, @config[:page_size], @config[:http_method], @config[:ssl_check])
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# Dynamic methods are passed as commands to CloudStack
|
120
|
+
#
|
121
|
+
# @example Use dynamic methods as commands
|
122
|
+
# cs_connector = CloudStackClient::Connector.new "https://example.com/client/api"
|
123
|
+
# cs_connector.login "Me", "MyPass", "MyDomain"
|
124
|
+
# response = cs_connector.listVirtualMachines(:response => :json, :state => :running)
|
125
|
+
# if response.has_key? "listvirtualmachinesresponse"
|
126
|
+
# vms = response["listvirtualmachinesresponse"]["virtualmachine"]
|
127
|
+
# cs_connector.stopVirtualMachine :id => vms.first["id"]
|
128
|
+
# end
|
129
|
+
#
|
130
|
+
# @param method_name [String] Name of the command
|
131
|
+
# @param parameters [Hash, Array] command parameters
|
132
|
+
# @param disable_auto_paging [Boolean] (optional) If true the command will be executed with manual paging
|
133
|
+
# @return [REXML::Document, Hash] Result of the query
|
134
|
+
def method_missing(*args)
|
135
|
+
name = args.shift
|
136
|
+
parameters = args.shift
|
137
|
+
auto_paging = !args.shift
|
138
|
+
if parameters.is_a?(Hash) && !parameters.has_key?(:command)
|
139
|
+
parameters[:command] = name
|
140
|
+
elsif parameters.is_a?(Array) && !parameters.find {|pos| pos.is_a?(Array) && pos[0] == :command}
|
141
|
+
parameters << [:command => name]
|
142
|
+
else
|
143
|
+
parameters = {:command => name}
|
144
|
+
end
|
145
|
+
if auto_paging && name.to_s.downcase.start_with?("list")
|
146
|
+
query_all_pages(parameters)
|
147
|
+
else
|
148
|
+
query(parameters)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def respond_to_missing?(name, private)
|
153
|
+
true
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module CloudStackClient
|
2
|
+
# Default values used by CloudStackClient
|
3
|
+
API_DEFAULTS = {
|
4
|
+
:web_uri => "",
|
5
|
+
:api_uri => "",
|
6
|
+
:ssl_check => true,
|
7
|
+
:http_method => :post,
|
8
|
+
:login_parameter => "loginUrl",
|
9
|
+
:page_size => 500,
|
10
|
+
:timestamp_offset => 3600
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
# Translation of the usage types as returned by getUsageRecords
|
14
|
+
USAGE_MAP = {
|
15
|
+
1 => :running_vm,
|
16
|
+
2 => :allocated_vm,
|
17
|
+
3 => :ip_address,
|
18
|
+
4 => :network_bytes_send,
|
19
|
+
5 => :network_bytes_received,
|
20
|
+
6 => :volume,
|
21
|
+
7 => :template,
|
22
|
+
8 => :iso,
|
23
|
+
9 => :snapshot,
|
24
|
+
11 => :load_balancer_policy,
|
25
|
+
12 => :port_forwarding_rule,
|
26
|
+
13 => :network_offering,
|
27
|
+
14 => :vpn_users
|
28
|
+
}.freeze
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloud_stack_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Roman Messer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-24 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Execute any command against a CloudStack Infrastructure. Also contains
|
15
|
+
a commandline utility with auto paging and support to read credentials from a config
|
16
|
+
file.
|
17
|
+
email:
|
18
|
+
- roman.messer@ict-cloud.com
|
19
|
+
executables:
|
20
|
+
- cloud-stack.rb
|
21
|
+
extensions: []
|
22
|
+
extra_rdoc_files: []
|
23
|
+
files:
|
24
|
+
- .gitignore
|
25
|
+
- .hgignore
|
26
|
+
- .yardopts
|
27
|
+
- Gemfile
|
28
|
+
- MIT-LICENSE.txt
|
29
|
+
- README.md
|
30
|
+
- Rakefile
|
31
|
+
- assets/cacert.pem
|
32
|
+
- bin/cloud-stack.rb
|
33
|
+
- cloud_stack_client.gemspec
|
34
|
+
- lib/cloud_stack_client.rb
|
35
|
+
- lib/cloud_stack_client/api.rb
|
36
|
+
- lib/cloud_stack_client/cli.rb
|
37
|
+
- lib/cloud_stack_client/connector.rb
|
38
|
+
- lib/cloud_stack_client/definitions.rb
|
39
|
+
- lib/cloud_stack_client/helpers.rb
|
40
|
+
- lib/cloud_stack_client/version.rb
|
41
|
+
homepage:
|
42
|
+
licenses: []
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.8.24
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: A simple library to work with the CloudStack API.
|
65
|
+
test_files: []
|
66
|
+
has_rdoc:
|