cloudshare-sdk 0.1.0.dev
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/lib/cloudshare-sdk/cs_high_api.rb +220 -0
- data/lib/cloudshare-sdk/cs_low_api.rb +116 -0
- data/lib/cloudshare-sdk.rb +6 -0
- metadata +50 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
require 'cloudshare-sdk/cs_low_api'
|
2
|
+
|
3
|
+
module CloudshareSDK
|
4
|
+
class CSHighApi
|
5
|
+
def initialize(id, key, version=CSLowApi::DEFAULT_VERSION, host=CSLowApi::DEFAULT_HOST)
|
6
|
+
@lowapi = CSLowApi.new(id, key, version, host)
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(category, command, params={})
|
10
|
+
@lowapi.call(category, command, params).json['data']
|
11
|
+
end
|
12
|
+
|
13
|
+
# Env info
|
14
|
+
|
15
|
+
def list_environments
|
16
|
+
call('env', 'ListEnvironments')
|
17
|
+
end
|
18
|
+
|
19
|
+
def list_environments_with_state
|
20
|
+
call('env', 'ListEnvironmentsWithStateExt')
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_environment_status(envId)
|
24
|
+
call('env', 'GetEnvironmentStateExt', {'EnvId' => envId})
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_environment_status_list
|
28
|
+
envs = list_environments
|
29
|
+
envs.map{|env| get_environment_status(env['envId'])}
|
30
|
+
end
|
31
|
+
|
32
|
+
# General env actions
|
33
|
+
|
34
|
+
def resume_environment(envId)
|
35
|
+
call('env', 'ResumeEnvironment', {'EnvId' => envId})
|
36
|
+
end
|
37
|
+
|
38
|
+
def revert_environment(envId)
|
39
|
+
call('env', 'RevertEnvironment', {'EnvId' => envId})
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_environment(envId)
|
43
|
+
call('env', 'DeleteEnvironment', {'EnvId' => envId})
|
44
|
+
end
|
45
|
+
|
46
|
+
def extend_environment(envId)
|
47
|
+
call('env', 'ExtendEnvironment', {'EnvId' => envId})
|
48
|
+
end
|
49
|
+
|
50
|
+
def postpone_inactivity(envId)
|
51
|
+
call('env', 'PostponeInactivityAction', {'EnvId' => envId})
|
52
|
+
end
|
53
|
+
|
54
|
+
def suspend_environment(envId)
|
55
|
+
call('env', 'SuspendEnvironment', {'EnvId' => envId})
|
56
|
+
end
|
57
|
+
|
58
|
+
def revert_environment_to_snapshot(envId, snapshotId)
|
59
|
+
call('env', 'RevertEnvironmentToSnapshot', {'EnvId' => envId, 'SnapshotId' => snapshotId})
|
60
|
+
end
|
61
|
+
|
62
|
+
# Create env actions
|
63
|
+
|
64
|
+
def list_templates
|
65
|
+
call('env', 'ListTemplates')
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_vm_from_template(envId, templateId, vm_name, vm_description)
|
69
|
+
call('env', 'AddVmFromTemplate',
|
70
|
+
{'EnvId' => envId, 'TemplateVmId' => templateId, 'VmName' => vm_name, 'VmDescription' => vm_description})
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_ent_app_env_options(project_filter='', blueprint_filter='', env_policy_duration_filter='')
|
74
|
+
call('env', 'CreateEntAppEnvOptions',
|
75
|
+
{'ProjectFilter' => project_filter, 'BlueprintFilter' => blueprint_filter,
|
76
|
+
'EnvironmentPolicyDurationFilter' => env_policy_duration_filter})
|
77
|
+
end
|
78
|
+
|
79
|
+
def create_ent_app_env(envPolicyId, snapshotId, env_new_name=nil, project_filter='',
|
80
|
+
blueprint_filter='', env_policy_duration_filter='')
|
81
|
+
call('env', 'CreateEntAppEnv', {'EnvironmentPolicyId' => envPolicyId,
|
82
|
+
'SnapshotId' => snapshotId,
|
83
|
+
'ProjectFilter' => project_filter,
|
84
|
+
'BlueprintFilter' => blueprint_filter,
|
85
|
+
'EnvironmentPolicyDurationFilter' => env_policy_duration_filter,
|
86
|
+
'EnvironmentNewName' => env_new_name})
|
87
|
+
end
|
88
|
+
|
89
|
+
def create_empty_ent_app_env(env_name, project_name, description='none')
|
90
|
+
call('env', 'CreateEmptyEntAppEnv',
|
91
|
+
{'EnvName' => env_name, 'ProjectName' => project_name, 'Description' => description})
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
# Snapshots
|
96
|
+
|
97
|
+
def get_snapshots(envId)
|
98
|
+
call('env', 'GetSnapshots', {'EnvId' => envId})
|
99
|
+
end
|
100
|
+
|
101
|
+
def get_snapshot_info(snapshotId)
|
102
|
+
call('env', 'GetSnapshotDetails', {'SnapshotId' => snapshotId})
|
103
|
+
end
|
104
|
+
|
105
|
+
def get_blueprints_for_publish(envId)
|
106
|
+
call('env', 'GetBlueprintsForPublish', {'EnvId' => envId})
|
107
|
+
end
|
108
|
+
|
109
|
+
def mark_snapshot_default(envId, snapshotId)
|
110
|
+
call('env', 'MarkSnapshotDefault', {'EnvId' => envId, 'SnapshotId' => snapshotId})
|
111
|
+
end
|
112
|
+
|
113
|
+
def ent_app_take_snapshot(envId, snapshot_name, description='', set_as_default=true)
|
114
|
+
call('env', 'EntAppTakeSnapshot',
|
115
|
+
{'EnvId' => envId, 'SnapshotName' => snapshot_name, 'Description' => description,
|
116
|
+
'SetAsDefault' => (set_as_default ? 'true' : 'false')})
|
117
|
+
end
|
118
|
+
|
119
|
+
def ent_app_take_snapshot_to_new_blueprint(envId, snapshot_name, new_blueprint_name, description='')
|
120
|
+
call('env', 'EntAppTakeSnapshotToNewBlueprint',
|
121
|
+
{'EnvId' => envId,
|
122
|
+
'SnapshotName' => snapshot_name,
|
123
|
+
'NewBlueprintName' => new_blueprint_name,
|
124
|
+
'Description' => description})
|
125
|
+
end
|
126
|
+
|
127
|
+
def ent_app_take_snapshot_to_existing_blueprint(envId, snapshot_name, otherBlueprintId, description='', set_as_default=true)
|
128
|
+
call('env', 'EntAppTakeSnapshotToExistingBlueprint',
|
129
|
+
{'EnvId' => envId,
|
130
|
+
'SnapshotName' => snapshot_name,
|
131
|
+
'OtherBlueprintId' => otherBlueprintId,
|
132
|
+
'Desctiption' => description,
|
133
|
+
'SetAsDefault' => (set_as_default ? 'true' : 'false')})
|
134
|
+
end
|
135
|
+
|
136
|
+
# VM actions
|
137
|
+
|
138
|
+
def delete_vm(envId, vmId)
|
139
|
+
call('env', 'DeleteVm', {'EnvId' => envId, 'VmId' => vmId})
|
140
|
+
end
|
141
|
+
|
142
|
+
def revert_vm(envId, vmId)
|
143
|
+
call('env', 'RevertVm', {'EnvId' => envId, 'VmId' => vmId})
|
144
|
+
end
|
145
|
+
|
146
|
+
def reboot_vm(envId, vmId)
|
147
|
+
call('env', 'RebootVm', {'EnvId' => envId, 'VmId' => vmId})
|
148
|
+
end
|
149
|
+
|
150
|
+
def execute_path(envId, vmId, path)
|
151
|
+
call('env', 'ExecutePathExt', {'EnvId' => envId, 'VmId' => vmId, 'Path' => path})
|
152
|
+
end
|
153
|
+
|
154
|
+
def edit_machine_hardware(envId, vmId, numCpus=nil,mbRAM=nil, gbDisk=nil)
|
155
|
+
call('env', 'EditMachineHardware',
|
156
|
+
{'EnvId' => envId,
|
157
|
+
'VmId' => vmId,
|
158
|
+
'NumCpus' => numCpus,
|
159
|
+
'MemorySizeMBs' => mbRAM,
|
160
|
+
'DiskSizeGBs' => gbDisk})
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_execution_id(envId, vmId, exec_id)
|
164
|
+
call('env', 'CheckExecutionStatus', {'EnvId' => envId, 'VmId' => vmId, 'ExecutionId' => exec_id})
|
165
|
+
end
|
166
|
+
|
167
|
+
# CloudFolders
|
168
|
+
|
169
|
+
def get_cloudfolders_info
|
170
|
+
call('env', 'GetCloudFoldersInfo')
|
171
|
+
end
|
172
|
+
|
173
|
+
def mount(envId)
|
174
|
+
call('env', 'Mount', {'EnvId' => envId})
|
175
|
+
end
|
176
|
+
|
177
|
+
def unmount(envId)
|
178
|
+
call('env', 'Unmount', {'EnvId' => envId})
|
179
|
+
end
|
180
|
+
|
181
|
+
def mount_and_fetch_info(envId)
|
182
|
+
call('env', 'MountAndFetchInfo', {'EnvId' => envId})
|
183
|
+
end
|
184
|
+
|
185
|
+
def mount_and_fetch_info_ext(envId)
|
186
|
+
call('env', 'MountAndFetchInfoExt', {'EnvId' => envId})
|
187
|
+
end
|
188
|
+
|
189
|
+
def regenerate_cloudfolders_password
|
190
|
+
call('env', 'RegenerateCloudfoldersPassword')
|
191
|
+
end
|
192
|
+
|
193
|
+
# Login
|
194
|
+
|
195
|
+
def get_login_url(url)
|
196
|
+
call('env', 'GetLoginUrl', {'Url' => url})
|
197
|
+
end
|
198
|
+
|
199
|
+
def who_am_i(userId)
|
200
|
+
call('env', 'WhoAmI', {'UserId' => userId})
|
201
|
+
end
|
202
|
+
|
203
|
+
# RDP
|
204
|
+
|
205
|
+
def get_remote_access(envId, vmId, isConsole='', desktopWidth='', desktopHeight='')
|
206
|
+
call('env', 'GetRemoteAccessFile',
|
207
|
+
{'EnvId' => envId,
|
208
|
+
'VmId' => vmId,
|
209
|
+
'IsConsole' => isConsole,
|
210
|
+
'DesktopWidth' => desktopWidth,
|
211
|
+
'DesktopHeight' => desktopHeight})
|
212
|
+
end
|
213
|
+
|
214
|
+
# Admin
|
215
|
+
|
216
|
+
def list_allowed_commands
|
217
|
+
call('admin', 'ListAllowedCommands')
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
require 'securerandom'
|
4
|
+
require 'digest'
|
5
|
+
|
6
|
+
module CloudshareSDK
|
7
|
+
def self.token_generator
|
8
|
+
if RUBY_VERSION >= "1.9"
|
9
|
+
SecureRandom.hex(10/2) # generated result string from #hex is double the size of given n...
|
10
|
+
else
|
11
|
+
o = [('a'..'z'), ('A'..'Z'), ('0'..'9')].map { |i| i.to_a }.flatten
|
12
|
+
(0...10).map { o[rand(o.length)] }.join
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.prettify_json(s)
|
17
|
+
begin
|
18
|
+
JSON.pretty_generate(Hash[JSON.parse(s).sort])
|
19
|
+
rescue
|
20
|
+
s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class ApiException < StandardError
|
25
|
+
attr_reader :content, :code
|
26
|
+
def initialize(content, code)
|
27
|
+
@content = content
|
28
|
+
@code = code
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"\ncontent:\n\n#@content\n\nhttp status code: #@code\n\n"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
class ApiResponse
|
38
|
+
def initialize(content, code)
|
39
|
+
@content = content
|
40
|
+
@code = code
|
41
|
+
end
|
42
|
+
|
43
|
+
def pretty_content
|
44
|
+
CloudshareSDK::prettify_json(@content)
|
45
|
+
end
|
46
|
+
|
47
|
+
def json
|
48
|
+
JSON.parse(@content)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
class CSLowApi
|
54
|
+
DEFAULT_HOST = "use.cloudshare.com"
|
55
|
+
DEFAULT_VERSION = "v2"
|
56
|
+
|
57
|
+
def initialize(id, key, version=DEFAULT_VERSION, host=DEFAULT_HOST)
|
58
|
+
@id = id
|
59
|
+
@key = key
|
60
|
+
@version = version
|
61
|
+
@host = host
|
62
|
+
end
|
63
|
+
|
64
|
+
def call(category, command, params={})
|
65
|
+
uri = gen_uri(category, command, params)
|
66
|
+
begin
|
67
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
68
|
+
http.use_ssl = true
|
69
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
70
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
71
|
+
f = http.request(request)
|
72
|
+
raise ApiException.new(f.body , f.code) if f.code != '200'
|
73
|
+
raise ApiException.new('Empty Response' , f.code) if f.body.length == 0
|
74
|
+
rescue StandardError => ex
|
75
|
+
raise ApiException.new((ex.respond_to?(:content) ? ex.content : ex.message),
|
76
|
+
(ex.respond_to?(:code) ? ex.code : -1))
|
77
|
+
end
|
78
|
+
|
79
|
+
ApiResponse.new(f.body, f.code)
|
80
|
+
end
|
81
|
+
|
82
|
+
def gen_uri(category, command, params)
|
83
|
+
hmac = Digest::SHA1.new
|
84
|
+
hmac.update(@key.encode('utf-8'))
|
85
|
+
hmac.update(command.downcase.encode('utf-8')) if @version != 'v1'
|
86
|
+
|
87
|
+
params['timestamp'] = Time.now.to_i.to_s
|
88
|
+
params['UserApiId'] = @id
|
89
|
+
params['token'] = CloudshareSDK::token_generator if @version != 'v1'
|
90
|
+
|
91
|
+
query = {}
|
92
|
+
params.keys.sort_by {|k| [k.downcase]}.each do |pkey|
|
93
|
+
pkey_lower = pkey.downcase
|
94
|
+
continue if pkey_lower == "hmac"
|
95
|
+
|
96
|
+
hmac.update(pkey_lower.encode('utf-8'))
|
97
|
+
pvalue = params[pkey]
|
98
|
+
if !pvalue.nil? and pvalue.length > 0
|
99
|
+
hmac.update(pvalue.encode('utf-8'))
|
100
|
+
query[pkey] = pvalue.encode('utf-8')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
query['HMAC'] = hmac.hexdigest
|
105
|
+
uri = URI("https://#{@host.encode('utf-8')}/Api/#{@version.encode('utf-8')}" +
|
106
|
+
"/#{category.encode('utf-8')}/#{command.encode('utf-8')}")
|
107
|
+
uri.tap do |u|
|
108
|
+
u.query = URI.encode_www_form(query)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def check_keys
|
113
|
+
call('ApiTest', 'Ping').json['data']
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloudshare-sdk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.dev
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Muly Gottlieb
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-04-09 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! 'An SDK for developing applications in Ruby to connect to the CloudShare
|
15
|
+
service using the CloudShare API. '
|
16
|
+
email: muly@cloudshare.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/cloudshare-sdk.rb
|
22
|
+
- lib/cloudshare-sdk/cs_high_api.rb
|
23
|
+
- lib/cloudshare-sdk/cs_low_api.rb
|
24
|
+
homepage: http://www.cloudshare.com
|
25
|
+
licenses:
|
26
|
+
- Apache 2.0
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>'
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.3.1
|
43
|
+
requirements: []
|
44
|
+
rubyforge_project:
|
45
|
+
rubygems_version: 1.8.28
|
46
|
+
signing_key:
|
47
|
+
specification_version: 3
|
48
|
+
summary: An SDK for developing applications in Ruby to connect to the CloudShare service
|
49
|
+
using the CloudShare API.
|
50
|
+
test_files: []
|