morpheus-cli 5.4.3.1 → 5.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +8 -0
  4. data/lib/morpheus/api/catalog_item_types_interface.rb +9 -12
  5. data/lib/morpheus/api/clusters_interface.rb +12 -0
  6. data/lib/morpheus/api/credential_types_interface.rb +9 -0
  7. data/lib/morpheus/api/credentials_interface.rb +9 -0
  8. data/lib/morpheus/api/monitoring_apps_interface.rb +12 -4
  9. data/lib/morpheus/api/monitoring_checks_interface.rb +12 -4
  10. data/lib/morpheus/api/monitoring_groups_interface.rb +13 -5
  11. data/lib/morpheus/api/monitoring_incidents_interface.rb +12 -4
  12. data/lib/morpheus/api/options_interface.rb +8 -1
  13. data/lib/morpheus/api/power_schedules_interface.rb +2 -2
  14. data/lib/morpheus/api/service_plans_interface.rb +6 -0
  15. data/lib/morpheus/cli/cli_command.rb +10 -17
  16. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +75 -8
  17. data/lib/morpheus/cli/commands/clusters.rb +119 -5
  18. data/lib/morpheus/cli/commands/credential_types_command.rb +36 -0
  19. data/lib/morpheus/cli/commands/credentials_command.rb +124 -0
  20. data/lib/morpheus/cli/commands/hosts.rb +20 -2
  21. data/lib/morpheus/cli/commands/instances.rb +5 -1
  22. data/lib/morpheus/cli/commands/monitoring_apps_command.rb +8 -8
  23. data/lib/morpheus/cli/commands/monitoring_checks_command.rb +8 -8
  24. data/lib/morpheus/cli/commands/monitoring_groups_command.rb +8 -8
  25. data/lib/morpheus/cli/commands/monitoring_incidents_command.rb +8 -8
  26. data/lib/morpheus/cli/commands/power_schedules_command.rb +189 -258
  27. data/lib/morpheus/cli/commands/service_plans_command.rb +51 -4
  28. data/lib/morpheus/cli/commands/storage_server_types.rb +0 -5
  29. data/lib/morpheus/cli/commands/storage_servers.rb +0 -6
  30. data/lib/morpheus/cli/commands/storage_volume_types.rb +0 -5
  31. data/lib/morpheus/cli/commands/storage_volumes.rb +0 -6
  32. data/lib/morpheus/cli/mixins/provisioning_helper.rb +37 -27
  33. data/lib/morpheus/cli/mixins/rest_command.rb +20 -4
  34. data/lib/morpheus/cli/mixins/storage_servers_helper.rb +0 -63
  35. data/lib/morpheus/cli/mixins/storage_volumes_helper.rb +0 -43
  36. data/lib/morpheus/cli/option_types.rb +1 -0
  37. data/lib/morpheus/cli/version.rb +1 -1
  38. data/lib/morpheus/routes.rb +13 -3
  39. metadata +11 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4a903c14e297c4ac0a1e4122f2348e997844c31051f7eb5e966663e3014adf9
4
- data.tar.gz: 4f1ee47b1c73c9f6e9a00bcc7faec384e46a798b29e1a11138361b4f574ca544
3
+ metadata.gz: e88f25d69ce8a6c1038899e3671c69a31266607d3370b2c4a20d3fa74d76dc42
4
+ data.tar.gz: '08ccc023d2cc5908a7a8f9a8a3cde3ec9cd11e08b85e53b1732aecc0e38ab166'
5
5
  SHA512:
6
- metadata.gz: 87adf644de800a8a79d474fdf686d02061216b5033d7a83030e46f9824c150d1089c42cf87099667a3cd3ec76f1b62683946a05ec7e4395febbd7f623267dcd7
7
- data.tar.gz: 013a285d1d21b26ffd89aec19c918626879de2fff8496684dc7cea85ea50fa92e54e187d0af93ac93e0f8f435101b9f40f8f55762b94579e59110c15cd3c0829
6
+ metadata.gz: 1a21ebb4f7b58cbd5aede974f4bb298a19a02c4aad9f92fbe0c149d5cde3a80dfdf141fbf7aca66ce9cf1c2fc9a4495f51e3c6fcea9ee7458a4153ed3c6bb1d9
7
+ data.tar.gz: f9412dd77a1c90346133832363ac8d756b0f4576b4a3102024552dba4c63d566430b57a3b53395080f928b88b5354f446bdc3bb9df6d1351b5994419ca884623
data/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  FROM ruby:2.5.1
2
2
 
3
- RUN gem install morpheus-cli -v 5.4.3.1
3
+ RUN gem install morpheus-cli -v 5.4.4
4
4
 
5
5
  ENTRYPOINT ["morpheus"]
@@ -892,6 +892,14 @@ class Morpheus::APIClient
892
892
  Morpheus::SnapshotsInterface.new(common_interface_options).setopts(@options)
893
893
  end
894
894
 
895
+ def credentials
896
+ Morpheus::CredentialsInterface.new(common_interface_options).setopts(@options)
897
+ end
898
+
899
+ def credential_types
900
+ Morpheus::CredentialTypesInterface.new(common_interface_options).setopts(@options)
901
+ end
902
+
895
903
  def rest(endpoint)
896
904
  Morpheus::RestInterface.new(common_interface_options).setopts(@options.merge({base_path: "#{@base_url}/api/#{endpoint}"}))
897
905
  end
@@ -6,22 +6,19 @@ class Morpheus::CatalogItemTypesInterface < Morpheus::RestInterface
6
6
  "/api/catalog-item-types"
7
7
  end
8
8
 
9
- # NOT json, multipart file upload
10
- # def update_logo(id, logo_file)
11
- # url = "#{base_path}/#{id}/update-logo"
12
- # headers = { :params => {}, :authorization => "Bearer #{@access_token}"}
13
- # payload = {}
14
- # payload[:logo] = logo_file
15
- # payload[:multipart] = true
16
- # execute(method: :post, url: url, headers: headers, payload: payload)
17
- # end
18
-
19
9
  # NOT json, multipart file upload, uses PUT update endpoint
20
- def update_logo(id, logo_file)
10
+ def update_logo(id, logo_file, dark_logo_file=nil)
11
+ #url = "#{base_path}/#{id}/update-logo"
21
12
  url = "#{base_path}/#{id}"
22
13
  headers = { :params => {}, :authorization => "Bearer #{@access_token}"}
23
14
  payload = {}
24
- payload["catalogItemType"] = {"logo" => logo_file}
15
+ payload["catalogItemType"] = {}
16
+ if logo_file
17
+ payload["catalogItemType"]["logo"] = logo_file
18
+ end
19
+ if dark_logo_file
20
+ payload["catalogItemType"]["darkLogo"] = dark_logo_file
21
+ end
25
22
  payload[:multipart] = true
26
23
  execute(method: :put, url: url, headers: headers, payload: payload)
27
24
  end
@@ -91,6 +91,18 @@ class Morpheus::ClustersInterface < Morpheus::APIClient
91
91
  execute(method: :get, url: url, headers: headers)
92
92
  end
93
93
 
94
+ def destroy_worker(id, worker_id, params={})
95
+ url = "#{base_path}/#{id}/servers/#{worker_id}"
96
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
97
+ execute(method: :delete, url: url, headers: headers)
98
+ end
99
+
100
+ def update_worker_count(id, params={})
101
+ url = "#{base_path}/#{id}/worker-count"
102
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
103
+ execute(method: :put, url: url, headers: headers)
104
+ end
105
+
94
106
  def list_services(id, params={})
95
107
  url = "#{base_path}/#{id}/services"
96
108
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -0,0 +1,9 @@
1
+ require 'morpheus/api/read_interface'
2
+
3
+ class Morpheus::CredentialTypesInterface < Morpheus::ReadInterface
4
+
5
+ def base_path
6
+ "/api/credential-types"
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'morpheus/api/rest_interface'
2
+
3
+ class Morpheus::CredentialsInterface < Morpheus::RestInterface
4
+
5
+ def base_path
6
+ "/api/credentials"
7
+ end
8
+
9
+ end
@@ -38,20 +38,28 @@ class Morpheus::MonitoringAppsInterface < Morpheus::APIClient
38
38
  execute(opts)
39
39
  end
40
40
 
41
- def quarantine(id, payload={})
42
- url = "#{@base_url}/api/monitoring/apps/#{id}/quarantine"
41
+ def mute(id, payload={})
42
+ url = "#{@base_url}/api/monitoring/apps/#{id}/mute"
43
43
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
44
44
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
45
45
  execute(opts)
46
46
  end
47
47
 
48
- def quarantine_all(payload={})
49
- url = "#{@base_url}/api/monitoring/apps/quarantine-all"
48
+ def mute_all(payload={})
49
+ url = "#{@base_url}/api/monitoring/apps/mute-all"
50
50
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
51
51
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
52
52
  execute(opts)
53
53
  end
54
54
 
55
+ def quarantine(id, payload={})
56
+ mute(id, payload)
57
+ end
58
+
59
+ def quarantine_all(payload={})
60
+ mute_all(payload)
61
+ end
62
+
55
63
  def statistics(id, params={})
56
64
  url = "#{@base_url}/api/monitoring/apps/#{id}/statistics"
57
65
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -39,22 +39,30 @@ class Morpheus::MonitoringChecksInterface < Morpheus::APIClient
39
39
  execute(opts)
40
40
  end
41
41
 
42
- def quarantine(id, options={})
43
- url = "#{@base_url}/api/monitoring/checks/#{id}/quarantine"
42
+ def mute(id, options={})
43
+ url = "#{@base_url}/api/monitoring/checks/#{id}/mute"
44
44
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
45
45
  payload = options
46
46
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
47
47
  execute(opts)
48
48
  end
49
49
 
50
- def quarantine_all(options={})
51
- url = "#{@base_url}/api/monitoring/checks/quarantine-all"
50
+ def mute_all(options={})
51
+ url = "#{@base_url}/api/monitoring/checks/mute-all"
52
52
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
53
53
  payload = options
54
54
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
55
55
  execute(opts)
56
56
  end
57
57
 
58
+ def quarantine(id, payload={})
59
+ mute(id, payload)
60
+ end
61
+
62
+ def quarantine_all(payload={})
63
+ mute_all(payload)
64
+ end
65
+
58
66
  def history(id, params={})
59
67
  url = "#{@base_url}/api/monitoring/checks/#{id}/history"
60
68
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -38,20 +38,28 @@ class Morpheus::MonitoringGroupsInterface < Morpheus::APIClient
38
38
  execute(opts)
39
39
  end
40
40
 
41
- def quarantine(id, payload={})
42
- url = "#{@base_url}/api/monitoring/groups/#{id}/quarantine"
41
+ def mute(id, payload={})
42
+ url = "#{@base_url}/api/monitoring/groups/#{id}/mute"
43
43
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
44
44
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
45
45
  execute(opts)
46
46
  end
47
47
 
48
- def quarantine_all(payload={})
49
- url = "#{@base_url}/api/monitoring/groups/quarantine-all"
48
+ def mute_all(payload={})
49
+ url = "#{@base_url}/api/monitoring/groups/mute-all"
50
50
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
51
51
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
52
52
  execute(opts)
53
53
  end
54
-
54
+
55
+ def quarantine(id, payload={})
56
+ mute(id, payload)
57
+ end
58
+
59
+ def quarantine_all(payload={})
60
+ mute_all(payload)
61
+ end
62
+
55
63
  def history(id, params={})
56
64
  url = "#{@base_url}/api/monitoring/groups/#{id}/history"
57
65
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -58,21 +58,29 @@ class Morpheus::MonitoringIncidentsInterface < Morpheus::APIClient
58
58
  execute(opts)
59
59
  end
60
60
 
61
- def quarantine(id, options={})
62
- url = "#{@base_url}/api/monitoring/incidents/#{id}/quarantine"
61
+ def mute(id, options={})
62
+ url = "#{@base_url}/api/monitoring/incidents/#{id}/mute"
63
63
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
64
64
  payload = options
65
65
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
66
66
  execute(opts)
67
67
  end
68
68
 
69
- def quarantine_all(payload={})
70
- url = "#{@base_url}/api/monitoring/incidents/quarantine-all"
69
+ def mute_all(payload={})
70
+ url = "#{@base_url}/api/monitoring/incidents/mute-all"
71
71
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
72
72
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
73
73
  execute(opts)
74
74
  end
75
75
 
76
+ def quarantine(id, payload={})
77
+ mute(id, payload)
78
+ end
79
+
80
+ def quarantine_all(payload={})
81
+ mute_all(payload)
82
+ end
83
+
76
84
  def history(id, params={})
77
85
  url = "#{@base_url}/api/monitoring/incidents/#{id}/history"
78
86
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -2,8 +2,15 @@ require 'morpheus/api/api_client'
2
2
 
3
3
  class Morpheus::OptionsInterface < Morpheus::APIClient
4
4
 
5
- def options_for_source(source,params = {})
5
+ def options_for_type(option_type, params={})
6
+ options_for_source(option_type['optionSource'], params, option_type['optionSourceType'])
7
+ end
8
+
9
+ def options_for_source(source,params = {}, option_source_type=nil)
6
10
  url = "#{@base_url}/api/options/#{source}"
11
+ if option_source_type
12
+ url = "#{@base_url}/api/options/#{option_source_type}/#{source}"
13
+ end
7
14
  headers = { params: params, authorization: "Bearer #{@access_token}" }
8
15
  execute(method: :get, url: url, headers: headers)
9
16
  end
@@ -2,10 +2,10 @@ require 'morpheus/api/api_client'
2
2
 
3
3
  class Morpheus::PowerSchedulesInterface < Morpheus::APIClient
4
4
 
5
- def get(id)
5
+ def get(id, params={})
6
6
  raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
7
7
  url = "#{@base_url}/api/power-schedules/#{id}"
8
- headers = { params: {}, authorization: "Bearer #{@access_token}" }
8
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
9
9
  opts = {method: :get, url: url, timeout: 10, headers: headers}
10
10
  execute(opts)
11
11
  end
@@ -42,6 +42,12 @@ class Morpheus::ServicePlansInterface < Morpheus::APIClient
42
42
  execute(method: :put, url: url, headers: headers)
43
43
  end
44
44
 
45
+ def destroy(id, params={})
46
+ url = "#{base_path}/#{id}"
47
+ headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
48
+ execute(method: :delete, url: url, headers: headers)
49
+ end
50
+
45
51
  def provision_types(params={})
46
52
  url = "#{base_path}/provision-types"
47
53
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -151,23 +151,13 @@ module Morpheus
151
151
 
152
152
  # add each one to the OptionParser
153
153
  option_types.each do |option_type|
154
- field_namespace = []
155
- field_name = option_type['fieldName'].to_s
156
- if field_name.empty?
157
- puts "Missing fieldName for option type: #{option_type}" if Morpheus::Logging.debug?
154
+ if option_type['fieldName'].empty?
155
+ puts_error "Missing fieldName for option type: #{option_type}" if Morpheus::Logging.debug?
158
156
  next
159
157
  end
160
-
161
- if !option_type['fieldContext'].to_s.empty?
162
- option_type['fieldContext'].split(".").each do |ns|
163
- field_namespace << ns
164
- end
165
- end
166
-
167
- full_field_name = field_name
168
- if !field_namespace.empty?
169
- full_field_name = "#{field_namespace.join('.')}.#{field_name}"
170
- end
158
+ full_field_name = option_type['fieldContext'].to_s.empty? ? option_type['fieldName'] : "#{option_type['fieldContext']}.#{option_type['fieldName']}"
159
+ field_namespace = full_field_name.split(".")
160
+ field_name = field_namespace.pop
171
161
 
172
162
  description = "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}"
173
163
  if option_type['description']
@@ -1507,8 +1497,11 @@ module Morpheus
1507
1497
  type, *ids = args
1508
1498
  type = type.to_s.singularize.underscore
1509
1499
  # still relying on the command or helper to define these _label and _key methods
1510
- label = send("#{type}_label")
1511
- object_key = send("#{type}_object_key")
1500
+ # label = send("#{type}_label")
1501
+ # object_key = send("#{type}_object_key")
1502
+ # ^ nope, not for long!
1503
+ object_key = respond_to?("#{type}_object_key", true) ? send("#{type}_object_key") : type.camelcase.singularize
1504
+ label = respond_to?("#{type}_label", true) ? send("#{type}_label") : type.titleize
1512
1505
  interface_name = "@#{type.pluralize}_interface"
1513
1506
  interface = instance_variable_get(interface_name)
1514
1507
  if interface.nil?
@@ -13,7 +13,7 @@ class Morpheus::Cli::CatalogItemTypesCommand
13
13
  set_command_description "Self Service: View and manage catalog item types"
14
14
 
15
15
  register_subcommands :list, :get, :add, :update, :remove
16
- register_subcommands({:'update-logo' => :update_logo})
16
+ register_subcommands({:'update-logo' => :update_logo, :'update-dark-logo' => :update_dark_logo})
17
17
 
18
18
  def connect(opts)
19
19
  @api_client = establish_remote_appliance_connection(opts)
@@ -224,6 +224,7 @@ EOT
224
224
  options = {}
225
225
  params = {}
226
226
  logo_file = nil
227
+ dark_logo_file = nil
227
228
  optparse = Morpheus::Cli::OptionParser.new do |opts|
228
229
  opts.banner = subcommand_usage("[name] [options]")
229
230
  # opts.on('-t', '--type [instance|blueprint|workflow]', "Item Type, default is instance.") do |val|
@@ -235,7 +236,7 @@ EOT
235
236
  filename = val
236
237
  logo_file = nil
237
238
  if filename == 'null'
238
- filename = 'null' # clear it
239
+ logo_file = 'null' # clear it
239
240
  else
240
241
  filename = File.expand_path(filename)
241
242
  if !File.exists?(filename)
@@ -244,6 +245,19 @@ EOT
244
245
  logo_file = File.new(filename, 'rb')
245
246
  end
246
247
  end
248
+ opts.on('--dark-logo FILE', String, "Upload a custom dark logo icon") do |val|
249
+ filename = val
250
+ dark_logo_file = nil
251
+ if filename == 'null'
252
+ dark_logo_file = 'null' # clear it
253
+ else
254
+ filename = File.expand_path(filename)
255
+ if !File.exists?(filename)
256
+ raise_command_error "File not found: #{filename}"
257
+ end
258
+ dark_logo_file = File.new(filename, 'rb')
259
+ end
260
+ end
247
261
  opts.on('--config-file FILE', String, "Config from a local JSON or YAML file") do |val|
248
262
  options[:config_file] = val.to_s
249
263
  file_content = nil
@@ -346,9 +360,9 @@ EOT
346
360
  end
347
361
  json_response = @catalog_item_types_interface.create(payload)
348
362
  if json_response['success']
349
- if logo_file
363
+ if logo_file || dark_logo_file
350
364
  begin
351
- @catalog_item_types_interface.update_logo(json_response['catalogItemType']['id'], logo_file)
365
+ @catalog_item_types_interface.update_logo(json_response['catalogItemType']['id'], logo_file, dark_logo_file)
352
366
  rescue RestClient::Exception => e
353
367
  print_red_alert "Failed to save logo!"
354
368
  print_rest_exception(e, options)
@@ -368,6 +382,7 @@ EOT
368
382
  params = {}
369
383
  payload = {}
370
384
  logo_file = nil
385
+ dark_logo_file = nil
371
386
  optparse = Morpheus::Cli::OptionParser.new do |opts|
372
387
  opts.banner = subcommand_usage("[type] [options]")
373
388
  build_option_type_options(opts, options, update_catalog_item_type_option_types)
@@ -375,7 +390,7 @@ EOT
375
390
  filename = val
376
391
  logo_file = nil
377
392
  if filename == 'null'
378
- filename = 'null' # clear it
393
+ logo_file = 'null' # clear it
379
394
  else
380
395
  filename = File.expand_path(filename)
381
396
  if !File.exists?(filename)
@@ -384,6 +399,19 @@ EOT
384
399
  logo_file = File.new(filename, 'rb')
385
400
  end
386
401
  end
402
+ opts.on('--dark-logo FILE', String, "Upload a custom dark logo icon") do |val|
403
+ filename = val
404
+ dark_logo_file = nil
405
+ if filename == 'null'
406
+ dark_logo_file = 'null' # clear it
407
+ else
408
+ filename = File.expand_path(filename)
409
+ if !File.exists?(filename)
410
+ raise_command_error "File not found: #{filename}"
411
+ end
412
+ dark_logo_file = File.new(filename, 'rb')
413
+ end
414
+ end
387
415
  opts.on('--config-file FILE', String, "Config from a local JSON or YAML file") do |val|
388
416
  options[:config_file] = val.to_s
389
417
  file_content = nil
@@ -474,7 +502,7 @@ EOT
474
502
  params['workflow'] = {'id' => params['workflow']} if params['workflow'] && !params['workflow'].is_a?(Hash)
475
503
  params['blueprint'] = {'id' => params['blueprint']} if params['blueprint'] && !params['blueprint'].is_a?(Hash)
476
504
  payload.deep_merge!({catalog_item_type_object_key => params})
477
- if payload[catalog_item_type_object_key].empty? # || options[:no_prompt]
505
+ if payload[catalog_item_type_object_key].empty? && (!logo_file && !dark_logo_file)# || options[:no_prompt]
478
506
  raise_command_error "Specify at least one option to update.\n#{optparse}"
479
507
  end
480
508
  end
@@ -485,9 +513,9 @@ EOT
485
513
  end
486
514
  json_response = @catalog_item_types_interface.update(catalog_item_type['id'], payload)
487
515
  if json_response['success']
488
- if logo_file
516
+ if logo_file || dark_logo_file
489
517
  begin
490
- @catalog_item_types_interface.update_logo(json_response['catalogItemType']['id'], logo_file)
518
+ @catalog_item_types_interface.update_logo(json_response['catalogItemType']['id'], logo_file, dark_logo_file)
491
519
  rescue RestClient::Exception => e
492
520
  print_red_alert "Failed to save logo!"
493
521
  print_rest_exception(e, options)
@@ -541,6 +569,45 @@ EOT
541
569
  end
542
570
  end
543
571
 
572
+ def update_dark_logo(args)
573
+ options = {}
574
+ params = {}
575
+ filename = nil
576
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
577
+ opts.banner = subcommand_usage("[type] [file]")
578
+ build_common_options(opts, options, [:json, :dry_run, :remote])
579
+ opts.footer = "Update the dark logo for a catalog item type." + "\n" +
580
+ "[type] is required. This is the name or id of a catalog item type." + "\n" +
581
+ "[file] is required. This is the path of the dark logo file"
582
+ end
583
+ optparse.parse!(args)
584
+ verify_args!(args:args, optparse:optparse, count:2)
585
+ connect(options)
586
+ catalog_item_type = find_catalog_item_type_by_name_or_id(args[0])
587
+ return 1 if catalog_item_type.nil?
588
+ filename = args[1]
589
+ dark_logo_file = nil
590
+ if filename == 'null'
591
+ dark_logo_file = 'null' # clear it
592
+ else
593
+ filename = File.expand_path(filename)
594
+ if !File.exists?(filename)
595
+ raise_command_error "File not found: #{filename}"
596
+ end
597
+ dark_logo_file = File.new(filename, 'rb')
598
+ end
599
+ @catalog_item_types_interface.setopts(options)
600
+ if options[:dry_run]
601
+ print_dry_run @catalog_item_types_interface.dry.update_logo(catalog_item_type['id'], nil, dark_logo_file)
602
+ return
603
+ end
604
+ json_response = @catalog_item_types_interface.update_logo(catalog_item_type['id'], nil, dark_logo_file)
605
+ render_response(json_response, options, catalog_item_type_object_key) do
606
+ print_green_success "Updated catalog item type #{catalog_item_type['name']} logo"
607
+ return _get(catalog_item_type["id"], {}, options)
608
+ end
609
+ end
610
+
544
611
  def remove(args)
545
612
  options = {}
546
613
  params = {}