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.
@@ -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
@@ -0,0 +1,6 @@
1
+ module CloudshareSDK
2
+ require 'cloudshare-sdk/cs_low_api'
3
+ require 'cloudshare-sdk/cs_high_api'
4
+ end
5
+
6
+
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: []