morpheus-cli 3.1.1.2 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
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