morpheus-cli 3.1.1.2 → 3.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec4341bf055129fa386b30d7ca8345a3eab0ed87
4
- data.tar.gz: 12e9c3616229ed6959ebe7743eaeb7d3f0ce27ca
3
+ metadata.gz: 41e5e60229896649507f3df02222124865c803ff
4
+ data.tar.gz: c4eef70518c898cf317d99c3148bbbb0b57af624
5
5
  SHA512:
6
- metadata.gz: 8de0e296034a0f945d8aa7b8ff5280fe139691f89c727f721c96e23c1c65b85f717a0f4b151f02c15521e524cd872fe1d02679a2e1899dfa94ad91271efce4aa
7
- data.tar.gz: fd69527c0a682861a750d6864a80d7ea44b3231521b33399086475ea69e9fce2194e3f4ae53be585aac27ca41782a532a990bd9be00e4d29b68e23463114bfe0
6
+ metadata.gz: 673e4e27f7a0dc245ead08bb40bf4f7ab67c5a73c4ac81d283c29659b66fe1a7b932c6bc62ea1e417ee3b4317e34d6117c98dc6d3958e67fab0ef292e45d3d38
7
+ data.tar.gz: 74b88bc851e272d82a46f2f8341b335c74cecdc5c6ada550bd8b973bd4a2fb6a0aa3dfb83a7092e1c4a138457f1ef874b32a4d1c58e94ae06fe0bc854d8385bd
@@ -243,16 +243,8 @@ class Morpheus::APIClient
243
243
  Morpheus::ImageBuilderInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
244
244
  end
245
245
 
246
- # def image_builds
247
- # Morpheus::ImageBuildsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
248
- # end
249
-
250
- # def preseed_scripts
251
- # Morpheus::PreseedScriptsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
252
- # end
253
-
254
- # def boot_scripts
255
- # Morpheus::BootScriptsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
256
- # end
246
+ def storage_providers
247
+ Morpheus::StorageProvidersInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
248
+ end
257
249
 
258
250
  end
@@ -0,0 +1,47 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::StorageProvidersInterface < Morpheus::APIClient
4
+ def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
5
+ @access_token = access_token
6
+ @refresh_token = refresh_token
7
+ @base_url = base_url
8
+ @expires_at = expires_at
9
+ end
10
+
11
+ def get(id, params={})
12
+ raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
13
+ url = "#{@base_url}/api/storage/providers/#{id}"
14
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
15
+ opts = {method: :get, url: url, headers: headers}
16
+ execute(opts)
17
+ end
18
+
19
+ def list(params={})
20
+ url = "#{@base_url}/api/storage/providers"
21
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
22
+ opts = {method: :get, url: url, headers: headers}
23
+ execute(opts)
24
+ end
25
+
26
+ def create(payload)
27
+ url = "#{@base_url}/api/storage/providers"
28
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
29
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
30
+ execute(opts)
31
+ end
32
+
33
+ def update(id, payload)
34
+ url = "#{@base_url}/api/storage/providers/#{id}"
35
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
36
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
37
+ execute(opts)
38
+ end
39
+
40
+ def destroy(id, params={})
41
+ url = "#{@base_url}/api/storage/providers/#{id}"
42
+ headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
43
+ opts = {method: :delete, url: url, timeout: 30, headers: headers}
44
+ execute(opts)
45
+ end
46
+
47
+ end
data/lib/morpheus/cli.rb CHANGED
@@ -106,6 +106,7 @@ module Morpheus
106
106
  load 'morpheus/cli/preseed_scripts_command.rb'
107
107
  load 'morpheus/cli/boot_scripts_command.rb'
108
108
  load 'morpheus/cli/archives_command.rb'
109
+ load 'morpheus/cli/storage_providers_command.rb'
109
110
 
110
111
  # nice to have commands
111
112
  load 'morpheus/cli/curl_command.rb'
@@ -560,12 +560,13 @@ class Morpheus::Cli::ArchivesCommand
560
560
  end
561
561
 
562
562
  if options[:dry_run]
563
- print_h1 "DRY RUN"
563
+ # print_h1 "DRY RUN"
564
564
  print "\n",cyan, bold, "Uploading #{upload_file_list.size} Files...", reset, "\n"
565
565
  upload_file_list.each do |obj|
566
566
  file, destination = obj[:file], obj[:destination]
567
- #print_dry_run @archive_buckets_interface.dry.upload_file(bucket_id, file, destination)
568
- print cyan,bold, " - Uploading #{file} to #{bucket_id}:#{destination}", reset, "\n"
567
+ #print cyan,bold, " - Uploading #{file} to #{bucket_id}:#{destination} DRY RUN", reset, "\n"
568
+ print_dry_run @archive_buckets_interface.dry.upload_file(bucket_id, file, destination)
569
+ print "\n"
569
570
  end
570
571
  return 0
571
572
  end
@@ -621,9 +622,10 @@ class Morpheus::Cli::ArchivesCommand
621
622
  end
622
623
 
623
624
  if options[:dry_run]
624
- print_h1 "DRY RUN"
625
- #print_dry_run @archive_buckets_interface.dry.upload_file(bucket_id, file, destination)
626
- print cyan,bold, " - Uploading #{file} to #{bucket_id}:#{destination} SKIPPED", reset, "\n"
625
+ #print cyan,bold, " - Uploading #{file} to #{bucket_id}:#{destination} DRY RUN", reset, "\n"
626
+ # print_h1 "DRY RUN"
627
+ print_dry_run @archive_buckets_interface.dry.upload_file(bucket_id, file, destination)
628
+ print "\n"
627
629
  return 0
628
630
  end
629
631
 
@@ -123,9 +123,25 @@ module Morpheus::Cli::PrintHelper
123
123
  end
124
124
  end
125
125
  print "\n"
126
- print "JSON: ", "\n"
127
- print reset
128
- print JSON.pretty_generate(payload)
126
+ if opts[:headers] && opts[:headers]['Content-Type'] == 'application/json'
127
+ print "JSON: ", "\n"
128
+ print reset
129
+ print JSON.pretty_generate(payload)
130
+ else
131
+ print "Content-Type: #{opts[:headers]['Content-Type']}", "\n"
132
+ #print "BODY: ", "\n"
133
+ print reset
134
+ if payload.is_a?(File)
135
+ # pretty_size = Filesize.from("#{payload.size} B").pretty.strip
136
+ pretty_size = "#{payload.size} B"
137
+ # print "File: #{payload.path} (#{payload.size} bytes)"
138
+ print "File: #{payload.path} (#{pretty_size})"
139
+ elsif payload.is_a?(String)
140
+ print payload
141
+ else
142
+ print payload.inspect
143
+ end
144
+ end
129
145
  end
130
146
  print "\n"
131
147
  print reset
@@ -0,0 +1,586 @@
1
+ require 'rest_client'
2
+ require 'optparse'
3
+ require 'filesize'
4
+ require 'table_print'
5
+ require 'morpheus/cli/cli_command'
6
+ require 'morpheus/cli/mixins/infrastructure_helper'
7
+
8
+ class Morpheus::Cli::StorageProvidersCommand
9
+ include Morpheus::Cli::CliCommand
10
+ include Morpheus::Cli::InfrastructureHelper
11
+
12
+ set_command_name :'storage-providers'
13
+
14
+ register_subcommands :list, :get, :add, :update, :remove
15
+
16
+ # set_default_subcommand :list
17
+
18
+ def initialize()
19
+ # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
20
+ end
21
+
22
+ def connect(opts)
23
+ @api_client = establish_remote_appliance_connection(opts)
24
+ @storage_providers_interface = @api_client.storage_providers
25
+ @clouds_interface = @api_client.clouds
26
+ @options_interface = @api_client.options
27
+ end
28
+
29
+ def handle(args)
30
+ handle_subcommand(args)
31
+ end
32
+
33
+ def list(args)
34
+ options = {}
35
+ params = {}
36
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
37
+ opts.banner = subcommand_usage()
38
+ build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
39
+ opts.footer = "List storage providers."
40
+ end
41
+ optparse.parse!(args)
42
+ connect(options)
43
+ begin
44
+ [:phrase, :offset, :max, :sort, :direction].each do |k|
45
+ params[k] = options[k] unless options[k].nil?
46
+ end
47
+ if options[:dry_run]
48
+ print_dry_run @storage_providers_interface.dry.list(params)
49
+ return
50
+ end
51
+ json_response = @storage_providers_interface.list(params)
52
+ storage_providers = json_response["storageProviders"]
53
+ if options[:include_fields]
54
+ json_response = {"storageProviders" => filter_data(storage_providers, options[:include_fields]) }
55
+ end
56
+ if options[:json]
57
+ puts as_json(json_response, options)
58
+ return 0
59
+ elsif options[:yaml]
60
+ puts as_yaml(json_response, options)
61
+ return 0
62
+ elsif options[:csv]
63
+ puts records_as_csv(storage_providers, options)
64
+ return 0
65
+ end
66
+ title = "Morpheus Storage Providers"
67
+ subtitles = []
68
+ if params[:phrase]
69
+ subtitles << "Search: #{params[:phrase]}".strip
70
+ end
71
+ print_h1 title, subtitles
72
+ if storage_providers.empty?
73
+ print cyan,"No storage providers found.",reset,"\n"
74
+ else
75
+ rows = storage_providers.collect {|storage_provider|
76
+ row = {
77
+ id: storage_provider['id'],
78
+ name: storage_provider['name'],
79
+ provider: format_storage_provider_type(storage_provider),
80
+ bucket: format_bucket_name(storage_provider),
81
+ backups: storage_provider['defaultBackupTarget'] ? 'Yes' : 'No',
82
+ deployments: storage_provider['defaultDeploymentTarget'] ? 'Yes' : 'No',
83
+ virtualImages: storage_provider['defaultVirtualImageTarget'] ? 'Yes' : 'No',
84
+ }
85
+ row
86
+ }
87
+ columns = [:id, :name, {:provider => {:display_name => "Provider Type".upcase} }, {:bucket => {:display_name => "Bucket Name".upcase} }, :backups, :deployments]
88
+ if options[:include_fields]
89
+ columns = options[:include_fields]
90
+ rows = storage_providers
91
+ end
92
+ print cyan
93
+ print as_pretty_table(rows, columns, options)
94
+ print reset
95
+ print_results_pagination(json_response, {:label => "storage provider", :n_label => "storage providers"})
96
+ end
97
+ print reset,"\n"
98
+ return 0
99
+ rescue RestClient::Exception => e
100
+ print_rest_exception(e, options)
101
+ exit 1
102
+ end
103
+ end
104
+
105
+ def get(args)
106
+ options = {}
107
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
108
+ opts.banner = subcommand_usage("[storage-provider]")
109
+ build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
110
+ opts.footer = "Get details about a storage provider." + "\n" +
111
+ "[storage-provider] is required. This is the name or id of a storage provider."
112
+ end
113
+ optparse.parse!(args)
114
+ if args.count != 1
115
+ print_error Morpheus::Terminal.angry_prompt
116
+ puts_error "#{command_name} missing argument: [storage-provider]\n#{optparse}"
117
+ return 1
118
+ end
119
+ connect(options)
120
+ begin
121
+ if options[:dry_run]
122
+ if args[0].to_s =~ /\A\d{1,}\Z/
123
+ print_dry_run @storage_providers_interface.dry.get(args[0].to_i)
124
+ else
125
+ print_dry_run @storage_providers_interface.dry.list({name:args[0]})
126
+ end
127
+ return
128
+ end
129
+ storage_provider = find_storage_provider_by_name_or_id(args[0])
130
+ return 1 if storage_provider.nil?
131
+ json_response = {'storageProvider' => storage_provider} # skip redundant request
132
+ # json_response = @storage_providers_interface.get(storage_provider['id'])
133
+ storage_provider = json_response['storageProvider']
134
+ if options[:include_fields]
135
+ json_response = {'storageProvider' => filter_data(storage_provider, options[:include_fields]) }
136
+ end
137
+ if options[:json]
138
+ puts as_json(json_response, options)
139
+ return 0
140
+ elsif options[:yaml]
141
+ puts as_yaml(json_response, options)
142
+ return 0
143
+ elsif options[:csv]
144
+ puts records_as_csv([storage_provider], options)
145
+ return 0
146
+ end
147
+ print_h1 "Storage Provider Details"
148
+ print cyan
149
+ description_cols = {
150
+ "ID" => 'id',
151
+ "Name" => lambda {|it| it['name'] },
152
+ "Provider Type" => lambda {|it| format_storage_provider_type(it) },
153
+ "Bucket Name" => lambda {|it| format_bucket_name(it) },
154
+ "Default Backup Target" => lambda {|it| it['defaultBackupTarget'] ? 'Yes' : 'No' },
155
+ "Default Deployment Target" => lambda {|it| it['defaultDeploymentTarget'] ? 'Yes' : 'No' },
156
+ "Default Virtual Image Store" => lambda {|it| it['defaultVirtualImageTarget'] ? 'Yes' : 'No' },
157
+ "Archive Snapshots" => lambda {|it| it['copyToStore'] ? 'Yes' : 'No' }
158
+ }
159
+ print_description_list(description_cols, storage_provider)
160
+ print reset,"\n"
161
+ return 0
162
+ rescue RestClient::Exception => e
163
+ print_rest_exception(e, options)
164
+ return 1
165
+ end
166
+ end
167
+
168
+ def add(args)
169
+ options = {}
170
+ ip_range_list = nil
171
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
172
+ opts.banner = subcommand_usage()
173
+ opts.on('--name VALUE', String, "Name for this storage provider") do |val|
174
+ options['name'] = val
175
+ end
176
+ opts.on('--type code', String, "Storage Provider Type Code") do |val|
177
+ options['providerType'] = val
178
+ end
179
+ opts.on('--bucket-name VALUE', String, "Bucket Name") do |val|
180
+ options['bucketName'] = val
181
+ end
182
+ opts.on('--default-backup-target [on|off]', String, "Default Backup Target") do |val|
183
+ options['defaultBackupTarget'] = val.to_s == 'on' || val.to_s == 'true'
184
+ end
185
+ opts.on('--default-deployment-target [on|off]', String, "Default Deployment Target") do |val|
186
+ options['defaultDeploymentTarget'] = val.to_s == 'on' || val.to_s == 'true'
187
+ end
188
+ opts.on('--default-virtual-image-target [on|off]', String, "Default Virtual Image Store") do |val|
189
+ options['defaultVirtualImageTarget'] = val.to_s == 'on' || val.to_s == 'true'
190
+ end
191
+ opts.on('--copy-to-store [on|off]', String, "Archive Snapshots") do |val|
192
+ options['copyToStore'] = val.to_s == 'on' || val.to_s == 'true'
193
+ end
194
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
195
+ opts.footer = "Create a new storage provider." + "\n" +
196
+ "[name] is required and can be passed as --name instead."
197
+ end
198
+ optparse.parse!(args)
199
+ if args.count > 1
200
+ print_error Morpheus::Terminal.angry_prompt
201
+ puts_error "wrong number of arguments, expected 0-1 and got #{args.count}\n#{optparse}"
202
+ return 1
203
+ end
204
+ connect(options)
205
+ begin
206
+ # merge -O options into normally parsed options
207
+ options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
208
+
209
+ # support [name] as first argument
210
+ if args[0]
211
+ options['name'] = args[0]
212
+ end
213
+
214
+ # construct payload
215
+ payload = nil
216
+ if options[:payload]
217
+ payload = options[:payload]
218
+ else
219
+ # prompt for storage provider options
220
+ payload = {
221
+ 'storageProvider' => {
222
+ # 'config' => {}
223
+ }
224
+ }
225
+
226
+ # allow arbitrary -O options
227
+ payload['storageProvider'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
228
+
229
+ # Name
230
+ if options['name']
231
+ payload['storageProvider']['name'] = options['name']
232
+ else
233
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this storage provider.'}], options)
234
+ payload['storageProvider']['name'] = v_prompt['name']
235
+ end
236
+
237
+ # Storage Provider Type
238
+ storage_provider_type_code = nil
239
+ if options['type']
240
+ storage_provider_type_code = options['type'].to_s
241
+ elsif options['providerType']
242
+ storage_provider_type_code = options['providerType'].to_s
243
+ else
244
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'providerType', 'fieldLabel' => 'Provider Type', 'type' => 'select', 'selectOptions' => get_storage_provider_types(), 'required' => true, 'description' => 'Choose a storage provider type.'}], options, @api_client, {})
245
+ storage_provider_type_code = v_prompt['providerType'] unless v_prompt['providerType'].nil?
246
+ end
247
+ payload['storageProvider']['providerType'] = storage_provider_type_code
248
+
249
+ # Provider Type Specific Options
250
+ provider_type_option_types = nil
251
+ if storage_provider_type_code == 's3'
252
+ # print_h2 "Amazon S3 Options"
253
+ provider_type_option_types = [
254
+ {'fieldContext' => 'config', 'fieldName' => 'accessKey', 'fieldLabel' => 'Access Key', 'type' => 'text', 'required' => true, 'description' => ''},
255
+ {'fieldContext' => 'config', 'fieldName' => 'secretKey', 'fieldLabel' => 'Secret Key', 'type' => 'password', 'required' => true, 'description' => ''},
256
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
257
+ {'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.'},
258
+ ]
259
+ elsif storage_provider_type_code == 'azure'
260
+ # print_h2 "Azure Options"
261
+ provider_type_option_types = [
262
+ {'fieldContext' => 'config', 'fieldName' => 'storageAccount', 'fieldLabel' => 'Storage Account', 'type' => 'text', 'required' => true, 'description' => ''},
263
+ {'fieldContext' => 'config', 'fieldName' => 'storageKey', 'fieldLabel' => 'Storage Key', 'type' => 'password', 'required' => true, 'description' => ''},
264
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''}
265
+ ]
266
+ elsif storage_provider_type_code == 'cifs'
267
+ # print_h2 "CIFS Options"
268
+ provider_type_option_types = [
269
+ {'fieldContext' => 'config', 'fieldName' => 'host', 'fieldLabel' => 'Host', 'type' => 'text', 'required' => true, 'description' => ''},
270
+ {'fieldContext' => 'config', 'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'description' => ''},
271
+ {'fieldContext' => 'config', 'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'description' => ''},
272
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''}
273
+ ]
274
+ elsif storage_provider_type_code == 'local'
275
+ # print_h2 "Local Storage Options"
276
+ provider_type_option_types = [
277
+ {'fieldContext' => 'config', 'fieldName' => 'basePath', 'fieldLabel' => 'Storage Path', 'type' => 'text', 'required' => true, 'description' => ''},
278
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'hidden', 'required' => true, 'description' => '', 'defaultValue' => '.'}
279
+ ]
280
+ elsif storage_provider_type_code == 'nfs'
281
+ # print_h2 "NFSv3 Options"
282
+ provider_type_option_types = [
283
+ {'fieldContext' => 'config', 'fieldName' => 'host', 'fieldLabel' => 'Host', 'type' => 'text', 'required' => true, 'description' => ''},
284
+ {'fieldContext' => 'config', 'fieldName' => 'exportFolder', 'fieldLabel' => 'Export Folder', 'type' => 'text', 'required' => false, 'description' => ''},
285
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'hidden', 'required' => true, 'description' => '', 'defaultValue' => '/'}
286
+ ]
287
+ elsif storage_provider_type_code == 'openstack'
288
+ # print_h2 "Openstack Swift Options"
289
+ provider_type_option_types = [
290
+ {'fieldContext' => 'config', 'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'description' => ''},
291
+ {'fieldContext' => 'config', 'fieldName' => 'apiKey', 'fieldLabel' => 'API Key', 'type' => 'password', 'required' => true, 'description' => ''},
292
+ {'fieldContext' => 'config', 'fieldName' => 'region', 'fieldLabel' => 'Region', 'type' => 'text', 'required' => true, 'description' => ''},
293
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
294
+ {'fieldContext' => 'config', 'fieldName' => 'identityUrl', 'fieldLabel' => 'Identity URL', 'type' => 'text', 'required' => true, 'description' => ''},
295
+ ]
296
+ elsif storage_provider_type_code == 'rackspace'
297
+ # print_h2 "Rackspace CDN Options"
298
+ provider_type_option_types = [
299
+ {'fieldContext' => 'config', 'fieldName' => 'accessKey', 'fieldLabel' => 'Access Key', 'type' => 'text', 'required' => true, 'description' => ''},
300
+ {'fieldContext' => 'config', 'fieldName' => 'secretKey', 'fieldLabel' => 'Secret Key', 'type' => 'password', 'required' => true, 'description' => ''},
301
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
302
+ {'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.'},
303
+ ]
304
+ else
305
+ puts "warning: unrecognized storage provider type: '#{storage_provider_type_code}'"
306
+ end
307
+ if provider_type_option_types
308
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(provider_type_option_types, options, @api_client, {})
309
+ payload['storageProvider'].deep_merge!(v_prompt)
310
+ end
311
+
312
+ # Default Backup Target
313
+ if options['defaultBackupTarget'] != nil
314
+ payload['storageProvider']['defaultBackupTarget'] = options['defaultBackupTarget']
315
+ else
316
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultBackupTarget', 'fieldLabel' => 'Default Backup Target', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'off'}], options)
317
+ payload['storageProvider']['defaultBackupTarget'] = (v_prompt['defaultBackupTarget'].to_s == 'on') unless v_prompt['defaultBackupTarget'].nil?
318
+ end
319
+
320
+ # Archive Snapshots
321
+ if options['copyToStore'] != nil
322
+ payload['storageProvider']['copyToStore'] = options['copyToStore']
323
+ else
324
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'copyToStore', 'fieldLabel' => 'Archive Snapshots', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'on'}], options)
325
+ payload['storageProvider']['copyToStore'] = (v_prompt['copyToStore'].to_s == 'on') unless v_prompt['copyToStore'].nil?
326
+ end
327
+
328
+ # Default Deployment Target
329
+ if options['defaultDeploymentTarget'] != nil
330
+ payload['storageProvider']['defaultDeploymentTarget'] = options['defaultDeploymentTarget']
331
+ else
332
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultDeploymentTarget', 'fieldLabel' => 'Default Deployment Target', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'off'}], options)
333
+ payload['storageProvider']['defaultDeploymentTarget'] = (v_prompt['defaultDeploymentTarget'].to_s == 'on') unless v_prompt['defaultDeploymentTarget'].nil?
334
+ end
335
+
336
+ # Default Virtual Image Store
337
+ if options['defaultVirtualImageTarget'] != nil
338
+ payload['storageProvider']['defaultVirtualImageTarget'] = options['defaultVirtualImageTarget']
339
+ else
340
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultVirtualImageTarget', 'fieldLabel' => 'Default Virtual Image Store', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'off'}], options)
341
+ payload['storageProvider']['defaultVirtualImageTarget'] = (v_prompt['defaultVirtualImageTarget'].to_s == 'on') unless v_prompt['defaultVirtualImageTarget'].nil?
342
+ end
343
+
344
+ end
345
+
346
+
347
+ if options[:dry_run]
348
+ print_dry_run @storage_providers_interface.dry.create(payload)
349
+ return
350
+ end
351
+ json_response = @storage_providers_interface.create(payload)
352
+ if options[:json]
353
+ print JSON.pretty_generate(json_response)
354
+ print "\n"
355
+ elsif !options[:quiet]
356
+ storage_provider = json_response['storageProvider']
357
+ print_green_success "Added storage provider #{storage_provider['name']}"
358
+ get([storage_provider['id']])
359
+ end
360
+ return 0
361
+ rescue RestClient::Exception => e
362
+ print_rest_exception(e, options)
363
+ exit 1
364
+ end
365
+ end
366
+
367
+ def update(args)
368
+ options = {}
369
+ ip_range_list = nil
370
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
371
+ opts.banner = subcommand_usage("[storage-provider] [options]")
372
+ opts.on('--name VALUE', String, "Name for this storage provider") do |val|
373
+ options['name'] = val
374
+ end
375
+ opts.on('--type code', String, "Storage Provider Type Code") do |val|
376
+ options['providerType'] = val
377
+ end
378
+ opts.on('--bucket-name VALUE', String, "Bucket Name") do |val|
379
+ options['bucketName'] = val
380
+ end
381
+ opts.on('--default-backup-target [on|off]', String, "Default Backup Target") do |val|
382
+ options['defaultBackupTarget'] = val.to_s == 'on' || val.to_s == 'true'
383
+ end
384
+ opts.on('--default-deployment-target [on|off]', String, "Default Deployment Target") do |val|
385
+ options['defaultDeploymentTarget'] = val.to_s == 'on' || val.to_s == 'true'
386
+ end
387
+ opts.on('--default-virtual-image-target [on|off]', String, "Default Virtual Image Store") do |val|
388
+ options['defaultVirtualImageTarget'] = val.to_s == 'on' || val.to_s == 'true'
389
+ end
390
+ opts.on('--copy-to-store [on|off]', String, "Archive Snapshots") do |val|
391
+ options['copyToStore'] = val.to_s == 'on' || val.to_s == 'true'
392
+ end
393
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
394
+ opts.footer = "Update a storage provider." + "\n" +
395
+ "[storage-provider] is required. This is the id of a storage provider."
396
+ end
397
+ optparse.parse!(args)
398
+ if args.count != 1
399
+ print_error Morpheus::Terminal.angry_prompt
400
+ puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
401
+ return 1
402
+ end
403
+ connect(options)
404
+
405
+ begin
406
+ storage_provider = find_storage_provider_by_name_or_id(args[0])
407
+ return 1 if storage_provider.nil?
408
+
409
+ # merge -O options into normally parsed options
410
+ options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
411
+
412
+ # construct payload
413
+ payload = nil
414
+ if options[:payload]
415
+ payload = options[:payload]
416
+ else
417
+ # prompt for storage provider options
418
+ # preserve previous config settings
419
+ payload = {
420
+ 'storageProvider' => {
421
+ 'config' => storage_provider['config']
422
+ }
423
+ }
424
+
425
+ # allow arbitrary -O options
426
+ payload['storageProvider'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
427
+
428
+ # Name
429
+ if options['name']
430
+ payload['storageProvider']['name'] = options['name']
431
+ end
432
+
433
+ # Default Backup Target
434
+ if options['defaultBackupTarget'] != nil
435
+ payload['storageProvider']['defaultBackupTarget'] = options['defaultBackupTarget']
436
+ end
437
+
438
+ # Archive Snapshots
439
+ if options['copyToStore'] != nil
440
+ payload['storageProvider']['copyToStore'] = options['copyToStore']
441
+ end
442
+
443
+ # Default Deployment Target
444
+ if options['defaultDeploymentTarget'] != nil
445
+ payload['storageProvider']['defaultDeploymentTarget'] = options['defaultDeploymentTarget']
446
+ end
447
+
448
+ # Default Virtual Image Store
449
+ if options['defaultVirtualImageTarget'] != nil
450
+ payload['storageProvider']['defaultVirtualImageTarget'] = options['defaultVirtualImageTarget']
451
+ end
452
+
453
+ end
454
+
455
+ if options[:dry_run]
456
+ print_dry_run @storage_providers_interface.dry.update(storage_provider["id"], payload)
457
+ return
458
+ end
459
+ json_response = @storage_providers_interface.update(storage_provider["id"], payload)
460
+ if options[:json]
461
+ puts as_json(json_response)
462
+ else
463
+ storage_provider = json_response['storageProvider']
464
+ print_green_success "Updated storage provider #{storage_provider['name']}"
465
+ get([storage_provider['id']])
466
+ end
467
+ return 0
468
+ rescue RestClient::Exception => e
469
+ print_rest_exception(e, options)
470
+ return 1
471
+ end
472
+ end
473
+
474
+ def remove(args)
475
+ options = {}
476
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
477
+ opts.banner = subcommand_usage("[storage-provider]")
478
+ build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
479
+ opts.footer = "Delete a storage provider." + "\n" +
480
+ "[storage-provider] is required. This is the name or id of a storage provider."
481
+ end
482
+ optparse.parse!(args)
483
+
484
+ if args.count < 1
485
+ print_error Morpheus::Terminal.angry_prompt
486
+ puts_error "#{command_name} missing argument: [storage-provider]\n#{optparse}"
487
+ return 1
488
+ end
489
+
490
+ connect(options)
491
+ begin
492
+ storage_provider = find_storage_provider_by_name_or_id(args[0])
493
+ return 1 if storage_provider.nil?
494
+
495
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the storage provider: #{storage_provider['name']}?")
496
+ return 9, "aborted command"
497
+ end
498
+ if options[:dry_run]
499
+ print_dry_run @storage_providers_interface.dry.destroy(storage_provider['id'])
500
+ return 0
501
+ end
502
+ json_response = @storage_providers_interface.destroy(storage_provider['id'])
503
+ if options[:json]
504
+ print JSON.pretty_generate(json_response)
505
+ print "\n"
506
+ else
507
+ print_green_success "Removed storage provider #{storage_provider['name']}"
508
+ # list([])
509
+ end
510
+ return 0
511
+ rescue RestClient::Exception => e
512
+ print_rest_exception(e, options)
513
+ return 1
514
+ end
515
+ end
516
+
517
+ private
518
+
519
+
520
+ def get_storage_provider_types()
521
+ [
522
+ {'name' => 'Amazon S3', 'value' => 's3'},
523
+ {'name' => 'Azure', 'value' => 'azure'},
524
+ {'name' => 'CIFS', 'value' => 'cifs'},
525
+ {'name' => 'Local Storage', 'value' => 'local'},
526
+ {'name' => 'NFSv3', 'value' => 'nfs'},
527
+ {'name' => 'Openstack Swift', 'value' => 'openstack'},
528
+ {'name' => 'Rackspace CDN', 'value' => 'rackspace'}
529
+ ]
530
+ end
531
+
532
+ def find_storage_provider_by_name_or_id(val)
533
+ if val.to_s =~ /\A\d{1,}\Z/
534
+ return find_storage_provider_by_id(val)
535
+ else
536
+ return find_storage_provider_by_name(val)
537
+ end
538
+ end
539
+
540
+ def find_storage_provider_by_id(id)
541
+ begin
542
+ json_response = @storage_providers_interface.get(id.to_i)
543
+ return json_response['storageProvider']
544
+ rescue RestClient::Exception => e
545
+ if e.response && e.response.code == 404
546
+ print_red_alert "Storage Provider not found by id #{id}"
547
+ return nil
548
+ else
549
+ raise e
550
+ end
551
+ end
552
+ end
553
+
554
+ def find_storage_provider_by_name(name)
555
+ json_response = @storage_providers_interface.list({name: name.to_s})
556
+ storage_providers = json_response['storageProviders']
557
+ if storage_providers.empty?
558
+ print_red_alert "Storage Provider not found by name #{name}"
559
+ return nil
560
+ elsif storage_providers.size > 1
561
+ print_red_alert "#{storage_providers.size} storage providers found by name #{name}"
562
+ rows = storage_providers.collect do |storage_provider|
563
+ {id: it['id'], name: it['name']}
564
+ end
565
+ print red
566
+ tp rows, [:id, :name]
567
+ print reset,"\n"
568
+ return nil
569
+ else
570
+ return storage_providers[0]
571
+ end
572
+ end
573
+
574
+ def format_bucket_name(storage_provider)
575
+ if storage_provider['providerType'] == 'local'
576
+ storage_provider['config'] ? storage_provider['config']['basePath'] : ''
577
+ else
578
+ storage_provider['bucketName']
579
+ end
580
+ end
581
+
582
+ def format_storage_provider_type(storage_provider)
583
+ storage_provider['providerType'].to_s.capitalize
584
+ end
585
+
586
+ end
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "3.1.1.2"
4
+ VERSION = "3.1.2"
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morpheus-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1.2
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Estes
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2017-12-08 00:00:00.000000000 Z
14
+ date: 2017-12-13 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -190,6 +190,7 @@ files:
190
190
  - lib/morpheus/api/security_groups_interface.rb
191
191
  - lib/morpheus/api/servers_interface.rb
192
192
  - lib/morpheus/api/setup_interface.rb
193
+ - lib/morpheus/api/storage_providers_interface.rb
193
194
  - lib/morpheus/api/task_sets_interface.rb
194
195
  - lib/morpheus/api/tasks_interface.rb
195
196
  - lib/morpheus/api/users_interface.rb
@@ -260,6 +261,7 @@ files:
260
261
  - lib/morpheus/cli/shell.rb
261
262
  - lib/morpheus/cli/source_command.rb
262
263
  - lib/morpheus/cli/ssl_verification_command.rb
264
+ - lib/morpheus/cli/storage_providers_command.rb
263
265
  - lib/morpheus/cli/tasks.rb
264
266
  - lib/morpheus/cli/users.rb
265
267
  - lib/morpheus/cli/version.rb