morpheus-cli 4.2.17 → 4.2.22

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
  SHA256:
3
- metadata.gz: 5ca98cbe4891f98ca85702bb9794a0f255e8208a22b30189220bbec1a48dd3b0
4
- data.tar.gz: 5c46ca8fc5d4944d7e5f363731652f1933e7a07226904d4b1c3829d9456ba64c
3
+ metadata.gz: f1e56f81e53557586c3a19751c97163f5c63ce1bda3ea04e5eadd54d7e1c08e0
4
+ data.tar.gz: 24c543afa2832100919d5451b8d8954952132db4b421cffe889882b5f7ef34e9
5
5
  SHA512:
6
- metadata.gz: 5f8b8ead51a8d5953f51b3543e293eff03b329a5ec1f8194a5956426f7f38716a210c99d4114c5e14feff24f74f9756c88db71be0dd094db279a40122ef115f4
7
- data.tar.gz: bf432f7ec48ea911a36029ae66f58339627e34a3548f60f36d7a49f7cc018728f3f77556d6abec53f1cff8490a6354db14b1664e3c546cf625dc2c637b573271
6
+ metadata.gz: 682d8dafc50d15c216470971f5c78ca09cba8feafa2d7f1cf0462a6368f88377a627411ba3d4287ff1669d321153be02f4db2e955606620d6a5bf8425b055e23
7
+ data.tar.gz: 60b6787aacf5b2275197c496a3ff9bc9018fe70e897def95bacb54268dbdf97d5dc362e3d8f7bbfb7b0db0b18cc8028ae99b2e1f2540bb821485c21ee27b945d
data/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  FROM ruby:2.5.1
2
2
 
3
- RUN gem install morpheus-cli -v 4.2.17
3
+ RUN gem install morpheus-cli -v 4.2.22
4
4
 
5
5
  ENTRYPOINT ["morpheus"]
@@ -1,4 +1,4 @@
1
- require 'morpheus/api/api_client'
1
+ require 'morpheus/api/rest_interface'
2
2
 
3
3
  class Morpheus::BackupJobsInterface < Morpheus::RestInterface
4
4
 
@@ -1,4 +1,4 @@
1
- require 'morpheus/api/api_client'
1
+ require 'morpheus/api/rest_interface'
2
2
 
3
3
  class Morpheus::BackupsInterface < Morpheus::RestInterface
4
4
 
@@ -1,4 +1,4 @@
1
- require 'morpheus/api/api_client'
1
+ require 'morpheus/api/rest_interface'
2
2
 
3
3
  class Morpheus::DeploymentsInterface < Morpheus::RestInterface
4
4
 
@@ -45,6 +45,7 @@ module Morpheus
45
45
  def self.load!()
46
46
  # load interfaces
47
47
  require 'morpheus/api/api_client.rb'
48
+ require 'morpheus/api/rest_interface.rb'
48
49
  Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each {|file| load file }
49
50
 
50
51
  # load mixins
@@ -62,11 +62,15 @@ class Morpheus::Cli::BlueprintsCommand
62
62
  params['ownerId'] << val
63
63
  end
64
64
  opts.add_hidden_option('--created-by')
65
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
65
+ build_standard_list_options(opts, options)
66
66
  opts.footer = "List blueprints."
67
67
  end
68
68
  optparse.parse!(args)
69
69
  connect(options)
70
+ # verify_args!(args:args, optparse:optparse, count:0)
71
+ if args.count > 0
72
+ options[:phrase] = args.join(" ")
73
+ end
70
74
  begin
71
75
  if params['ownerId']
72
76
  params['ownerId'] = params['ownerId'].collect do |owner_id|
@@ -125,7 +129,7 @@ class Morpheus::Cli::BlueprintsCommand
125
129
  opts.on( '-c', '--config', "Display raw config only. Default is YAML. Combine with -j for JSON instead." ) do
126
130
  options[:show_config] = true
127
131
  end
128
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :outfile, :dry_run, :remote])
132
+ build_standard_get_options(opts, options)
129
133
  opts.footer = "Get details about a blueprint.\n" +
130
134
  "[blueprint] is required. This is the name or id of a blueprint. Supports 1-N [instance] arguments."
131
135
  end
@@ -154,8 +158,9 @@ class Morpheus::Cli::BlueprintsCommand
154
158
  end
155
159
  @blueprints_interface.setopts(options)
156
160
  blueprint = find_blueprint_by_name_or_id(arg)
157
- exit 1 if blueprint.nil?
158
-
161
+ if blueprint.nil?
162
+ return 1, "blueprint not found"
163
+ end
159
164
  json_response = {'blueprint' => blueprint} # skip redundant request
160
165
  #json_response = @blueprints_interface.get(blueprint['id'])
161
166
  blueprint = json_response['blueprint']
@@ -165,43 +170,13 @@ class Morpheus::Cli::BlueprintsCommand
165
170
  unless options[:json] || options[:yaml] || options[:csv]
166
171
  options[:yaml] = true
167
172
  end
168
- blueprint_config = blueprint['config']
169
- render_result = render_with_format(blueprint_config, options)
170
- return 0 if render_result
173
+ return render_with_format(blueprint['config'], options)
171
174
  end
172
-
173
- render_result = render_with_format(json_response, options, 'blueprint')
174
- return 0 if render_result
175
-
176
- print_h1 "Blueprint Details"
177
-
178
- print_blueprint_details(blueprint)
179
-
180
- if blueprint['resourcePermission'].nil?
181
- #print "\n", "No group access found", "\n"
182
- else
183
- # print_h2 "Group Access"
184
- # rows = []
185
- # if blueprint['resourcePermission']['allSites'] || blueprint['resourcePermission']['all']
186
- # rows.push({"name" => 'All'})
187
- # end
188
- # if blueprint['resourcePermission']['sites']
189
- # blueprint['resourcePermission']['sites'].each do |site|
190
- # rows.push(site)
191
- # end
192
- # end
193
- # rows = rows.collect do |site|
194
- # {group: site['name'], default: site['default'] ? 'Yes' : ''}
195
- # end
196
- # # columns = [:group, :default]
197
- # columns = [:group]
198
- # print cyan
199
- # print as_pretty_table(rows, columns)
200
- # print reset,"\n"
201
- end
202
-
203
- #print reset,"\n"
204
- return 0
175
+ render_response(json_response, options, 'blueprint') do
176
+ print_h1 "Blueprint Details"
177
+ print_blueprint_details(blueprint)
178
+ end
179
+ return 0, nil
205
180
  rescue RestClient::Exception => e
206
181
  print_rest_exception(e, options)
207
182
  exit 1
@@ -216,17 +191,12 @@ class Morpheus::Cli::BlueprintsCommand
216
191
  opts.on('-t', '--type TYPE', String, "Blueprint Type. Default is morpheus.") do |val|
217
192
  options[:blueprint_type] = parse_blueprint_type(val.to_s)
218
193
  end
219
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
194
+ build_standard_add_options(opts, options)
220
195
  opts.footer = "Create a new blueprint.\n" +
221
196
  "[name] is required. This is the name of the new blueprint."
222
197
  end
223
198
  optparse.parse!(args)
224
- if args.count > 1
225
- print_error Morpheus::Terminal.angry_prompt
226
- puts_error "#{command_name} add expects 0-1 arguments and received #{args.count}: #{args}\n#{optparse}"
227
- return 1
228
- end
229
- options[:options] ||= {}
199
+ verify_args!(args:args, optparse:optparse, min:0, max:1)
230
200
  if args[0]
231
201
  options[:options]['name'] = args[0]
232
202
  end
@@ -248,9 +218,7 @@ class Morpheus::Cli::BlueprintsCommand
248
218
  end
249
219
  params = Morpheus::Cli::OptionTypes.prompt(add_blueprint_option_types, options[:options], @api_client, options[:params])
250
220
  params.deep_compact!
251
- #blueprint_payload = params.select {|k,v| ['name', 'description', 'category'].include?(k) }
252
221
  # expects no namespace, just the config
253
- #payload = blueprint_payload
254
222
  payload.deep_merge!(params)
255
223
  end
256
224
  @blueprints_interface.setopts(options)
@@ -260,12 +228,8 @@ class Morpheus::Cli::BlueprintsCommand
260
228
  end
261
229
 
262
230
  json_response = @blueprints_interface.create(payload)
263
-
264
- if options[:json]
265
- print JSON.pretty_generate(json_response)
266
- print "\n"
267
- elsif !options[:quiet]
268
- blueprint = json_response["blueprint"]
231
+ blueprint = json_response['blueprint']
232
+ render_response(json_response, options, 'blueprint') do
269
233
  print_green_success "Added blueprint #{blueprint['name']}"
270
234
  if !options[:no_prompt]
271
235
  if options[:payload].nil? && ::Morpheus::Cli::OptionTypes::confirm("Would you like to add a tier now?", options.merge({default: false}))
@@ -275,11 +239,11 @@ class Morpheus::Cli::BlueprintsCommand
275
239
  end
276
240
  else
277
241
  # print details
278
- get([blueprint['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
242
+ return _get(blueprint["id"], options)
279
243
  end
280
244
  end
281
245
  end
282
- return 0
246
+ return 0, nil
283
247
  rescue RestClient::Exception => e
284
248
  print_rest_exception(e, options)
285
249
  exit 1
@@ -294,7 +258,7 @@ class Morpheus::Cli::BlueprintsCommand
294
258
  opts.on( '--owner USER', "Owner Username or ID" ) do |val|
295
259
  options[:owner] = val == 'null' ? nil : val
296
260
  end
297
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
261
+ build_standard_update_options(opts, options)
298
262
  opts.footer = "Update a blueprint.\n" +
299
263
  "[blueprint] is required. This is the name or id of a blueprint."
300
264
  end
@@ -388,7 +352,7 @@ class Morpheus::Cli::BlueprintsCommand
388
352
  options[:owner] = val == 'null' ? nil : val
389
353
  end
390
354
  build_option_type_options(opts, options, update_blueprint_option_types(false))
391
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
355
+ build_standard_update_options(opts, options)
392
356
  opts.footer = "Update a blueprint permissions.\n" +
393
357
  "[blueprint] is required. This is the name or id of a blueprint."
394
358
  end
@@ -586,7 +550,7 @@ class Morpheus::Cli::BlueprintsCommand
586
550
  options = {}
587
551
  optparse = Morpheus::Cli::OptionParser.new do |opts|
588
552
  opts.banner = subcommand_usage("[blueprint]")
589
- build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
553
+ build_standard_remove_options(opts, options)
590
554
  opts.footer = "Delete a blueprint." + "\n" +
591
555
  "[blueprint] is required. This is the name or id of a blueprint."
592
556
  end
@@ -2123,6 +2087,7 @@ class Morpheus::Cli::BlueprintsCommand
2123
2087
  }
2124
2088
 
2125
2089
  print_description_list(description_cols, blueprint)
2090
+ print reset,"\n"
2126
2091
  # print_h2 "Tiers"
2127
2092
  if blueprint["config"] && blueprint["config"]["tiers"] && blueprint["config"]["tiers"].keys.size != 0
2128
2093
  print cyan
@@ -2213,7 +2178,8 @@ class Morpheus::Cli::BlueprintsCommand
2213
2178
  else
2214
2179
  #print white,"\nTemplate is empty, use `blueprints add-tier \"#{blueprint['name']}\"`",reset,"\n"
2215
2180
  end
2216
- print reset,"\n"
2181
+ # print reset,"\n"
2182
+ print reset
2217
2183
  end
2218
2184
 
2219
2185
  # this parses the environments => groups => clouds tree structure
@@ -570,16 +570,16 @@ class Morpheus::Cli::BudgetsCommand
570
570
  {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 1},
571
571
  # {'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'defaultValue' => true},
572
572
  {'fieldName' => 'scope', 'fieldLabel' => 'Scope', 'code' => 'budget.scope', 'type' => 'select', 'selectOptions' => [{'name'=>'Account','value'=>'account'},{'name'=>'Tenant','value'=>'tenant'},{'name'=>'Cloud','value'=>'cloud'},{'name'=>'Group','value'=>'group'},{'name'=>'User','value'=>'user'}], 'defaultValue' => 'account', 'required' => true, 'displayOrder' => 3},
573
- {'fieldName' => 'tenant', 'fieldLabel' => 'Tenant', 'type' => 'select', 'optionSource' => lambda {
573
+ {'fieldName' => 'tenant', 'fieldLabel' => 'Tenant', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
574
574
  @options_interface.options_for_source("tenants", {})['data']
575
575
  }, 'required' => true, 'dependsOnCode' => 'budget.scope:tenant', 'displayOrder' => 4},
576
- {'fieldName' => 'user', 'fieldLabel' => 'User', 'type' => 'select', 'optionSource' => lambda {
576
+ {'fieldName' => 'user', 'fieldLabel' => 'User', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
577
577
  @options_interface.options_for_source("users", {})['data']
578
578
  }, 'required' => true, 'dependsOnCode' => 'budget.scope:user', 'displayOrder' => 5},
579
- {'fieldName' => 'group', 'fieldLabel' => 'Group', 'type' => 'select', 'optionSource' => lambda {
579
+ {'fieldName' => 'group', 'fieldLabel' => 'Group', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
580
580
  @options_interface.options_for_source("groups", {})['data']
581
581
  }, 'required' => true, 'dependsOnCode' => 'budget.scope:group', 'displayOrder' => 6},
582
- {'fieldName' => 'cloud', 'fieldLabel' => 'Cloud', 'type' => 'select', 'optionSource' => lambda {
582
+ {'fieldName' => 'cloud', 'fieldLabel' => 'Cloud', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
583
583
  @options_interface.options_for_source("clouds", {})['data']
584
584
  }, 'required' => true, 'dependsOnCode' => 'budget.scope:cloud', 'displayOrder' => 7},
585
585
  {'fieldName' => 'year', 'fieldLabel' => 'Period', 'type' => 'text', 'required' => true, 'defaultValue' => Time.now.year, 'description' => "The period (year) the budget applies to. Default is the current year.", 'displayOrder' => 8},
@@ -524,6 +524,12 @@ module Morpheus
524
524
  end
525
525
  end
526
526
 
527
+ when :find_by_name
528
+ opts.on('--find-by-name', "Always treat the identifier argument as a name, never an ID. Useful for specifying names that look like numbers. eg. '1234'" ) do
529
+ options[:find_by_name] = true
530
+ end
531
+ # opts.add_hidden_option('--find-by-name') if opts.is_a?(Morpheus::Cli::OptionParser)
532
+
527
533
  when :remote
528
534
  opts.on( '-r', '--remote REMOTE', "Remote name. The current remote is used by default." ) do |val|
529
535
  options[:remote] = val
@@ -1237,17 +1243,18 @@ module Morpheus
1237
1243
  end
1238
1244
  end
1239
1245
  if options[:outfile]
1246
+ full_outfile = File.expand_path(options[:outfile])
1240
1247
  if output
1241
1248
  print_to_file(output, options[:outfile], options[:overwrite])
1242
- print "#{cyan}Wrote output to file #{options[:outfile]} (#{File.size(options[:outfile])} B)\n" unless options[:quiet]
1249
+ print "#{cyan}Wrote output to file #{options[:outfile]} (#{File.size(full_outfile)} B)\n" unless options[:quiet]
1243
1250
  else
1244
1251
  # uhhh ok lets try this
1245
- Morpheus::Logging::DarkPrinter.puts "using experimental feature: --outfile without a common format like json, yml or csv" if Morpheus::Logging.debug?
1252
+ Morpheus::Logging::DarkPrinter.puts "using experimental feature: --out without a common format like json, yml or csv" if Morpheus::Logging.debug?
1246
1253
  result = with_stdout_to_file(options[:outfile], options[:overwrite], 'w+', &block)
1247
- print "#{cyan}Wrote output to file #{options[:outfile]} (#{File.size(options[:outfile])} B)\n" unless options[:quiet]
1248
- if result
1254
+ if result && result != 0
1249
1255
  return result
1250
1256
  end
1257
+ print "#{cyan}Wrote output to file #{options[:outfile]} (#{File.size(full_outfile)} B)\n" unless options[:quiet]
1251
1258
  return 0, nil
1252
1259
  end
1253
1260
  else
@@ -326,6 +326,9 @@ class Morpheus::Cli::CloudResourcePoolsCommand
326
326
  opts.on('--active [on|off]', String, "Can be used to disable a resource pool") do |val|
327
327
  options['active'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
328
328
  end
329
+ opts.on('--default-pool [on|off]', String, "Set resource pool as the default") do |val|
330
+ options['defaultPool'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
331
+ end
329
332
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
330
333
  opts.footer = "Update a resource pool." + "\n" +
331
334
  "[cloud] is required. This is the name or id of the cloud."
@@ -437,6 +440,11 @@ class Morpheus::Cli::CloudResourcePoolsCommand
437
440
  else
438
441
  payload['resourcePool']['active'] = true
439
442
  end
443
+
444
+ # Default
445
+ if options['defaultPool'] != nil
446
+ payload['resourcePool']['defaultPool'] = options['defaultPool']
447
+ end
440
448
 
441
449
  # Visibility
442
450
  if options['visibility'] != nil
@@ -552,6 +560,9 @@ class Morpheus::Cli::CloudResourcePoolsCommand
552
560
  opts.on('--active [on|off]', String, "Can be used to disable a resource pool") do |val|
553
561
  options['active'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
554
562
  end
563
+ opts.on('--default-pool [on|off]', String, "Set resource pool as the default") do |val|
564
+ options['defaultPool'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
565
+ end
555
566
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
556
567
  opts.footer = "Update a resource pool." + "\n" +
557
568
  "[cloud] is required. This is the name or id of the cloud." + "\n"
@@ -641,6 +652,11 @@ class Morpheus::Cli::CloudResourcePoolsCommand
641
652
  if options['active'] != nil
642
653
  payload['resourcePool']['active'] = options['active']
643
654
  end
655
+
656
+ # Default
657
+ if options['defaultPool'] != nil
658
+ payload['resourcePool']['defaultPool'] = options['defaultPool']
659
+ end
644
660
 
645
661
  # Visibility
646
662
  if options['visibility'] != nil
@@ -46,11 +46,15 @@ class Morpheus::Cli::Clouds
46
46
  opts.on( '-t', '--type TYPE', "Cloud Type" ) do |val|
47
47
  options[:zone_type] = val
48
48
  end
49
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
49
+ build_standard_list_options(opts, options)
50
50
  opts.footer = "List clouds."
51
51
  end
52
52
  optparse.parse!(args)
53
53
  connect(options)
54
+ # verify_args!(args:args, optparse:optparse, count:0)
55
+ if args.count > 0
56
+ options[:phrase] = args.join(" ")
57
+ end
54
58
  begin
55
59
  if options[:zone_type]
56
60
  cloud_type = cloud_type_for_name(options[:zone_type])
@@ -71,15 +75,7 @@ class Morpheus::Cli::Clouds
71
75
  end
72
76
 
73
77
  json_response = @clouds_interface.list(params)
74
- if options[:json]
75
- puts as_json(json_response, options, "zones")
76
- return 0
77
- elsif options[:yaml]
78
- puts as_yaml(json_response, options, "zones")
79
- return 0
80
- elsif options[:csv]
81
- puts records_as_csv(json_response['zones'], options)
82
- else
78
+ render_response(json_response, options, 'zones') do
83
79
  clouds = json_response['zones']
84
80
  title = "Morpheus Clouds"
85
81
  subtitles = []
@@ -99,6 +95,7 @@ class Morpheus::Cli::Clouds
99
95
  end
100
96
  print reset,"\n"
101
97
  end
98
+ return 0, nil
102
99
  rescue RestClient::Exception => e
103
100
  print_rest_exception(e, options)
104
101
  exit 1
@@ -9,15 +9,20 @@ class Morpheus::Cli::CurlCommand
9
9
  set_command_hidden
10
10
 
11
11
  def handle(args)
12
- split_args = args.join(" ").split(" -- ")
13
- args = split_args[0].split(" ")
14
- curl_args = split_args[1] ? split_args[1].split(" ") : []
12
+ # support syntax for arbitrary curl args after " -- "
13
+ # eg. curl /api/instances -- -ksv
14
+ split_index = args.index("--")
15
+ curl_args = []
16
+ if split_index
17
+ if args.length > (split_index + 1)
18
+ curl_args = args[(split_index + 1)..-1]
19
+ end
20
+ args = args[0..(split_index - 1)]
21
+ end
15
22
  curl_method = nil
16
23
  curl_data = nil
17
24
  curl_verbsose = false
18
25
  show_progress = false
19
- # puts "args is : #{args}"
20
- # puts "curl_args is : #{curl_args}"
21
26
  options = {}
22
27
  optparse = Morpheus::Cli::OptionParser.new do|opts|
23
28
  opts.banner = "Usage: morpheus curl [path] -- [*args]"
@@ -98,16 +103,27 @@ EOT
98
103
  end
99
104
  curl_cmd << " \"#{url}\""
100
105
  if @access_token
101
- curl_cmd << " -H \"Authorization: Bearer #{@access_token}\""
106
+ if !(options[:headers] && options[:headers]['Authorization'])
107
+ curl_cmd << " -H \"Authorization: Bearer #{@access_token}\""
108
+ end
102
109
  end
103
110
  if curl_data
104
111
  #todo: curl_data.gsub("'","\\'")
105
112
  curl_cmd << " --data '#{curl_data}'"
113
+ if api_path !~ /^\/?oauth/
114
+ if !(options[:headers] && options[:headers]['Content-Type'])
115
+ curl_cmd << " -H \"Content-Type: application/json\""
116
+ end
117
+ end
118
+ end
119
+ if options[:headers]
120
+ options[:headers].each do |k,v|
121
+ curl_cmd << " -H \"#{k}: #{v}\""
122
+ end
106
123
  end
107
124
  if !curl_args.empty?
108
125
  curl_cmd << " " + curl_args.join(' ')
109
126
  end
110
-
111
127
  # Morpheus::Logging::DarkPrinter.puts "#{curl_cmd}" if Morpheus::Logging.debug?
112
128
  curl_cmd_str = options[:scrub] ? Morpheus::Logging.scrub_message(curl_cmd) : curl_cmd
113
129
 
@@ -388,7 +388,7 @@ EOT
388
388
  deployment = find_deployment_by_name_or_id(args[0])
389
389
  return 1 if deployment.nil?
390
390
  else
391
- deployment_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'deploymentId', 'fieldLabel' => 'Deployment', 'type' => 'select', 'required' => true, 'description' => 'Deployment to add version to', 'optionSource' => lambda {
391
+ deployment_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'deploymentId', 'fieldLabel' => 'Deployment', 'type' => 'select', 'required' => true, 'description' => 'Deployment to add version to', 'optionSource' => lambda { |api_client, api_params|
392
392
  @deployments_interface.list(max:10000)['deployments'].collect {|it|
393
393
  {'name' => it['name'], 'value' => it['id']}
394
394
  }
@@ -44,7 +44,7 @@ class Morpheus::Cli::InvoicesCommand
44
44
  opts.on('--prices', '--prices', "Display prices: Total, Compute, Storage, Network, Extra" ) do
45
45
  options[:show_prices] = true
46
46
  end
47
- opts.on('--type TYPE', String, "Filter by Ref Type eg. ComputeSite (Group), ComputeZone (Cloud), ComputeServer (Host), Instance, Container, User") do |val|
47
+ opts.on('-t', '--type TYPE', "Filter by Ref Type eg. ComputeSite (Group), ComputeZone (Cloud), ComputeServer (Host), Instance, Container, User") do |val|
48
48
  params['refType'] ||= []
49
49
  values = val.split(",").collect {|it| it.strip }.select {|it| it != "" }
50
50
  values.each { |it| params['refType'] << parse_invoice_ref_type(it) }
@@ -193,9 +193,8 @@ class Morpheus::Cli::InvoicesCommand
193
193
  subtitles += parse_list_subtitles(options)
194
194
  print_h1 title, subtitles
195
195
  if invoices.empty?
196
- unless options[:totals_only]
197
- print cyan,"No invoices found.",reset,"\n"
198
- end
196
+ print cyan,"No invoices found.",reset,"\n"
197
+ print reset,"\n"
199
198
  else
200
199
  # current_date = Time.now
201
200
  # current_period = "#{current_date.year}#{current_date.month.to_s.rjust(2, '0')}"
@@ -300,8 +299,8 @@ class Morpheus::Cli::InvoicesCommand
300
299
  end
301
300
  if options[:show_estimates]
302
301
  cost_rows += [
303
- {label: 'Estimated Cost'.upcase, compute: invoice_totals['estimatedComputeCost'], memory: invoice_totals['estimatedMemoryCost'], storage: invoice_totals['estimatedStorageCost'], network: invoice_totals['estimatedNetworkCost'], license: invoice_totals['estimatedLicenseCost'], extra: invoice_totals['estimatedExtraCost'], running: invoice_totals['estimatedRunningCost'], total: invoice_totals['estimatedTotalCost']},
304
- {label: 'Estimated Price'.upcase, compute: invoice_totals['estimatedComputePrice'], memory: invoice_totals['estimatedMemoryPrice'], storage: invoice_totals['estimatedStoragePrice'], network: invoice_totals['estimatedNetworkPrice'], license: invoice_totals['estimatedLicensePrice'], extra: invoice_totals['estimatedExtraPrice'], running: invoice_totals['estimatedRunningPrice'], total: invoice_totals['estimatedTotalPrice']},
302
+ {label: 'Metered Cost'.upcase, compute: invoice_totals['estimatedComputeCost'], memory: invoice_totals['estimatedMemoryCost'], storage: invoice_totals['estimatedStorageCost'], network: invoice_totals['estimatedNetworkCost'], license: invoice_totals['estimatedLicenseCost'], extra: invoice_totals['estimatedExtraCost'], running: invoice_totals['estimatedRunningCost'], total: invoice_totals['estimatedTotalCost']},
303
+ {label: 'Metered Price'.upcase, compute: invoice_totals['estimatedComputePrice'], memory: invoice_totals['estimatedMemoryPrice'], storage: invoice_totals['estimatedStoragePrice'], network: invoice_totals['estimatedNetworkPrice'], license: invoice_totals['estimatedLicensePrice'], extra: invoice_totals['estimatedExtraPrice'], running: invoice_totals['estimatedRunningPrice'], total: invoice_totals['estimatedTotalPrice']},
305
304
  ]
306
305
  end
307
306
  cost_columns = {
@@ -534,8 +533,8 @@ EOT
534
533
  end
535
534
  if options[:show_estimates]
536
535
  cost_rows += [
537
- {label: 'Estimated Cost'.upcase, compute: invoice['estimatedComputeCost'], memory: invoice['estimatedMemoryCost'], storage: invoice['estimatedStorageCost'], network: invoice['estimatedNetworkCost'], license: invoice['estimatedLicenseCost'], extra: invoice['estimatedExtraCost'], running: invoice['estimatedRunningCost'], total: invoice['estimatedTotalCost']},
538
- {label: 'Estimated Price'.upcase, compute: invoice['estimatedComputePrice'], memory: invoice['estimatedMemoryPrice'], storage: invoice['estimatedStoragePrice'], network: invoice['estimatedNetworkPrice'], license: invoice['estimatedLicensePrice'], extra: invoice['estimatedExtraPrice'], running: invoice['estimatedRunningPrice'], total: invoice['estimatedTotalPrice']},
536
+ {label: 'Metered Cost'.upcase, compute: invoice['estimatedComputeCost'], memory: invoice['estimatedMemoryCost'], storage: invoice['estimatedStorageCost'], network: invoice['estimatedNetworkCost'], license: invoice['estimatedLicenseCost'], extra: invoice['estimatedExtraCost'], running: invoice['estimatedRunningCost'], total: invoice['estimatedTotalCost']},
537
+ {label: 'Metered Price'.upcase, compute: invoice['estimatedComputePrice'], memory: invoice['estimatedMemoryPrice'], storage: invoice['estimatedStoragePrice'], network: invoice['estimatedNetworkPrice'], license: invoice['estimatedLicensePrice'], extra: invoice['estimatedExtraPrice'], running: invoice['estimatedRunningPrice'], total: invoice['estimatedTotalPrice']},
539
538
  ]
540
539
  end
541
540
  cost_columns = {
@@ -683,7 +682,7 @@ EOT
683
682
  params['externalId'] ||= []
684
683
  params['externalId'] << val
685
684
  end
686
- opts.on('--type TYPE', String, "Filter by Ref Type eg. ComputeSite (Group), ComputeZone (Cloud), ComputeServer (Host), Instance, Container, User") do |val|
685
+ opts.on('-t', '--type TYPE', "Filter by Ref Type eg. ComputeSite (Group), ComputeZone (Cloud), ComputeServer (Host), Instance, Container, User") do |val|
687
686
  params['refType'] ||= []
688
687
  values = val.split(",").collect {|it| it.strip }.select {|it| it != "" }
689
688
  values.each { |it| params['refType'] << parse_invoice_ref_type(it) }
@@ -102,15 +102,15 @@ class Morpheus::Cli::JobsCommand
102
102
  if stats = json_response['stats']
103
103
  label_width = 17
104
104
 
105
- print_h2 "Executions Stats - Last 7 Days"
105
+ print_h2 "Execution Stats - Last 7 Days"
106
106
  print cyan
107
107
 
108
108
  print "Jobs".rjust(label_width, ' ') + ": #{stats['jobCount']}\n"
109
109
  print "Executions Today".rjust(label_width, ' ') + ": #{stats['todayCount']}\n"
110
110
  print "Daily Executions".rjust(label_width, ' ') + ": " + stats['executionsPerDay'].join(' | ') + "\n"
111
111
  print "Total Executions".rjust(label_width, ' ') + ": #{stats['execCount']}\n"
112
- print "Completed".rjust(label_width, ' ') + ": " + generate_usage_bar(stats['execSuccessRate'].to_f, 100) + "#{stats['execSuccess']}".rjust(15, ' ') + " of " + "#{stats['execCount']}".ljust(15, ' ') + "\n#{cyan}"
113
- print "Failed".rjust(label_width, ' ') + ": " + generate_usage_bar(stats['execFailedRate'].to_f, 100) + "#{stats['execFailed']}".rjust(15, ' ') + " of " + "#{stats['execCount']}".ljust(15, ' ') + "\n#{cyan}"
112
+ print "Completed".rjust(label_width, ' ') + ": " + generate_usage_bar(stats['execSuccessRate'].to_f, 100, {bar_color:green}) + "#{stats['execSuccess']}".rjust(15, ' ') + " of " + "#{stats['execCount']}".ljust(15, ' ') + "\n#{cyan}"
113
+ print "Failed".rjust(label_width, ' ') + ": " + generate_usage_bar(stats['execFailedRate'].to_f, 100, {bar_color:red}) + "#{stats['execFailed']}".rjust(15, ' ') + " of " + "#{stats['execCount']}".ljust(15, ' ') + "\n#{cyan}"
114
114
  end
115
115
  print reset,"\n"
116
116
  end
@@ -304,7 +304,7 @@ class Morpheus::Cli::JobsCommand
304
304
  job_options = @jobs_interface.options(job_type_id)
305
305
 
306
306
  # prompt task / workflow
307
- if job_type['code'] == 'morpheus.task'
307
+ if ['morpheus.task.jobType', 'morpheus.task'].include?(job_type['code'])
308
308
  params['task'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'task.id', 'fieldLabel' => 'Task', 'type' => 'select', 'required' => true, 'optionSource' => 'tasks'}], options[:options], @api_client, {})['task']
309
309
  else
310
310
  params['workflow'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'workflow.id', 'fieldLabel' => 'Workflow', 'type' => 'select', 'required' => true, 'optionSource' => 'operationTaskSets'}], options[:options], @api_client, {})['workflow']
@@ -320,10 +320,11 @@ class Morpheus::Cli::JobsCommand
320
320
  exit 1
321
321
  end
322
322
  params['task'] = {'id' => task['id']}
323
- job_type_id = load_job_type_id_by_code('morpheus.task')
323
+ job_type_id = load_job_type_id_by_code('morpheus.task.jobType') || load_job_type_id_by_code('morpheus.task')
324
324
  end
325
325
 
326
326
  # workflow
327
+ task_set = nil
327
328
  if !options[:workflow].nil?
328
329
  task_set = find_by_name_or_id('task_set', options[:workflow])
329
330
 
@@ -332,8 +333,29 @@ class Morpheus::Cli::JobsCommand
332
333
  exit 1
333
334
  end
334
335
  params['workflow'] = {'id' => task_set['id']}
335
- job_type_id = load_job_type_id_by_code('morpheus.workflow')
336
+ job_type_id = load_job_type_id_by_code('morpheus.workflow.jobType') || load_job_type_id_by_code('morpheus.workflow')
336
337
  end
338
+ # load workflow if we havent yet
339
+ if (params['workflow'] && params['workflow']['id']) && task_set.nil?
340
+ task_set = find_by_name_or_id('task_set', params['workflow']['id'])
341
+ if task_set.nil?
342
+ print_red_alert "Workflow #{params['workflow']['id']} not found"
343
+ exit 1
344
+ end
345
+ end
346
+ # prompt for custom options for workflow
347
+ custom_option_types = task_set ? task_set['optionTypes'] : nil
348
+ if custom_option_types && custom_option_types.size() > 0
349
+ # they are all returned in a single array right now, so skip prompting for the jobType optionTypes
350
+ custom_option_types.reject! { |it| it['code'] && it['code'].include?('job.type') }
351
+ custom_option_types = custom_option_types.collect {|it|
352
+ it['fieldContext'] = 'customOptions'
353
+ it
354
+ }
355
+ custom_options = Morpheus::Cli::OptionTypes.prompt(custom_option_types, options[:options], @api_client, {})
356
+ params['customOptions'] = custom_options['customOptions']
357
+ end
358
+
337
359
 
338
360
  # load options based upon job type + task / taskset
339
361
  job_options = @jobs_interface.options(job_type_id, {'taskId' => params['task'] ? params['task']['id'] : nil, 'workflowId' => params['workflow'] ? params['workflow']['id'] : nil})
@@ -768,7 +790,7 @@ class Morpheus::Cli::JobsCommand
768
790
  params = {}
769
791
  optparse = Morpheus::Cli::OptionParser.new do |opts|
770
792
  opts.banner = subcommand_usage("[id]")
771
- opts.on('-D', '--details [on|off]', String, "Can be used to enable / disable execution details. Default if on") do |val|
793
+ opts.on('-D', '--details [on|off]', String, "Can be used to enable / disable execution details. Default is on") do |val|
772
794
  options[:details] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
773
795
  end
774
796
  build_common_options(opts, options, [:json, :dry_run, :remote])
@@ -970,7 +992,7 @@ class Morpheus::Cli::JobsCommand
970
992
  def format_status(status_string, return_color=cyan)
971
993
  out = ""
972
994
  if status_string
973
- if ['success', 'successful', 'ok'].include?(status_string)
995
+ if ['complete','success', 'successful', 'ok'].include?(status_string)
974
996
  out << "#{green}#{status_string.upcase}"
975
997
  elsif ['error', 'offline', 'failed', 'failure'].include?(status_string)
976
998
  out << "#{red}#{status_string.upcase}"
@@ -244,15 +244,14 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
244
244
  options = {}
245
245
  params = {}
246
246
  logo_file = nil
247
- option_type_ids = nil
248
247
  optparse = Morpheus::Cli::OptionParser.new do|opts|
249
248
  opts.banner = subcommand_usage("[name]")
250
249
  build_option_type_options(opts, options, add_instance_type_option_types())
251
250
  opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |list|
252
251
  if list.nil?
253
- option_type_ids = []
252
+ params['optionTypes'] = []
254
253
  else
255
- option_type_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
254
+ params['optionTypes'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
256
255
  end
257
256
  end
258
257
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
@@ -348,6 +347,13 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
348
347
  opts.banner = subcommand_usage("[name] [options]")
349
348
  build_option_type_options(opts, options, update_instance_type_option_types())
350
349
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
350
+ opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |list|
351
+ if list.nil?
352
+ params['optionTypes'] = []
353
+ else
354
+ params['optionTypes'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
355
+ end
356
+ end
351
357
  opts.footer = "Update an instance type." + "\n" +
352
358
  "[name] is required. This is the name or id of a instance type."
353
359
  end
@@ -375,6 +381,14 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
375
381
  params['hasSettings'] = ['on','true','1'].include?(params['hasSettings'].to_s) if params.key?('hasSettings')
376
382
  params['hasAutoScale'] = ['on','true','1'].include?(params['hasAutoScale'].to_s) if params.key?('hasAutoScale')
377
383
  params['hasDeployment'] = ['on','true','1'].include?(params['hasDeployment'].to_s) if params.key?('hasDeployment')
384
+ if params['optionTypes']
385
+ prompt_results = prompt_for_option_types(params, options, @api_client)
386
+ if prompt_results[:success]
387
+ params['optionTypes'] = prompt_results[:data] unless prompt_results[:data].nil?
388
+ else
389
+ return 1
390
+ end
391
+ end
378
392
  if params.empty?
379
393
  puts optparse
380
394
  #option_lines = update_instance_type_option_types.collect {|it| "\t-O #{it['fieldName']}=\"value\"" }.join("\n")
@@ -596,22 +596,28 @@ class Morpheus::Cli::NetworkPoolsCommand
596
596
  def add_ip(args)
597
597
  options = {}
598
598
  params = {}
599
+ next_free_ip = false
599
600
  optparse = Morpheus::Cli::OptionParser.new do |opts|
600
- opts.banner = subcommand_usage("[network-pool] [ip]")
601
+ opts.banner = subcommand_usage("[network-pool] [ip] [--next]")
601
602
  opts.on('--ip-address VALUE', String, "IP Address for this network pool IP") do |val|
602
603
  options[:options]['ipAddress'] = val
603
604
  end
605
+ opts.on('--next-free-ip', '--next-free-ip', "Use the next available ip address. This can be used instead of specifying an ip address") do
606
+ next_free_ip = true
607
+ end
604
608
  opts.on('--hostname VALUE', String, "Hostname for this network pool IP") do |val|
605
609
  options[:options]['hostname'] = val
606
610
  end
607
611
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
608
612
  opts.footer = "Create a new network pool IP." + "\n" +
609
613
  "[network-pool] is required. This is the name or id of a network pool.\n" +
610
- "[ip] is required and can be passed as --ip-address instead."
614
+ "[ip] is required or --next-free-ip to use the next available address instead."
611
615
  end
612
616
  optparse.parse!(args)
613
- if args.count < 1 || args.count > 2
614
- raise_command_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args}\n#{optparse}"
617
+ if next_free_ip
618
+ verify_args!(args:args, count:1, optparse:optparse)
619
+ else
620
+ verify_args!(args:args, min:1, max:2, optparse:optparse)
615
621
  end
616
622
  connect(options)
617
623
  begin
@@ -639,8 +645,10 @@ class Morpheus::Cli::NetworkPoolsCommand
639
645
  payload['networkPoolIp'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
640
646
 
641
647
  # IP Address
642
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ipAddress', 'fieldLabel' => 'IP Address', 'type' => 'text', 'required' => true, 'description' => 'IP Address for this network pool IP.'}], options[:options])
643
- payload['networkPoolIp']['ipAddress'] = v_prompt['ipAddress'] unless v_prompt['ipAddress'].to_s.empty?
648
+ unless next_free_ip
649
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ipAddress', 'fieldLabel' => 'IP Address', 'type' => 'text', 'required' => true, 'description' => 'IP Address for this network pool IP.'}], options[:options])
650
+ payload['networkPoolIp']['ipAddress'] = v_prompt['ipAddress'] unless v_prompt['ipAddress'].to_s.empty?
651
+ end
644
652
 
645
653
  # Hostname
646
654
  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'hostname', 'fieldLabel' => 'Hostname', 'type' => 'text', 'required' => true, 'description' => 'Hostname for this network pool IP.'}], options[:options])
@@ -102,7 +102,7 @@ EOT
102
102
  options = {}
103
103
  optparse = Morpheus::Cli::OptionParser.new do |opts|
104
104
  opts.banner = subcommand_usage("[project]")
105
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
105
+ build_standard_get_options(opts, options, [:find_by_name])
106
106
  opts.footer = <<-EOT
107
107
  Get details about a project.
108
108
  [project] is required. This is the name or id of a project.
@@ -127,8 +127,8 @@ EOT
127
127
  end
128
128
  return
129
129
  end
130
- project = find_project_by_name_or_id(id)
131
- exit 1 if project.nil?
130
+ project = options[:find_by_name] ? find_project_by_name(id) : find_project_by_name_or_id(id)
131
+ return 1, "project not found by '#{id}'" if project.nil?
132
132
  # refetch it by id
133
133
  json_response = {'project' => project}
134
134
  unless id.to_s =~ /\A\d{1,}\Z/
@@ -332,7 +332,7 @@ EOT
332
332
  opts.on('--remove-resources LIST', Array, "Remove Resources, comma separated list of resource names or IDs to remove.") do |list|
333
333
  remove_resource_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
334
334
  end
335
- build_standard_update_options(opts, options)
335
+ build_standard_update_options(opts, options, [:find_by_name])
336
336
  opts.footer = <<-EOT
337
337
  Update a project.
338
338
  [project] is required. This is the name or id of a project.
@@ -342,7 +342,7 @@ EOT
342
342
  verify_args!(args:args, optparse:optparse, count:1)
343
343
  connect(options)
344
344
  exit_code, err = 0, nil
345
- project = find_project_by_name_or_id(args[0])
345
+ project = options[:find_by_name] ? find_project_by_name(args[0]) : find_project_by_name_or_id(args[0])
346
346
  return 1, "project not found by '#{args[0]}'" if project.nil?
347
347
  # construct payload
348
348
  if options[:payload]
@@ -433,7 +433,7 @@ EOT
433
433
  options = {}
434
434
  optparse = Morpheus::Cli::OptionParser.new do |opts|
435
435
  opts.banner = subcommand_usage("[project]")
436
- build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
436
+ build_standard_remove_options(opts, options, [:find_by_name])
437
437
  # opts.on( '-f', '--force', "Force Delete" ) do
438
438
  # params[:force] = true
439
439
  # end
@@ -446,7 +446,7 @@ EOT
446
446
  verify_args!(args:args, optparse:optparse, count:1)
447
447
  connect(options)
448
448
  exit_code, err = 0, nil
449
- project = find_project_by_name_or_id(args[0])
449
+ project = options[:find_by_name] ? find_project_by_name(args[0]) : find_project_by_name_or_id(args[0])
450
450
  return 1, "project not found by '#{args[0]}'" if project.nil?
451
451
  unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the project #{project['name']}?")
452
452
  return 9, "aborted command"
@@ -478,7 +478,7 @@ class Morpheus::Cli::ProvisioningLicensesCommand
478
478
 
479
479
  def add_license_option_types
480
480
  [
481
- {'fieldName' => 'licenseType', 'fieldLabel' => 'License Type', 'type' => 'select', 'optionSource' => lambda {
481
+ {'fieldName' => 'licenseType', 'fieldLabel' => 'License Type', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
482
482
  # @options_interface.options_for_source("licenseTypes", {})['data']
483
483
  get_license_types_dropdown()
484
484
  }, 'required' => true, 'displayOrder' => 1},
@@ -493,7 +493,7 @@ class Morpheus::Cli::ProvisioningLicensesCommand
493
493
  # @options_interface.options_for_source("virtualImages", {})['data']
494
494
  get_virtual_images_dropdown()
495
495
  }, 'displayOrder' => 9},
496
- {'fieldName' => 'tenants', 'fieldLabel' => 'Tenants', 'type' => 'multiSelect', 'optionSource' => lambda {
496
+ {'fieldName' => 'tenants', 'fieldLabel' => 'Tenants', 'type' => 'multiSelect', 'optionSource' => lambda { |api_client, api_params|
497
497
  @options_interface.options_for_source("allTenants", {})['data']
498
498
  }, 'displayOrder' => 10},
499
499
  ]
@@ -409,9 +409,9 @@ class Morpheus::Cli::ServicePlanCommand
409
409
  while Morpheus::Cli::OptionTypes.confirm("Add #{price_sets.empty? ? '' : 'another '}price set?", {:default => false}) do
410
410
  price_unit = prompt_price_unit(options)
411
411
 
412
- avail_price_sets ||= @price_sets_interface.list['priceSets'].collect {|it| {'name' => it['name'], 'value' => it['id'], 'priceUnit' => it['priceUnit']}}
412
+ avail_price_sets ||= @price_sets_interface.list({'priceUnit' => price_unit, 'max' => 10000})['priceSets'].collect {|it| {'name' => it['name'], 'value' => it['id'], 'priceUnit' => it['priceUnit']}}
413
413
 
414
- if price_set_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'priceSet', 'type' => 'select', 'fieldLabel' => 'Price Set', 'selectOptions' => avail_price_sets.reject {|it| it['priceUnit'] != price_unit}, 'required' => false, 'description' => 'Select Price.'}],options[:options],@api_client,{}, options[:no_prompt], true)['priceSet']
414
+ if price_set_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'priceSet', 'type' => 'select', 'fieldLabel' => 'Price Set', 'selectOptions' => avail_price_sets, 'required' => false, 'description' => 'Select Price.'}],options[:options],@api_client,{}, options[:no_prompt], true)['priceSet']
415
415
  price_set = avail_price_sets.find {|it| it['value'] == price_set_id}
416
416
  price_sets << {'id' => price_set['value'], 'priceUnit' => price_set['priceUnit']}
417
417
  avail_price_sets.reject! {|it| it['value'] == price_set_id}
@@ -832,6 +832,7 @@ class Morpheus::Cli::Tasks
832
832
  payload = options[:payload]
833
833
  payload.deep_merge!({'job' => passed_options}) unless passed_options.empty?
834
834
  else
835
+ # always parse instances and/or hosts
835
836
  if instance_ids.size > 0 && server_ids.size > 0
836
837
  raise_command_error "Pass --instance or --host, not both.\n#{optparse}"
837
838
  elsif instance_ids.size > 0
@@ -848,19 +849,30 @@ class Morpheus::Cli::Tasks
848
849
  servers << server
849
850
  end
850
851
  params['servers'] = servers.collect {|it| it['id'] }
851
- elsif target_type == 'appliance'
852
- # cool, run it locally.
852
+ end
853
+ # validate requires inputs based on task executeTarget
854
+ if task['executeTarget'] == 'resource'
855
+ if instance_ids.empty? && server_ids.empty?
856
+ # todo: prompt for Context: None,Instance,Server and then Instance(s) or Server(s)
857
+ raise_command_error "missing required option: --instance or --host\n#{optparse}"
858
+ end
859
+ elsif task['executeTarget'] == 'local'
860
+ # no targetType required for local
861
+ elsif task['executeTarget'] == 'remote'
862
+ # not sure about this one
853
863
  else
854
- raise_command_error "missing required option: --instance or --host\n#{optparse}"
864
+ # unknown executeTarget
855
865
  end
866
+
867
+
856
868
 
857
869
  # todo: prompt to task optionTypes for customOptions
858
870
  if task['optionTypes']
859
871
 
860
872
  end
861
-
862
- params['targetType'] = target_type
863
-
873
+ if target_type
874
+ params['targetType'] = target_type
875
+ end
864
876
  job_payload = {}
865
877
  job_payload.deep_merge!(params)
866
878
  job_payload.deep_merge!(passed_options) unless passed_options.empty?
@@ -877,15 +889,17 @@ class Morpheus::Cli::Tasks
877
889
  puts as_json(json_response, options)
878
890
  return json_response['success'] ? 0 : 1
879
891
  else
880
- target_desc = ""
892
+ target_desc = nil
881
893
  if instances.size() > 0
882
894
  target_desc = (instances.size() == 1) ? "instance #{instances[0]['name']}" : "#{instances.size()} instances"
883
895
  elsif servers.size() > 0
884
896
  target_desc = (servers.size() == 1) ? "host #{servers[0]['name']}" : "#{servers.size()} hosts"
885
- elsif target_type == 'appliance'
886
- target_desc = "appliance"
887
897
  end
888
- print_green_success "Executing task #{task['name']} on #{target_desc}"
898
+ if target_desc
899
+ print_green_success "Executing task #{task['name']} on #{target_desc}"
900
+ else
901
+ print_green_success "Executing task #{task['name']}"
902
+ end
889
903
  # todo: refresh, use get processId and load process record isntead? err
890
904
  if json_response["jobExecution"] && json_response["jobExecution"]["id"]
891
905
  get_args = [json_response["jobExecution"]["id"], "--details"] + (options[:remote] ? ["-r",options[:remote]] : [])
@@ -295,7 +295,7 @@ EOT
295
295
  [
296
296
  {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
297
297
  {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
298
- {'fieldContext' => 'role', 'fieldName' => 'id', 'fieldLabel' => 'Base Role', 'type' => 'select', 'optionSource' => lambda {
298
+ {'fieldContext' => 'role', 'fieldName' => 'id', 'fieldLabel' => 'Base Role', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
299
299
  @roles_interface.list(nil, {roleType:'account'})['roles'].collect {|it|
300
300
  {"name" => (it["authority"] || it["name"]), "value" => it["id"]}
301
301
  }
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "4.2.17"
4
+ VERSION = "4.2.22"
5
5
  end
6
6
  end
@@ -619,10 +619,11 @@ class Morpheus::Cli::Workflows
619
619
  elsif target_type == 'appliance'
620
620
  # cool, run it locally.
621
621
  else
622
- raise_command_error "missing required option: --instance, --host or --appliance\n#{optparse}"
622
+ # cool, run it locally.
623
+ #raise_command_error "missing required option: --instance, --host or --appliance\n#{optparse}"
623
624
  end
624
625
 
625
- # todo: prompt to workflow optionTypes for customOptions
626
+ # prompt to workflow optionTypes for customOptions
626
627
  custom_options = nil
627
628
  if workflow['optionTypes'] && workflow['optionTypes'].size() > 0
628
629
  custom_option_types = workflow['optionTypes'].collect {|it|
@@ -631,9 +632,9 @@ class Morpheus::Cli::Workflows
631
632
  }
632
633
  custom_options = Morpheus::Cli::OptionTypes.prompt(custom_option_types, options[:options], @api_client, {})
633
634
  end
634
-
635
- params['targetType'] = target_type
636
-
635
+ if target_type
636
+ params['targetType'] = target_type
637
+ end
637
638
  job_payload = {}
638
639
  job_payload.deep_merge!(params)
639
640
  passed_options.delete('customOptions')
@@ -655,15 +656,17 @@ class Morpheus::Cli::Workflows
655
656
  puts as_json(json_response, options)
656
657
  return json_response['success'] ? 0 : 1
657
658
  else
658
- target_desc = ""
659
+ target_desc = nil
659
660
  if instances.size() > 0
660
661
  target_desc = (instances.size() == 1) ? "instance #{instances[0]['name']}" : "#{instances.size()} instances"
661
662
  elsif servers.size() > 0
662
663
  target_desc = (servers.size() == 1) ? "host #{servers[0]['name']}" : "#{servers.size()} hosts"
663
- elsif target_type == 'appliance'
664
- target_desc = "appliance"
665
664
  end
666
- print_green_success "Executing workflow #{workflow['name']} on #{target_desc}"
665
+ if target_desc
666
+ print_green_success "Executing workflow #{workflow['name']} on #{target_desc}"
667
+ else
668
+ print_green_success "Executing workflow #{workflow['name']}"
669
+ end
667
670
  # todo: refresh, use get processId and load process record isntead? err
668
671
  if json_response["jobExecution"] && json_response["jobExecution"]["id"]
669
672
  get_args = [json_response["jobExecution"]["id"], "--details"] + (options[:remote] ? ["-r",options[:remote]] : [])
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: 4.2.17
4
+ version: 4.2.22
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: 2020-08-17 00:00:00.000000000 Z
14
+ date: 2020-09-13 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler