cantemo-portal-agent 1.0.9 → 1.1.0

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.
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