morpheus-cli 4.2.17 → 4.2.22

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
  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