morpheus-cli 3.4.1.10 → 3.5.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.
- checksums.yaml +5 -5
- data/lib/morpheus/api/api_client.rb +4 -0
- data/lib/morpheus/api/cypher_interface.rb +55 -0
- data/lib/morpheus/api/storage_providers_interface.rb +113 -0
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/cli/archives_command.rb +5 -6
- data/lib/morpheus/cli/cli_command.rb +10 -1
- data/lib/morpheus/cli/clouds.rb +1 -0
- data/lib/morpheus/cli/cypher_command.rb +412 -0
- data/lib/morpheus/cli/echo_command.rb +1 -1
- data/lib/morpheus/cli/library_option_lists_command.rb +109 -30
- data/lib/morpheus/cli/policies_command.rb +208 -118
- data/lib/morpheus/cli/set_prompt_command.rb +1 -1
- data/lib/morpheus/cli/shell.rb +3 -2
- data/lib/morpheus/cli/storage_providers_command.rb +788 -5
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/terminal.rb +1 -1
- metadata +5 -3
data/lib/morpheus/cli/shell.rb
CHANGED
@@ -80,8 +80,8 @@ class Morpheus::Cli::Shell
|
|
80
80
|
end
|
81
81
|
# cleanup empty brackets caused by var value
|
82
82
|
@calculated_prompt = @calculated_prompt.gsub("[]", "").gsub("<>", "").gsub("{}", "")
|
83
|
-
|
84
|
-
@calculated_prompt = "#{@calculated_prompt}#{reset} "
|
83
|
+
#@calculated_prompt = @calculated_prompt.strip
|
84
|
+
# @calculated_prompt = "#{@calculated_prompt}#{reset} "
|
85
85
|
@calculated_prompt
|
86
86
|
end
|
87
87
|
|
@@ -211,6 +211,7 @@ class Morpheus::Cli::Shell
|
|
211
211
|
input = input.strip
|
212
212
|
|
213
213
|
result = execute(input)
|
214
|
+
print reset
|
214
215
|
end
|
215
216
|
end
|
216
217
|
|
@@ -12,7 +12,17 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
12
12
|
set_command_name :'storage-providers'
|
13
13
|
|
14
14
|
register_subcommands :list, :get, :add, :update, :remove
|
15
|
-
|
15
|
+
# file commands
|
16
|
+
register_subcommands :'list-files' => :list_files
|
17
|
+
register_subcommands :'ls' => :ls
|
18
|
+
#register_subcommands :'file' => :get_file
|
19
|
+
# register_subcommands :'history' => :file_history
|
20
|
+
register_subcommands :'upload' => :upload_file
|
21
|
+
register_subcommands :'download' => :download_file
|
22
|
+
register_subcommands :'read' => :read_file
|
23
|
+
register_subcommands :'remove-file' => :remove_file
|
24
|
+
register_subcommands :'rm' => :remove_file
|
25
|
+
|
16
26
|
# set_default_subcommand :list
|
17
27
|
|
18
28
|
def initialize()
|
@@ -39,6 +49,11 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
39
49
|
opts.footer = "List storage providers."
|
40
50
|
end
|
41
51
|
optparse.parse!(args)
|
52
|
+
if args.count != 0
|
53
|
+
print_error Morpheus::Terminal.angry_prompt
|
54
|
+
puts_error "wrong number of arguments, expected 0 and got #{args.count}\n#{optparse}"
|
55
|
+
return 1
|
56
|
+
end
|
42
57
|
connect(options)
|
43
58
|
begin
|
44
59
|
params.merge!(parse_list_options(options))
|
@@ -158,6 +173,7 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
158
173
|
def add(args)
|
159
174
|
options = {}
|
160
175
|
ip_range_list = nil
|
176
|
+
create_bucket = nil
|
161
177
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
162
178
|
opts.banner = subcommand_usage()
|
163
179
|
opts.on('--name VALUE', String, "Name for this storage provider") do |val|
|
@@ -181,6 +197,9 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
181
197
|
opts.on('--copy-to-store [on|off]', String, "Archive Snapshots") do |val|
|
182
198
|
options['copyToStore'] = val.to_s == 'on' || val.to_s == 'true'
|
183
199
|
end
|
200
|
+
#opts.on('--create-bucket [on|off]', String, "Create Bucket") do |val|
|
201
|
+
# create_bucket = val.to_s == 'on' || val.to_s == 'true' || val.nil?
|
202
|
+
#end
|
184
203
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
|
185
204
|
opts.footer = "Create a new storage provider." + "\n" +
|
186
205
|
"[name] is required and can be passed as --name instead."
|
@@ -244,14 +263,17 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
244
263
|
{'fieldContext' => 'config', 'fieldName' => 'accessKey', 'fieldLabel' => 'Access Key', 'type' => 'text', 'required' => true, 'description' => ''},
|
245
264
|
{'fieldContext' => 'config', 'fieldName' => 'secretKey', 'fieldLabel' => 'Secret Key', 'type' => 'password', 'required' => true, 'description' => ''},
|
246
265
|
{'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
|
247
|
-
{'
|
266
|
+
{'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
|
267
|
+
{'fieldContext' => 'config', 'fieldName' => 'region', 'fieldLabel' => 'Region', 'type' => 'text', 'required' => false, 'description' => 'Optional Amazon region if creating a new bucket.'},
|
268
|
+
{'fieldContext' => 'config', 'fieldName' => 'endpoint', 'fieldLabel' => 'Endpoint URL', 'type' => 'text', 'required' => false, 'description' => 'Optional endpoint URL if pointing to an object store other than amazon that mimics the Amazon S3 APIs.'}
|
248
269
|
]
|
249
270
|
elsif storage_provider_type_code == 'azure'
|
250
271
|
# print_h2 "Azure Options"
|
251
272
|
provider_type_option_types = [
|
252
273
|
{'fieldContext' => 'config', 'fieldName' => 'storageAccount', 'fieldLabel' => 'Storage Account', 'type' => 'text', 'required' => true, 'description' => ''},
|
253
274
|
{'fieldContext' => 'config', 'fieldName' => 'storageKey', 'fieldLabel' => 'Storage Key', 'type' => 'password', 'required' => true, 'description' => ''},
|
254
|
-
{'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''}
|
275
|
+
{'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
|
276
|
+
{'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
|
255
277
|
]
|
256
278
|
elsif storage_provider_type_code == 'cifs'
|
257
279
|
# print_h2 "CIFS Options"
|
@@ -281,6 +303,7 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
281
303
|
{'fieldContext' => 'config', 'fieldName' => 'apiKey', 'fieldLabel' => 'API Key', 'type' => 'password', 'required' => true, 'description' => ''},
|
282
304
|
{'fieldContext' => 'config', 'fieldName' => 'region', 'fieldLabel' => 'Region', 'type' => 'text', 'required' => true, 'description' => ''},
|
283
305
|
{'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
|
306
|
+
{'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
|
284
307
|
{'fieldContext' => 'config', 'fieldName' => 'identityUrl', 'fieldLabel' => 'Identity URL', 'type' => 'text', 'required' => true, 'description' => ''},
|
285
308
|
]
|
286
309
|
elsif storage_provider_type_code == 'rackspace'
|
@@ -289,6 +312,7 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
289
312
|
{'fieldContext' => 'config', 'fieldName' => 'accessKey', 'fieldLabel' => 'Access Key', 'type' => 'text', 'required' => true, 'description' => ''},
|
290
313
|
{'fieldContext' => 'config', 'fieldName' => 'secretKey', 'fieldLabel' => 'Secret Key', 'type' => 'password', 'required' => true, 'description' => ''},
|
291
314
|
{'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
|
315
|
+
{'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
|
292
316
|
{'fieldContext' => 'config', 'fieldName' => 'endpoint', 'fieldLabel' => 'Endpoint URL', 'type' => 'text', 'required' => true, 'description' => 'Optional endpoint URL if pointing to an object store other than amazon that mimics the Amazon S3 APIs.'},
|
293
317
|
]
|
294
318
|
else
|
@@ -330,7 +354,12 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
330
354
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultVirtualImageTarget', 'fieldLabel' => 'Default Virtual Image Store', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'off'}], options)
|
331
355
|
payload['storageProvider']['defaultVirtualImageTarget'] = (v_prompt['defaultVirtualImageTarget'].to_s == 'on') unless v_prompt['defaultVirtualImageTarget'].nil?
|
332
356
|
end
|
333
|
-
|
357
|
+
#if create_bucket
|
358
|
+
# payload['createBucket'] = true
|
359
|
+
#end
|
360
|
+
if payload['storageProvider']['createBucket'] == 'on'
|
361
|
+
payload['storageProvider']['createBucket'] = true
|
362
|
+
end
|
334
363
|
end
|
335
364
|
|
336
365
|
|
@@ -440,6 +469,9 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
440
469
|
payload['storageProvider']['defaultVirtualImageTarget'] = options['defaultVirtualImageTarget']
|
441
470
|
end
|
442
471
|
|
472
|
+
if payload['storageProvider']['createBucket'] == 'on'
|
473
|
+
payload['storageProvider']['createBucket'] = true
|
474
|
+
end
|
443
475
|
end
|
444
476
|
|
445
477
|
if options[:dry_run]
|
@@ -465,7 +497,7 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
465
497
|
options = {}
|
466
498
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
467
499
|
opts.banner = subcommand_usage("[storage-provider]")
|
468
|
-
build_common_options(opts, options, [:
|
500
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
469
501
|
opts.footer = "Delete a storage provider." + "\n" +
|
470
502
|
"[storage-provider] is required. This is the name or id of a storage provider."
|
471
503
|
end
|
@@ -504,6 +536,686 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
504
536
|
end
|
505
537
|
end
|
506
538
|
|
539
|
+
def list_files(args)
|
540
|
+
options = {}
|
541
|
+
params = {}
|
542
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
543
|
+
opts.banner = subcommand_usage("[provider:/path]")
|
544
|
+
opts.on('-a', '--all', "Show all files, including subdirectories under the /path.") do
|
545
|
+
params[:fullTree] = true
|
546
|
+
end
|
547
|
+
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run])
|
548
|
+
opts.footer = "List files in a storage provider. \nInclude [/path] to show files under a directory."
|
549
|
+
end
|
550
|
+
optparse.parse!(args)
|
551
|
+
if args.count < 1 || args.count > 2
|
552
|
+
print_error Morpheus::Terminal.angry_prompt
|
553
|
+
puts_error "#{command_name} list-files expects 1-2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
|
554
|
+
return 1
|
555
|
+
end
|
556
|
+
storage_provider_id, search_file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
|
557
|
+
connect(options)
|
558
|
+
begin
|
559
|
+
storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
|
560
|
+
return 1 if storage_provider.nil?
|
561
|
+
params.merge!(parse_list_options(options))
|
562
|
+
[:fullTree].each do |k|
|
563
|
+
params[k] = options[k] unless options[k].nil?
|
564
|
+
end
|
565
|
+
if options[:dry_run]
|
566
|
+
print_dry_run @storage_providers_interface.dry.list_files(storage_provider['id'], search_file_path, params)
|
567
|
+
return
|
568
|
+
end
|
569
|
+
json_response = @storage_providers_interface.list_files(storage_provider['id'], search_file_path, params)
|
570
|
+
storage_files = json_response['storageFiles']
|
571
|
+
# storage_provider = json_response['storageProvider']
|
572
|
+
if options[:json]
|
573
|
+
print JSON.pretty_generate(json_response)
|
574
|
+
return
|
575
|
+
end
|
576
|
+
if options[:json]
|
577
|
+
puts as_json(json_response, options, "storageFiles")
|
578
|
+
return 0
|
579
|
+
elsif options[:yaml]
|
580
|
+
puts as_yaml(json_response, options, "storageFiles")
|
581
|
+
return 0
|
582
|
+
elsif options[:csv]
|
583
|
+
puts records_as_csv(json_response['storageFiles'], options)
|
584
|
+
return 0
|
585
|
+
end
|
586
|
+
print_h1 "Storage Files", ["#{storage_provider['name']}:#{search_file_path}"]
|
587
|
+
print cyan
|
588
|
+
description_cols = {
|
589
|
+
"ID" => 'id',
|
590
|
+
"Name" => 'name',
|
591
|
+
# "Bucket Name" => 'bucketName',
|
592
|
+
#"Path" => lambda {|it| search_file_path }
|
593
|
+
}
|
594
|
+
#print_description_list(description_cols, storage_provider)
|
595
|
+
#print "\n"
|
596
|
+
#print_h2 "Path: #{search_file_path}"
|
597
|
+
# print "Directory: #{search_file_path}"
|
598
|
+
if storage_files && storage_files.size > 0
|
599
|
+
print_storage_files_table(storage_files, {fullTree: params[:fullTree]})
|
600
|
+
#print_results_pagination(json_response, {:label => "file", :n_label => "files"})
|
601
|
+
print reset, "\n"
|
602
|
+
return 0
|
603
|
+
else
|
604
|
+
# puts "No files found for path #{search_file_path}"
|
605
|
+
if search_file_path.empty? || search_file_path == "/"
|
606
|
+
puts "This storage provider has no files."
|
607
|
+
print reset,"\n"
|
608
|
+
return 0
|
609
|
+
else
|
610
|
+
puts "No files found for path #{search_file_path}"
|
611
|
+
print reset,"\n"
|
612
|
+
return 1
|
613
|
+
end
|
614
|
+
end
|
615
|
+
rescue RestClient::Exception => e
|
616
|
+
print_rest_exception(e, options)
|
617
|
+
return 1
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
def ls(args)
|
622
|
+
options = {}
|
623
|
+
params = {}
|
624
|
+
do_one_file_per_line = false
|
625
|
+
do_long_format = false
|
626
|
+
do_human_bytes = false
|
627
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
628
|
+
opts.banner = subcommand_usage("[provider/path]")
|
629
|
+
opts.on('-a', '--all', "Show all files, including subdirectories under the /path.") do
|
630
|
+
params[:fullTree] = true
|
631
|
+
do_one_file_per_line = true
|
632
|
+
end
|
633
|
+
opts.on('-l', '--long', "Lists files in the long format, which contains lots of useful information, e.g. the exact size of the file, the file type, and when it was last modified.") do
|
634
|
+
do_long_format = true
|
635
|
+
do_one_file_per_line
|
636
|
+
end
|
637
|
+
opts.on('-H', '--human', "Humanized file sizes. The default is just the number of bytes.") do
|
638
|
+
do_human_bytes = true
|
639
|
+
end
|
640
|
+
opts.on('-1', '--oneline', "One file per line. The default delimiter is a single space.") do
|
641
|
+
do_one_file_per_line = true
|
642
|
+
end
|
643
|
+
build_common_options(opts, options, [:list, :json, :fields, :dry_run])
|
644
|
+
opts.footer = "Print filenames for a given location.\nPass storage location in the format provider/path."
|
645
|
+
end
|
646
|
+
optparse.parse!(args)
|
647
|
+
if args.count < 1 || args.count > 2
|
648
|
+
print_error Morpheus::Terminal.angry_prompt
|
649
|
+
puts_error "#{command_name} ls expects 1-2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
|
650
|
+
return 1
|
651
|
+
end
|
652
|
+
storage_provider_id, search_file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
|
653
|
+
connect(options)
|
654
|
+
begin
|
655
|
+
storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
|
656
|
+
return 1 if storage_provider.nil?
|
657
|
+
params.merge!(parse_list_options(options))
|
658
|
+
[:fullTree].each do |k|
|
659
|
+
params[k] = options[k] unless options[k].nil?
|
660
|
+
end
|
661
|
+
if options[:dry_run]
|
662
|
+
print_dry_run @storage_providers_interface.dry.list_files(storage_provider['id'], search_file_path, params)
|
663
|
+
return 0
|
664
|
+
end
|
665
|
+
json_response = @storage_providers_interface.list_files(storage_provider['id'], search_file_path, params)
|
666
|
+
if options[:json]
|
667
|
+
puts as_json(json_response, options, "storageFiles")
|
668
|
+
# no files is an error condition for this command
|
669
|
+
if !json_response['storageFiles'] || json_response['storageFiles'].size == 0
|
670
|
+
return 1
|
671
|
+
end
|
672
|
+
return 0
|
673
|
+
end
|
674
|
+
#storage_provider = json_response['storageProvider'] # yep, this is returned too
|
675
|
+
storage_files = json_response['storageFiles']
|
676
|
+
# print_h2 "Directory: #{search_file_path}"
|
677
|
+
# print "Directory: #{search_file_path}"
|
678
|
+
if storage_files && storage_files.size > 0
|
679
|
+
if do_long_format
|
680
|
+
# ls long format
|
681
|
+
# owner groups filesize type filename
|
682
|
+
now = Time.now
|
683
|
+
storage_files.each do |storage_file|
|
684
|
+
# -rw-r--r-- 1 jdickson staff 1361 Oct 23 08:00 voltron_2.10.log
|
685
|
+
file_color = cyan # reset
|
686
|
+
if storage_file['isDirectory']
|
687
|
+
file_color = blue
|
688
|
+
end
|
689
|
+
file_info = []
|
690
|
+
# Number of links
|
691
|
+
# file_info << file["linkCount"].to_i + 1
|
692
|
+
# Owner
|
693
|
+
owner_str = ""
|
694
|
+
if storage_file['owner']
|
695
|
+
owner_str = storage_file['owner']['name']
|
696
|
+
elsif storage_provider['owner']
|
697
|
+
owner_str = storage_provider['owner']['name']
|
698
|
+
else
|
699
|
+
owner_str = "noone"
|
700
|
+
end
|
701
|
+
#file_info << truncate_string(owner_str, 15).ljust(15, " ")
|
702
|
+
# Group (Tenants)
|
703
|
+
groups_str = ""
|
704
|
+
if storage_file['visibility'] == 'public'
|
705
|
+
# this is confusing because of Public URL (isPublic) setting
|
706
|
+
groups_str = "public"
|
707
|
+
else
|
708
|
+
if storage_file['accounts'].instance_of?(Array) && storage_file['accounts'].size > 0
|
709
|
+
# groups_str = storage_file['accounts'].collect {|it| it['name'] }.join(',')
|
710
|
+
groups_str = (storage_file['accounts'].size == 1) ? "#{storage_file['accounts'][0]['name']}" : "#{storage_file['accounts'].size} tenants"
|
711
|
+
elsif storage_provider['accounts'].instance_of?(Array) && storage_provider['accounts'].size > 0
|
712
|
+
# groups_str = storage_provider['accounts'].collect {|it| it['name'] }.join(',')
|
713
|
+
groups_str = (storage_provider['accounts'].size == 1) ? "#{storage_provider['accounts'][0]['name']}" : "#{storage_provider['accounts'].size} tenants"
|
714
|
+
else
|
715
|
+
groups_str = owner_str
|
716
|
+
end
|
717
|
+
end
|
718
|
+
#file_info << truncate_string(groups_str, 15).ljust(15, " ")
|
719
|
+
# File Type
|
720
|
+
content_type = storage_file['contentType'].to_s
|
721
|
+
if storage_file['isDirectory']
|
722
|
+
content_type = "directory"
|
723
|
+
else
|
724
|
+
content_type = storage_file['contentType'].to_s
|
725
|
+
end
|
726
|
+
file_info << content_type.ljust(25, " ")
|
727
|
+
filesize_str = ""
|
728
|
+
if do_human_bytes
|
729
|
+
# filesize_str = format_bytes(storage_file['contentLength'])
|
730
|
+
filesize_str = format_bytes_short(storage_file['contentLength'])
|
731
|
+
else
|
732
|
+
filesize_str = storage_file['contentLength'].to_i.to_s
|
733
|
+
end
|
734
|
+
# file_info << filesize_str.ljust(12, " ")
|
735
|
+
file_info << filesize_str.ljust(7, " ")
|
736
|
+
mtime = ""
|
737
|
+
last_updated = parse_time(storage_file['dateModified'])
|
738
|
+
if last_updated
|
739
|
+
if last_updated.year == now.year
|
740
|
+
mtime = format_local_dt(last_updated, {format: "%b %e %H:%M"})
|
741
|
+
else
|
742
|
+
mtime = format_local_dt(last_updated, {format: "%b %e %Y"})
|
743
|
+
end
|
744
|
+
end
|
745
|
+
file_info << mtime.ljust(12, " ")
|
746
|
+
fn = format_filename(storage_file['name'], {fullTree: params[:fullTree]})
|
747
|
+
file_info << file_color + fn.to_s + cyan
|
748
|
+
print cyan, file_info.join(" "), reset, "\n"
|
749
|
+
end
|
750
|
+
else
|
751
|
+
file_names = storage_files.collect do |storage_file|
|
752
|
+
file_color = cyan # reset
|
753
|
+
if storage_file['isDirectory']
|
754
|
+
file_color = blue
|
755
|
+
end
|
756
|
+
fn = format_filename(storage_file['name'], {fullTree: params[:fullTree]})
|
757
|
+
file_color + fn.to_s + reset
|
758
|
+
end
|
759
|
+
if do_one_file_per_line
|
760
|
+
print file_names.join("\n")
|
761
|
+
else
|
762
|
+
print file_names.join("\t")
|
763
|
+
end
|
764
|
+
print "\n"
|
765
|
+
end
|
766
|
+
else
|
767
|
+
print_error yellow, "No files found for path: #{search_file_path}", reset, "\n"
|
768
|
+
return 1
|
769
|
+
end
|
770
|
+
|
771
|
+
return 0
|
772
|
+
rescue RestClient::Exception => e
|
773
|
+
print_rest_exception(e, options)
|
774
|
+
return 1
|
775
|
+
end
|
776
|
+
end
|
777
|
+
|
778
|
+
# def get_file(args)
|
779
|
+
# todo...
|
780
|
+
# end
|
781
|
+
|
782
|
+
def upload_file(args)
|
783
|
+
options = {}
|
784
|
+
query_params = {}
|
785
|
+
do_recursive = false
|
786
|
+
ignore_regexp = nil
|
787
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
788
|
+
opts.banner = subcommand_usage("[local-file] [provider:/path]")
|
789
|
+
# opts.on('--filename FILEPATH', String, "Remote file path for the file or folder being uploaded, this is an alternative to [remote-file-path]." ) do |val|
|
790
|
+
# options['type'] = val
|
791
|
+
# end
|
792
|
+
opts.on( '-R', '--recursive', "Upload a directory and all of its files. This must be passed if [local-file] is a directory." ) do
|
793
|
+
do_recursive = true
|
794
|
+
end
|
795
|
+
opts.on('--ignore-files PATTERN', String, "Pattern of files to be ignored when uploading a directory." ) do |val|
|
796
|
+
ignore_regexp = /#{Regexp.escape(val)}/
|
797
|
+
end
|
798
|
+
opts.footer = "Upload a local file or folder to a storage provider. " +
|
799
|
+
"\nThe first argument [local-file] should be the path of a local file or directory." +
|
800
|
+
"\nThe second argument [provider:/path] should contain the name or id of the provider." +
|
801
|
+
"\nThe [:/path] component is optional and can be used to specify the destination of the uploaded file or folder." +
|
802
|
+
"\nThe default destination is the same name as the [local-file], under the root directory '/'. " +
|
803
|
+
"\nThis will overwrite any existing remote files that match the destination /path."
|
804
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run])
|
805
|
+
end
|
806
|
+
optparse.parse!(args)
|
807
|
+
|
808
|
+
if args.count != 2
|
809
|
+
print_error Morpheus::Terminal.angry_prompt
|
810
|
+
puts_error "#{command_name} upload expects 2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
|
811
|
+
return 1
|
812
|
+
end
|
813
|
+
# validate local file path
|
814
|
+
local_file_path = File.expand_path(args[0].squeeze('/'))
|
815
|
+
if local_file_path == "" || local_file_path == "/" || local_file_path == "."
|
816
|
+
print_error Morpheus::Terminal.angry_prompt
|
817
|
+
puts_error "#{command_name} missing argument: [local-file]\n#{optparse}"
|
818
|
+
return 1
|
819
|
+
end
|
820
|
+
if !File.exists?(local_file_path)
|
821
|
+
print_error Morpheus::Terminal.angry_prompt
|
822
|
+
puts_error "#{command_name} bad argument: [local-file]\nFile '#{local_file_path}' was not found.\n#{optparse}"
|
823
|
+
return 1
|
824
|
+
end
|
825
|
+
|
826
|
+
# validate provider:/path
|
827
|
+
storage_provider_id, remote_file_path = parse_storage_provider_id_and_file_path(args[1], args[2])
|
828
|
+
|
829
|
+
# if local_file_path.include?('../') # || options[:yes]
|
830
|
+
# raise_command_error "Sorry, you may not use relative paths in your local filepath."
|
831
|
+
# end
|
832
|
+
|
833
|
+
# validate provider name (or id)
|
834
|
+
if !storage_provider_id
|
835
|
+
print_error Morpheus::Terminal.angry_prompt
|
836
|
+
puts_error "#{command_name} missing argument: [provider]\n#{optparse}"
|
837
|
+
return 1
|
838
|
+
end
|
839
|
+
|
840
|
+
# strip leading slash of remote name
|
841
|
+
# if remote_file_path[0].chr == "/"
|
842
|
+
# remote_file_path = remote_file_path[1..-1]
|
843
|
+
# end
|
844
|
+
|
845
|
+
if remote_file_path.include?('./') # || options[:yes]
|
846
|
+
raise_command_error "Sorry, you may not use relative paths in your remote filepath."
|
847
|
+
end
|
848
|
+
|
849
|
+
# if !options[:yes]
|
850
|
+
scary_local_paths = ["/", "/root", "C:\\"]
|
851
|
+
if scary_local_paths.include?(local_file_path)
|
852
|
+
unless Morpheus::Cli::OptionTypes.confirm("Are you sure you want to upload all the files in local directory '#{local_file_path}' !?")
|
853
|
+
return 9, "aborted command"
|
854
|
+
end
|
855
|
+
end
|
856
|
+
# end
|
857
|
+
|
858
|
+
connect(options)
|
859
|
+
begin
|
860
|
+
storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
|
861
|
+
return 1 if storage_provider.nil?
|
862
|
+
|
863
|
+
# how many files we dealing with?
|
864
|
+
files_to_upload = []
|
865
|
+
if File.directory?(local_file_path)
|
866
|
+
# upload directory
|
867
|
+
if !do_recursive
|
868
|
+
print_error Morpheus::Terminal.angry_prompt
|
869
|
+
puts_error "bad argument: '#{local_file_path}' is a directory. Use -R or --recursive to upload a directory.\n#{optparse}"
|
870
|
+
return 1
|
871
|
+
end
|
872
|
+
found_files = Dir.glob("#{local_file_path}/**/*")
|
873
|
+
# note: api call for directories is not needed
|
874
|
+
found_files = found_files.select {|file| File.file?(file) }
|
875
|
+
if ignore_regexp
|
876
|
+
found_files = found_files.reject {|it| it =~ ignore_regexp}
|
877
|
+
end
|
878
|
+
files_to_upload = found_files
|
879
|
+
|
880
|
+
if files_to_upload.size == 0
|
881
|
+
print_error Morpheus::Terminal.angry_prompt
|
882
|
+
puts_error "bad argument: Local directory '#{local_file_path}' contains 0 files."
|
883
|
+
return 1
|
884
|
+
end
|
885
|
+
|
886
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to upload directory #{local_file_path} (#{files_to_upload.size} files) to #{storage_provider['name']}:#{remote_file_path}?")
|
887
|
+
return 9, "aborted command"
|
888
|
+
end
|
889
|
+
|
890
|
+
if !options[:yes]
|
891
|
+
if files_to_upload.size > 100
|
892
|
+
unless Morpheus::Cli::OptionTypes.confirm("Are you REALLY sure you want to upload #{files_to_upload.size} files ?")
|
893
|
+
return 9, "aborted command"
|
894
|
+
end
|
895
|
+
end
|
896
|
+
end
|
897
|
+
|
898
|
+
# local_dirname = File.dirname(local_file_path)
|
899
|
+
# local_basename = File.basename(local_file_path)
|
900
|
+
upload_file_list = []
|
901
|
+
files_to_upload.each do |file|
|
902
|
+
destination = file.sub(local_file_path, (remote_file_path || "")).squeeze('/')
|
903
|
+
upload_file_list << {file: file, destination: destination}
|
904
|
+
end
|
905
|
+
|
906
|
+
if options[:dry_run]
|
907
|
+
# print_h1 "DRY RUN"
|
908
|
+
print "\n",cyan, bold, "Uploading #{upload_file_list.size} Files...", reset, "\n"
|
909
|
+
upload_file_list.each do |obj|
|
910
|
+
file, destination = obj[:file], obj[:destination]
|
911
|
+
#print cyan,bold, " - Uploading #{file} to #{storage_provider_id}:#{destination} DRY RUN", reset, "\n"
|
912
|
+
print_dry_run @storage_providers_interface.dry.upload_file(storage_provider['id'], file, destination)
|
913
|
+
print "\n"
|
914
|
+
end
|
915
|
+
return 0
|
916
|
+
end
|
917
|
+
|
918
|
+
print "\n",cyan, bold, "Uploading #{upload_file_list.size} Files...", reset, "\n"
|
919
|
+
bad_upload_responses = []
|
920
|
+
upload_file_list.each do |obj|
|
921
|
+
file, destination = obj[:file], obj[:destination]
|
922
|
+
print cyan,bold, " - Uploading #{file} to #{storage_provider_id}:#{destination}", reset
|
923
|
+
upload_response = @storage_providers_interface.upload_file(storage_provider['id'], file, destination)
|
924
|
+
if upload_response['success']
|
925
|
+
print bold," #{green}SUCCESS#{reset}"
|
926
|
+
else
|
927
|
+
print bold," #{red}ERROR#{reset}"
|
928
|
+
if upload_response['msg']
|
929
|
+
bad_upload_responses << upload_response
|
930
|
+
print " #{upload_response['msg']}#{reset}"
|
931
|
+
end
|
932
|
+
end
|
933
|
+
print "\n"
|
934
|
+
end
|
935
|
+
if bad_upload_responses.size > 0
|
936
|
+
print cyan, bold, "Completed Upload of #{upload_file_list.size} Files. #{red}#{bad_upload_responses.size} Errors!", reset, "\n"
|
937
|
+
else
|
938
|
+
print cyan, bold, "Completed Upload of #{upload_file_list.size} Files!", reset, "\n"
|
939
|
+
end
|
940
|
+
|
941
|
+
else
|
942
|
+
|
943
|
+
# upload file
|
944
|
+
if !File.exists?(local_file_path) && !File.file?(local_file_path)
|
945
|
+
print_error Morpheus::Terminal.angry_prompt
|
946
|
+
puts_error "#{command_name} bad argument: [local-file]\nFile '#{local_file_path}' was not found.\n#{optparse}"
|
947
|
+
return 1
|
948
|
+
end
|
949
|
+
|
950
|
+
# local_dirname = File.dirname(local_file_path)
|
951
|
+
# local_basename = File.basename(local_file_path)
|
952
|
+
|
953
|
+
file = local_file_path
|
954
|
+
destination = File.basename(file)
|
955
|
+
if remote_file_path[-1].chr == "/"
|
956
|
+
# work like `cp`, and place into the directory
|
957
|
+
destination = remote_file_path + File.basename(file)
|
958
|
+
elsif remote_file_path
|
959
|
+
# renaming file
|
960
|
+
destination = remote_file_path
|
961
|
+
end
|
962
|
+
destination = destination.squeeze('/')
|
963
|
+
|
964
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to upload #{local_file_path} to #{storage_provider['name']}:#{destination}?")
|
965
|
+
return 9, "aborted command"
|
966
|
+
end
|
967
|
+
|
968
|
+
if options[:dry_run]
|
969
|
+
#print cyan,bold, " - Uploading #{file} to #{storage_provider_id}:#{destination} DRY RUN", reset, "\n"
|
970
|
+
# print_h1 "DRY RUN"
|
971
|
+
print_dry_run @storage_providers_interface.dry.upload_file(storage_provider['id'], file, destination)
|
972
|
+
print "\n"
|
973
|
+
return 0
|
974
|
+
end
|
975
|
+
|
976
|
+
print cyan,bold, " - Uploading #{file} to #{storage_provider_id}:#{destination}", reset
|
977
|
+
upload_response = @storage_providers_interface.upload_file(storage_provider['id'], file, destination)
|
978
|
+
if upload_response['success']
|
979
|
+
print bold," #{green}Success#{reset}"
|
980
|
+
else
|
981
|
+
print bold," #{red}Error#{reset}"
|
982
|
+
if upload_response['msg']
|
983
|
+
print " #{upload_response['msg']}#{reset}"
|
984
|
+
end
|
985
|
+
end
|
986
|
+
print "\n"
|
987
|
+
|
988
|
+
end
|
989
|
+
#print cyan, bold, "Upload Complete!", reset, "\n"
|
990
|
+
|
991
|
+
return 0
|
992
|
+
rescue RestClient::Exception => e
|
993
|
+
print_rest_exception(e, options)
|
994
|
+
return 1
|
995
|
+
end
|
996
|
+
end
|
997
|
+
|
998
|
+
def download_file(args)
|
999
|
+
full_command_string = "#{command_name} download #{args.join(' ')}".strip
|
1000
|
+
options = {}
|
1001
|
+
outfile = nil
|
1002
|
+
do_overwrite = false
|
1003
|
+
do_mkdir = false
|
1004
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1005
|
+
opts.banner = subcommand_usage("[provider:/path] [local-file]")
|
1006
|
+
opts.on( '-f', '--force', "Overwrite existing [local-file] if it exists." ) do
|
1007
|
+
do_overwrite = true
|
1008
|
+
# do_mkdir = true
|
1009
|
+
end
|
1010
|
+
opts.on( '-p', '--mkdir', "Create missing directories for [local-file] if they do not exist." ) do
|
1011
|
+
do_mkdir = true
|
1012
|
+
end
|
1013
|
+
build_common_options(opts, options, [:dry_run, :quiet])
|
1014
|
+
opts.footer = "Download a file or directory.\n" +
|
1015
|
+
"[provider:/path] is required. This is the name or id of the provider and /path the file or folder to be downloaded.\n" +
|
1016
|
+
"[local-file] is required. This is the full local filepath for the downloaded file.\n" +
|
1017
|
+
"Directories will be downloaded as a .zip file, so you'll want to specify a [local-file] with a .zip extension."
|
1018
|
+
end
|
1019
|
+
optparse.parse!(args)
|
1020
|
+
if args.count < 2 || args.count > 3
|
1021
|
+
print_error Morpheus::Terminal.angry_prompt
|
1022
|
+
puts_error "#{command_name} download expects 2-3 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
|
1023
|
+
return 1
|
1024
|
+
end
|
1025
|
+
storage_provider_id = nil
|
1026
|
+
local = nil
|
1027
|
+
outfile = nil
|
1028
|
+
if args.count == 3
|
1029
|
+
storage_provider_id, file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
|
1030
|
+
outfile = args[2]
|
1031
|
+
else
|
1032
|
+
storage_provider_id, file_path = parse_storage_provider_id_and_file_path(args[0])
|
1033
|
+
outfile = args[1]
|
1034
|
+
end
|
1035
|
+
connect(options)
|
1036
|
+
begin
|
1037
|
+
storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
|
1038
|
+
return 1 if storage_provider.nil?
|
1039
|
+
|
1040
|
+
file_path = file_path.squeeze('/')
|
1041
|
+
outfile = File.expand_path(outfile)
|
1042
|
+
if Dir.exists?(outfile)
|
1043
|
+
outfile = File.join(outfile, File.basename(file_path))
|
1044
|
+
end
|
1045
|
+
if Dir.exists?(outfile)
|
1046
|
+
print_red_alert "[local-file] is invalid. It is the name of an existing directory: #{outfile}"
|
1047
|
+
return 1
|
1048
|
+
end
|
1049
|
+
destination_dir = File.dirname(outfile)
|
1050
|
+
if !Dir.exists?(destination_dir)
|
1051
|
+
if do_mkdir
|
1052
|
+
print cyan,"Creating local directory #{destination_dir}",reset,"\n"
|
1053
|
+
FileUtils.mkdir_p(destination_dir)
|
1054
|
+
else
|
1055
|
+
print_red_alert "[local-file] is invalid. Directory not found: #{destination_dir}"
|
1056
|
+
return 1
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
if File.exists?(outfile)
|
1060
|
+
if do_overwrite
|
1061
|
+
# uhh need to be careful wih the passed filepath here..
|
1062
|
+
# don't delete, just overwrite.
|
1063
|
+
# File.delete(outfile)
|
1064
|
+
else
|
1065
|
+
print_error Morpheus::Terminal.angry_prompt
|
1066
|
+
puts_error "[local-file] is invalid. File already exists: #{outfile}", "Use -f to overwrite the existing file."
|
1067
|
+
# puts_error optparse
|
1068
|
+
return 1
|
1069
|
+
end
|
1070
|
+
end
|
1071
|
+
begin
|
1072
|
+
if options[:dry_run]
|
1073
|
+
print_dry_run @storage_providers_interface.dry.download_file_chunked(storage_provider['id'], file_path, outfile), full_command_string
|
1074
|
+
return 0
|
1075
|
+
end
|
1076
|
+
if !options[:quiet]
|
1077
|
+
print cyan + "Downloading archive file #{storage_provider['name']}:#{file_path} to #{outfile} ... "
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
http_response = @storage_providers_interface.download_file_chunked(storage_provider['id'], file_path, outfile)
|
1081
|
+
|
1082
|
+
# FileUtils.chmod(0600, outfile)
|
1083
|
+
success = http_response.code.to_i == 200
|
1084
|
+
if success
|
1085
|
+
if !options[:quiet]
|
1086
|
+
print green + "SUCCESS" + reset + "\n"
|
1087
|
+
end
|
1088
|
+
return 0
|
1089
|
+
else
|
1090
|
+
if !options[:quiet]
|
1091
|
+
print red + "ERROR" + reset + " HTTP #{http_response.code}" + "\n"
|
1092
|
+
end
|
1093
|
+
# F it, just remove a bad result
|
1094
|
+
if File.exists?(outfile) && File.file?(outfile)
|
1095
|
+
Morpheus::Logging::DarkPrinter.puts "Deleting bad file download: #{outfile}" if Morpheus::Logging.debug?
|
1096
|
+
File.delete(outfile)
|
1097
|
+
end
|
1098
|
+
if options[:debug]
|
1099
|
+
puts_error http_response.inspect
|
1100
|
+
end
|
1101
|
+
return 1
|
1102
|
+
end
|
1103
|
+
rescue RestClient::Exception => e
|
1104
|
+
# this is not reached
|
1105
|
+
if e.response && e.response.code == 404
|
1106
|
+
print_red_alert "Storage file not found by path #{file_path}"
|
1107
|
+
return nil
|
1108
|
+
else
|
1109
|
+
raise e
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
rescue RestClient::Exception => e
|
1113
|
+
print_rest_exception(e, options)
|
1114
|
+
return 1
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
def read_file(args)
|
1120
|
+
full_command_string = "#{command_name} read #{args.join(' ')}".strip
|
1121
|
+
options = {}
|
1122
|
+
outfile = nil
|
1123
|
+
do_overwrite = false
|
1124
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1125
|
+
opts.banner = subcommand_usage("[provider:/path]")
|
1126
|
+
build_common_options(opts, options, [:dry_run])
|
1127
|
+
opts.footer = "Print the contents of a storage file.\n" +
|
1128
|
+
"[provider:/path] is required. This is the name or id of the provider and /path the file or folder to be downloaded.\n" +
|
1129
|
+
"This confirmation can be skipped with the -y option."
|
1130
|
+
end
|
1131
|
+
optparse.parse!(args)
|
1132
|
+
if args.count < 1 || args.count > 2
|
1133
|
+
print_error Morpheus::Terminal.angry_prompt
|
1134
|
+
puts_error "#{command_name} read expects 1-2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
|
1135
|
+
return 1
|
1136
|
+
end
|
1137
|
+
connect(options)
|
1138
|
+
begin
|
1139
|
+
storage_provider_id, file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
|
1140
|
+
storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
|
1141
|
+
return 1 if storage_provider.nil?
|
1142
|
+
|
1143
|
+
file_path = file_path.squeeze('/')
|
1144
|
+
|
1145
|
+
if options[:dry_run]
|
1146
|
+
print_dry_run @storage_providers_interface.dry.download_file(storage_provider['id'], file_path), full_command_string
|
1147
|
+
return 1
|
1148
|
+
end
|
1149
|
+
file_response = @storage_providers_interface.download_file(storage_provider['id'], file_path)
|
1150
|
+
puts file_response.body.to_s
|
1151
|
+
return 0
|
1152
|
+
rescue RestClient::Exception => e
|
1153
|
+
print_rest_exception(e, options)
|
1154
|
+
return 1
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
def remove_file(args)
|
1160
|
+
options = {}
|
1161
|
+
query_params = {}
|
1162
|
+
do_recursive = false
|
1163
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1164
|
+
opts.banner = subcommand_usage("[provider:/path]")
|
1165
|
+
opts.on( '-R', '--recursive', "Delete a directory and all of its files. This must be passed if specifying a directory." ) do
|
1166
|
+
do_recursive = true
|
1167
|
+
end
|
1168
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run])
|
1169
|
+
opts.footer = "Delete a storage file or directory."
|
1170
|
+
end
|
1171
|
+
optparse.parse!(args)
|
1172
|
+
# consider only allowing args.count == 1 here in the format [provider:/path]
|
1173
|
+
if args.count < 1 || args.count > 2
|
1174
|
+
print_error Morpheus::Terminal.angry_prompt
|
1175
|
+
puts_error "#{command_name} remove-file expects 1-2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
|
1176
|
+
return 1
|
1177
|
+
end
|
1178
|
+
storage_provider_id, file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
|
1179
|
+
connect(options)
|
1180
|
+
begin
|
1181
|
+
|
1182
|
+
storage_file = find_storage_file_by_bucket_and_path(storage_provider_id, file_path)
|
1183
|
+
return 1 if storage_file.nil?
|
1184
|
+
if storage_file['isDirectory']
|
1185
|
+
if !do_recursive
|
1186
|
+
print_error Morpheus::Terminal.angry_prompt
|
1187
|
+
puts_error "bad argument: '#{file_path}' is a directory. Use -R or --recursive to delete a directory.\n#{optparse}"
|
1188
|
+
return 1
|
1189
|
+
end
|
1190
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the directory: #{args[0]}?")
|
1191
|
+
return 9, "aborted command"
|
1192
|
+
end
|
1193
|
+
else
|
1194
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the file: #{args[0]}?")
|
1195
|
+
return 9, "aborted command"
|
1196
|
+
end
|
1197
|
+
end
|
1198
|
+
|
1199
|
+
if options[:dry_run]
|
1200
|
+
print_dry_run @storage_files_interface.dry.destroy(storage_file['id'], query_params)
|
1201
|
+
return 0
|
1202
|
+
end
|
1203
|
+
json_response = @storage_files_interface.destroy(storage_file['id'], query_params)
|
1204
|
+
if options[:json]
|
1205
|
+
print JSON.pretty_generate(json_response)
|
1206
|
+
print "\n"
|
1207
|
+
else
|
1208
|
+
print_green_success "Removed file #{args[0]}"
|
1209
|
+
end
|
1210
|
+
return 0
|
1211
|
+
|
1212
|
+
rescue RestClient::Exception => e
|
1213
|
+
print_rest_exception(e, options)
|
1214
|
+
return 1
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
end
|
1218
|
+
|
507
1219
|
private
|
508
1220
|
|
509
1221
|
|
@@ -573,4 +1285,75 @@ class Morpheus::Cli::StorageProvidersCommand
|
|
573
1285
|
storage_provider['providerType'].to_s.capitalize
|
574
1286
|
end
|
575
1287
|
|
1288
|
+
# parse_storage_provider_id_and_file_path() provides flexible argument formats for provider and path
|
1289
|
+
# it looks for [provider:/path] or [provider] [path]
|
1290
|
+
# @param delim [String] Default is a comma and any surrounding white space.
|
1291
|
+
# @return [Array] 2 elements, provider name (or id) and the file path.
|
1292
|
+
# The default file path is "/".
|
1293
|
+
# Examples:
|
1294
|
+
# parse_storage_provider_id_and_file_path("test") == ["test", "/"]
|
1295
|
+
# parse_storage_provider_id_and_file_path("test:/global.cfg") == ["test", "/global.cfg"]
|
1296
|
+
# parse_storage_provider_id_and_file_path("test:/node1/node.cfg") == ["test", "/node1/node.cfg"]
|
1297
|
+
# parse_storage_provider_id_and_file_path("test/node1/node.cfg") == ["test", "/node1/node.cfg"]
|
1298
|
+
# parse_storage_provider_id_and_file_path("test", "node1/node.cfg") == ["test", "/node1/node.cfg"]
|
1299
|
+
#
|
1300
|
+
def parse_storage_provider_id_and_file_path(*args)
|
1301
|
+
if args.size < 1 || args.size > 2
|
1302
|
+
return nil, nil
|
1303
|
+
end
|
1304
|
+
if !args[0]
|
1305
|
+
return nil, nil
|
1306
|
+
end
|
1307
|
+
full_path = args[0].to_s
|
1308
|
+
if args[1]
|
1309
|
+
if full_path.include?(":")
|
1310
|
+
full_path = "#{full_path}/#{args[1]}"
|
1311
|
+
else
|
1312
|
+
full_path = "#{full_path}:#{args[1]}"
|
1313
|
+
end
|
1314
|
+
end
|
1315
|
+
# ok fine, allow just id/filePath, without a colon.
|
1316
|
+
if !full_path.include?(":") && full_path.include?("/")
|
1317
|
+
path_elements = full_path.split("/")
|
1318
|
+
full_path = path_elements[0] + ":" + path_elements[1..-1].join("/")
|
1319
|
+
end
|
1320
|
+
uri_elements = full_path.split(":")
|
1321
|
+
storage_provider_id = uri_elements[0]
|
1322
|
+
file_path = uri_elements[1..-1].join("/") # [1]
|
1323
|
+
file_path = "/#{file_path}".squeeze("/")
|
1324
|
+
return storage_provider_id, file_path
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
def format_filename(filename, options={})
|
1328
|
+
if options[:fullTree]
|
1329
|
+
filename.to_s
|
1330
|
+
else
|
1331
|
+
filename.to_s.split('/').last()
|
1332
|
+
end
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
def print_storage_files_table(storage_files, options={})
|
1336
|
+
table_color = options[:color] || cyan
|
1337
|
+
rows = storage_files.collect do |storage_file|
|
1338
|
+
{
|
1339
|
+
id: storage_file['id'],
|
1340
|
+
name: format_filename(storage_file['name'], options),
|
1341
|
+
type: storage_file['isDirectory'] ? 'directory' : (storage_file['contentType']),
|
1342
|
+
size: storage_file['isDirectory'] ? '' : format_bytes(storage_file['contentLength']),
|
1343
|
+
lastUpdated: format_local_dt(storage_file['dateModified'])
|
1344
|
+
}
|
1345
|
+
end
|
1346
|
+
columns = [
|
1347
|
+
# :id,
|
1348
|
+
{:name => {:display_name => "File".upcase} },
|
1349
|
+
:type,
|
1350
|
+
:size,
|
1351
|
+
# {:dateCreated => {:display_name => "Date Created"} },
|
1352
|
+
{:lastUpdated => {:display_name => "Last Modified".upcase} }
|
1353
|
+
]
|
1354
|
+
print table_color
|
1355
|
+
print as_pretty_table(rows, columns, options)
|
1356
|
+
print reset
|
1357
|
+
end
|
1358
|
+
|
576
1359
|
end
|