cantemo-portal-agent 1.0.9 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/exe/cantemo-portal-agent +8 -6
  3. data/lib/cantemo/portal/agent/WatchFolderUtility/foreman.rb +59 -0
  4. data/lib/cantemo/portal/agent/cli/commands/watch_folders-working.rb +237 -0
  5. data/lib/cantemo/portal/agent/cli/commands/watch_folders.rb +63 -0
  6. data/lib/cantemo/portal/agent/version.rb +1 -1
  7. data/lib/envoi/aspera/watch_service/client.rb +397 -0
  8. data/lib/envoi/aspera/watch_service/snapshot.rb +11 -0
  9. data/lib/envoi/aspera/watch_service/subscription.rb +0 -0
  10. data/lib/envoi/aspera/watch_service/watch_folder.rb +322 -0
  11. data/lib/envoi/mam/agent/cli/commands/cantemo-agent.rb +62 -0
  12. data/lib/envoi/mam/agent/cli/commands/cantemo-watch_folders.rb +41 -0
  13. data/lib/envoi/mam/agent/cli/commands/cantemo.rb +5 -0
  14. data/lib/envoi/mam/agent/cli/commands/iconik.rb +21 -11
  15. data/lib/envoi/mam/agent/cli/commands/mediasilo.rb +1 -1
  16. data/lib/envoi/mam/agent/cli/commands/vidispine.rb +7 -4
  17. data/lib/envoi/mam/agent/cli/commands/wiredrive.rb +15 -2
  18. data/lib/envoi/mam/agent/cli/commands.rb +4 -4
  19. data/lib/envoi/mam/agent/cli.rb +3 -3
  20. data/lib/envoi/mam/agent/transfer_client/aspera.rb +145 -7
  21. data/lib/envoi/mam/agent/version.rb +1 -1
  22. data/lib/envoi/mam/agent/watch_folder_utility/foreman.rb +76 -0
  23. data/lib/envoi/mam/agent.rb +6 -1
  24. data/lib/envoi/mam/cantemo/agent/watch_folder_handler-working.rb +111 -0
  25. data/lib/envoi/mam/cantemo/agent/watch_folder_handler.rb +176 -0
  26. data/lib/envoi/mam/cantemo/agent/watch_folder_handler_aspera.rb +112 -0
  27. data/lib/envoi/mam/cantemo/agent.rb +288 -0
  28. data/lib/envoi/mam/iconik/agent.rb +15 -3
  29. data/lib/envoi/mam/vidispine/agent.rb +6 -1
  30. data/lib/envoi/watch_folder_utility/watch_folder/handler/listen.rb +189 -0
  31. metadata +48 -4
@@ -0,0 +1,397 @@
1
+ require 'json'
2
+ require 'logger'
3
+ require 'open3'
4
+ require 'shellwords'
5
+
6
+ module Envoi
7
+ module Aspera
8
+ module WatchService
9
+
10
+ class Client
11
+
12
+ attr_accessor :logger, :initial_args, :config
13
+
14
+ attr_accessor :aswatchadmin_executable_path, :default_username
15
+
16
+ DEFAULT_ASWATCHADMIN_EXECUTABLE_PATH = '/Library/Aspera/bin/aswatchadmin'
17
+
18
+ DAEMON_NAME_FIELD_NAME = 'name'
19
+ DAEMON_CONFIGURATION_FIELD_NAME = 'configuration'
20
+
21
+ DAEMONS_QUERY_LINE_PART_TO_SUB = 'configuration: '
22
+ DAEMONS_QUERY_LINE_START = "#{DAEMONS_QUERY_LINE_PART_TO_SUB} {"
23
+
24
+ class Expressions
25
+ SNAPSHOT_CREATE_VERSION_PARSE = /(?<version>\d*)\.$/
26
+ SNAPSHOT_PRINT_PARSE = /^\s{2}(?<path>.*), (?<stat_as_json>\{"ino":\d+,.*})$/
27
+ SUBSCRIPTION_CREATE_PARSE = /(?<json>\{.*\})\s*$/
28
+ SUBSCRIPTION_RESUBSCRIBE_SUCCESS_PARSE = /^\[aswatchadmin resubscribe\] Successfully resubscribed subscription '[^']*'\.$/
29
+ SNAPSHOT_DIFFERENTIAL_PARSE = /^event\=(?<event>[^\,]*),path\=(?<path>.*),stat\=\[type\=(?<stat_type>[A-Z_]*),(?<change>[^\]]*)\]$/
30
+ end
31
+
32
+ class SnapshotEntry < Hash
33
+
34
+ def initialize(data)
35
+ # @attributes = data.is_a?(MatchData) ? { path: data[:path], stat_as_json: data[:stat_as_json] } : data
36
+ merge! data
37
+ end
38
+
39
+ def path; self[:path] end
40
+
41
+ def stat
42
+ self[:stat] ||= begin
43
+ json = self[:stat_as_json]
44
+ JSON.parse(json) if json
45
+ end
46
+ end
47
+
48
+ def stat_as_json; self[:stat_as_json] end
49
+
50
+ if MatchData.method_defined?(:named_captures)
51
+ def self.new_from_match_data(match_data)
52
+ new(match_data.named_captures)
53
+ end
54
+ else
55
+ def self.new_from_match_data(match_data)
56
+ new(Hash[match_data.names.map(&:to_sym).zip(match_data.captures)])
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.current_os_type
62
+ case RUBY_PLATFORM
63
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
64
+ return :windows
65
+ when /darwin|mac os/
66
+ return :mac
67
+ else # unix family
68
+ return :unix
69
+ end
70
+ end
71
+
72
+ def self.detect_executable
73
+ executable_name = 'aswatchadmin'
74
+ paths = case current_os_type
75
+ when :windows
76
+ executable_name += '.exe'
77
+ [
78
+ File.join(ENV['LOCALAPPDATA'], 'Aspera', 'bin', executable_name)
79
+ ]
80
+ when :mac
81
+ [
82
+ "/Library/Aspera/bin/#{executable_name}",
83
+ ]
84
+ else
85
+ [
86
+ File.join("/opt/aspera/bin/#{executable_name}")
87
+ ]
88
+ end
89
+ paths.find { |p| File.executable?(p) }
90
+ end
91
+
92
+ def initialize(args = {})
93
+ @initial_args = args.clone
94
+ initialize_logger(args)
95
+
96
+ @config = args[:config]
97
+
98
+ @aswatchadmin_executable_path = args[:aswatchadmin_executable_path] ||
99
+ self.class.detect_executable ||
100
+ DEFAULT_ASWATCHADMIN_EXECUTABLE_PATH
101
+ @default_daemon_name = args[:default_daemon_name] || args[:daemon_name] || default_daemon_name_get
102
+ @dry_run = args.fetch(:dry_run, false)
103
+ end
104
+
105
+ def initialize_logger(args = {})
106
+ @logger = args[:logger] || Logger.new(STDOUT)
107
+ end
108
+
109
+ def dry_run?;
110
+ @dry_run
111
+ end
112
+
113
+ def shell_execute(command, dry_run = @dry_run)
114
+ command = command.shelljoin if command.is_a?(Array)
115
+ if dry_run
116
+ logger.debug { "Skipping Execution of Command: '#{command}' " }
117
+ return
118
+ end
119
+ logger.debug { "Executing Command: '#{command}'" }
120
+
121
+ response = ''
122
+ Open3.popen3(command) do |stdin, stdout, stderr, thread|
123
+ # stdin.sync = true
124
+ # stdout.sync = true
125
+ # stderr.sync = true
126
+ output = ''
127
+ loop do
128
+ output << stdout.read #rescue nil
129
+ output << stderr.read # rescue nil
130
+ unless output.empty?
131
+ # print output
132
+ response << output.dup
133
+ output.clear
134
+ end
135
+ break if thread.stop?
136
+ end
137
+ end
138
+
139
+ logger.debug { "RESPONSE: #{response.empty? ? '' : "\n#{response}"}" }
140
+ response
141
+ end
142
+
143
+ # @return [Hash]
144
+ def default_daemon_get
145
+ daemons = daemons_query
146
+ return nil unless daemons.length == 1
147
+ default_daemon = daemons.first
148
+ end
149
+
150
+ # @return [String|nil]
151
+ def default_daemon_name_get
152
+ _default_daemon = default_daemon_get
153
+ return nil unless _default_daemon
154
+ _default_daemon[DAEMON_NAME_FIELD_NAME]
155
+ end
156
+
157
+ # @return [Array]
158
+ def daemons_query(args = {})
159
+ command = [aswatchadmin_executable_path, 'query-daemons']
160
+ response = shell_execute(command)
161
+
162
+ return response unless args.fetch(:parse_response, true)
163
+
164
+ daemons_query_response_parse(response)
165
+ end
166
+
167
+ # @return [Array[Hash]]
168
+ def daemons_query_response_parse(response)
169
+ response_ary = response.split("\n")
170
+ first_line = response_ary.shift
171
+ daemon = nil
172
+ daemons = response_ary.each_with_object([]) do |line, _daemons|
173
+ _line = line.strip
174
+
175
+ if _line.start_with?(DAEMONS_QUERY_LINE_START)
176
+ configuration_json = _line.sub(DAEMONS_QUERY_LINE_PART_TO_SUB, '')
177
+ configuration = JSON.parse(configuration_json)
178
+ daemon[DAEMON_CONFIGURATION_FIELD_NAME] = configuration
179
+ else
180
+ _daemons << daemon if daemon
181
+ daemon_name = _line
182
+ daemon = { DAEMON_NAME_FIELD_NAME => daemon_name }
183
+ end
184
+ end
185
+ daemons << daemon if daemon
186
+ end
187
+
188
+ def subscription_create(args = {})
189
+ daemon_name = args[:daemon_name] || args[:daemon] || @default_daemon_name
190
+ raise ArgumentError, 'Missing argument for required parameter daemon_name' unless daemon_name
191
+
192
+ watch_folder_path = args[:watch_folder_path]
193
+ raise ArgumentError, 'Missing argument for required parameter watch_folder_path' unless watch_folder_path
194
+
195
+ scan_period = args[:scan_period]
196
+ expire_in = args[:expire_in]
197
+
198
+ command = [aswatchadmin_executable_path, 'subscribe', daemon_name, watch_folder_path]
199
+ command << '--scan-period' << scan_period if scan_period
200
+ command << '--expire_in' << expire_in if expire_in
201
+ response = shell_execute(command)
202
+
203
+ return response unless args.fetch(:parse_response, true)
204
+
205
+ subscription_create_response_parse(response)
206
+ end
207
+
208
+ # @param [Object] response
209
+ # @return [Object]
210
+ def subscription_create_response_parse(response)
211
+ subscription_json_match = Expressions::SUBSCRIPTION_CREATE_PARSE.match(response)
212
+ raise "Failed to parse new subscription information from response. '#{response}'" unless subscription_json_match
213
+ subscription_json = subscription_json_match.to_s
214
+ subscription = JSON.parse(subscription_json)
215
+ end
216
+
217
+ def subscription_resubscribe(args = {})
218
+ daemon_name = args[:daemon_name] || args[:daemon] || @default_daemon_name
219
+ raise ArgumentError, 'Missing argument for required parameter daemon_name' unless daemon_name
220
+
221
+ subscription_id = args[:subscription_id]
222
+ raise ArgumentError, 'Missing argument for required parameter subscription_id' unless subscription_id
223
+
224
+ command = [aswatchadmin_executable_path, 'resubscribe', daemon_name, subscription_id]
225
+ response = shell_execute(command)
226
+
227
+ return response unless args.fetch(:parse_response, true)
228
+
229
+ subscription_resubscribe_parse_response(response)
230
+ end
231
+
232
+ def subscription_resubscribe_parse_response(response)
233
+ raise response unless Expressions::SUBSCRIPTION_RESUBSCRIBE_SUCCESS_PARSE.match(response)
234
+ true
235
+ end
236
+
237
+ # Create a snapshot using the subscription
238
+ #
239
+ # ```
240
+ # $ /Library/Aspera/bin/aswatchadmin create-snapshot jw f090e8b5-d9e2-474b-acb1-68c4f76c8c53
241
+ # [aswatchadmin create-snapshot] Successfully created snapshot 0.
242
+ # ```
243
+ def subscription_snapshot_create(args = {})
244
+ daemon_name = args[:daemon_name] || args[:daemon] || @default_daemon_name
245
+ raise ArgumentError, 'Missing argument for required parameter daemon_name' unless daemon_name
246
+
247
+ subscription_id = args[:subscription_id]
248
+ raise ArgumentError, 'Missing argument for required parameter subscription_id' unless subscription_id
249
+
250
+ command = [aswatchadmin_executable_path, 'create-snapshot', daemon_name, subscription_id]
251
+ response = shell_execute(command)
252
+
253
+ return response unless args.fetch(:parse_response, true)
254
+
255
+ subscription_snapshot_create_response_parse(response)
256
+ end
257
+
258
+ def subscription_snapshot_create_response_parse(response)
259
+ snapshot_version = Expressions::SNAPSHOT_CREATE_VERSION_PARSE.match(response)
260
+ raise "Failed to parse snapshot version from response. '#{response}'" unless snapshot_version
261
+ snapshot_version
262
+ end
263
+
264
+ def subscription_snapshot_differential(args = {})
265
+ daemon_name = args[:daemon_name] || args[:daemon] || @default_daemon_name
266
+ raise ArgumentError, 'Missing argument for required parameter daemon_name' unless daemon_name
267
+
268
+ subscription_id = args[:subscription_id]
269
+ raise ArgumentError, 'Missing argument for required parameter subscription_id' unless subscription_id
270
+
271
+ from = args[:from]
272
+
273
+ to = args[:to]
274
+
275
+ path = args[:path]
276
+ identifier = args[:identifier]
277
+ format = args[:format]
278
+ escape = args[:escape]
279
+ exclude_create = args[:exclude_create]
280
+ exclude_modify = args[:exclude_modify]
281
+ exclude_remove = args[:exclude_remove]
282
+ leafs_only = args[:leafs_only]
283
+
284
+ command = [aswatchadmin_executable_path, 'snapshot-differential', daemon_name, subscription_id]
285
+ command << from if from
286
+ command << to if to
287
+ command << '--path' << path if path && !path.empty?
288
+ command << '--identifier' << identifier if identifier && !identifier.empty?
289
+ command << '--format' << format if format && !format.empty?
290
+ command << '--escape' << escape if escape && !escape.empty?
291
+ command << '--exclude_create' if exclude_create
292
+ command << '--exclude_modify' if exclude_modify
293
+ command << '--exclude-remove' if exclude_remove
294
+ command << '--leafs-only' if leafs_only
295
+ response = shell_execute(command)
296
+
297
+ return response unless args.fetch(:parse_response, true)
298
+
299
+ subscription_snapshot_differential_response_parse(response)
300
+ end
301
+
302
+ def subscription_snapshot_differential_response_parse(response)
303
+ response.split.map do |v|
304
+ m = v.match(Expressions::SNAPSHOT_DIFFERENTIAL_PARSE)
305
+ m ? Hash[m.names.zip(m.captures)] : v
306
+ end.join('\n')
307
+ end
308
+
309
+ def subscription_snapshot_print(args = {})
310
+ daemon_name = args[:daemon_name] || args[:daemon] || @default_daemon_name
311
+ raise ArgumentError, 'Missing argument for required parameter daemon_name' unless daemon_name
312
+
313
+ subscription_id = args[:subscription_id]
314
+ raise ArgumentError, 'Missing argument for required parameter subscription_id' unless subscription_id
315
+
316
+ snapshot_version = args[:snapshot_version]
317
+ command = [aswatchadmin_executable_path, 'print-snapshot', daemon_name, subscription_id]
318
+ command << '--snapshot' << snapshot_version if snapshot_version
319
+
320
+ response = shell_execute(command)
321
+
322
+ return response unless args.fetch(:parse_response, false)
323
+
324
+ subscription_snapshot_print_response_parse(response)
325
+ end
326
+
327
+ def subscription_snapshot_print_response_parse(response)
328
+ response
329
+ .to_enum(:scan, Expressions::SNAPSHOT_PRINT_PARSE)
330
+ .map { SnapshotEntry.new_from_match_data(Regexp.last_match) }
331
+ end
332
+
333
+ def subscription_snapshot_entries_get(args = { })
334
+ response = subscription_snapshot_print(args)
335
+ subscription_snapshot_print_response_parse(response)
336
+ end
337
+
338
+
339
+ # List subscriptions for a specific daemon
340
+ # @see https://download.asperasoft.com/download/docs/entsrv/3.8.1/cs_admin_osx/webhelp/index.html#dita-watchfolder/watchd_subscriptions.html
341
+ def subscriptions_get(args = {})
342
+ daemon_name = args[:daemon_name] || args[:daemon] || @default_daemon_name
343
+ raise ArgumentError, 'Missing argument for required parameter daemon_name' unless daemon_name
344
+
345
+ command = [aswatchadmin_executable_path, 'query-subscriptions', daemon_name]
346
+ response = shell_execute(command)
347
+
348
+ return response unless args.fetch(:parse_response, true)
349
+
350
+ subscriptions_get_response_parse(response)
351
+ end
352
+
353
+ def subscriptions_get_response_parse(response)
354
+ response_json = "[#{response.split.join(",\n")}]"
355
+ subscriptions = JSON.parse(response_json)
356
+ end
357
+
358
+ # Unsubscribe from a watch
359
+ #
360
+ # $ /Library/Aspera/bin/aswatchadmin unsubscribe daemonname 3b758f2d-97f9-4054-80d5-ed67dcaa8daa
361
+ # [aswatchadmin unsubscribe] Successfully unsubscribed subscription '3b758f2d-97f9-4054-80d5-ed67dcaa8daa' from daemon 'daemonname'.
362
+ #
363
+ # @see https://download.asperasoft.com/download/docs/entsrv/3.8.1/cs_admin_osx/webhelp/index.html#dita-watchfolder/watchd_subscriptions.html
364
+ def subscription_unsubscribe(args = {})
365
+ daemon_name = args[:daemon_name] || args[:daemon] || @default_daemon_name
366
+ raise ArgumentError, 'Missing argument for required parameter daemon_name' unless daemon_name
367
+
368
+ subscription_id = args[:subscription_id]
369
+ raise ArgumentError, 'Missing argument for required parameter subscription_id' unless subscription_id
370
+
371
+ command = [aswatchadmin_executable_path, 'unsubscribe', daemon_name, subscription_id]
372
+ response = shell_execute(command)
373
+ end
374
+
375
+ def subscriptions_unsubscribe_all(args = {})
376
+ subscriptions = subscriptions_get(args)
377
+ args_out = args.dup
378
+ path = args[:path]
379
+ subscriptions.each do |subscription|
380
+ next unless subscription['path'] == path if path
381
+ subscription_id = subscription['identifier']
382
+ args_out[:subscription_id] = subscription_id
383
+ subscription_unsubscribe(args_out)
384
+ end
385
+ end
386
+
387
+ def subscription_find_for_path(args = {})
388
+ path = args[:path]
389
+ subscriptions = args[:subscriptions] || subscriptions_get(args)
390
+ subscriptions.keep_if { |s| s['path'] =~ /(?:\w|-)*:\/{2,3}#{Regexp.escape(path)}/ }
391
+ end
392
+
393
+ end
394
+
395
+ end
396
+ end
397
+ end
@@ -0,0 +1,11 @@
1
+ module Envoi
2
+ module Aspera
3
+ module WatchService
4
+
5
+ class Snapshot
6
+
7
+ end
8
+
9
+ end
10
+ end
11
+ end
File without changes