morpheus-cli 5.3.2.3 → 5.3.3

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.
@@ -222,52 +222,52 @@ class Morpheus::Cli::InvoicesCommand
222
222
  # {"LAST COST DATE" => lambda {|it| format_local_dt(it['lastCostDate']) } },
223
223
  # {"LAST ACTUAL DATE" => lambda {|it| format_local_dt(it['lastActualDate']) } },
224
224
  ] : []) + [
225
- {"COMPUTE PRICE" => lambda {|it| format_money(it['computePrice'], 'usd', {sigdig:options[:sigdig]}) } },
226
- {"MEMORY PRICE" => lambda {|it| format_money(it['memoryPrice'], 'usd', {sigdig:options[:sigdig]}) } },
227
- {"STORAGE PRICE" => lambda {|it| format_money(it['storagePrice'], 'usd', {sigdig:options[:sigdig]}) } },
228
- {"NETWORK PRICE" => lambda {|it| format_money(it['networkPrice'], 'usd', {sigdig:options[:sigdig]}) } },
229
- {"EXTRA PRICE" => lambda {|it| format_money(it['extraPrice'], 'usd', {sigdig:options[:sigdig]}) } },
230
- {"MTD PRICE" => lambda {|it| format_money(it['runningPrice'], 'usd', {sigdig:options[:sigdig]}) } },
225
+ {"COMPUTE PRICE" => lambda {|it| format_money(it['computePrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
226
+ {"MEMORY PRICE" => lambda {|it| format_money(it['memoryPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
227
+ {"STORAGE PRICE" => lambda {|it| format_money(it['storagePrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
228
+ {"NETWORK PRICE" => lambda {|it| format_money(it['networkPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
229
+ {"EXTRA PRICE" => lambda {|it| format_money(it['extraPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
230
+ {"MTD PRICE" => lambda {|it| format_money(it['runningPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
231
231
  {"TOTAL PRICE" => lambda {|it|
232
- format_money(it['totalPrice'], 'usd', {sigdig:options[:sigdig]}) + ((it['totalCost'].to_f > 0 && it['totalCost'] != it['runningCost']) ? " (Projected)" : "")
232
+ format_money(it['totalPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) + ((it['totalCost'].to_f > 0 && it['totalCost'] != it['runningCost']) ? " (Projected)" : "")
233
233
  } }
234
234
  ]
235
235
 
236
236
  if options[:show_costs] && json_response['masterAccount'] != false
237
237
  columns += [
238
- {"COMPUTE COST" => lambda {|it| format_money(it['computeCost'], 'usd', {sigdig:options[:sigdig]}) } },
238
+ {"COMPUTE COST" => lambda {|it| format_money(it['computeCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
239
239
  {"MEMORY COST" => lambda {|it| format_money(it['memoryCost']) } },
240
- {"STORAGE COST" => lambda {|it| format_money(it['storageCost'], 'usd', {sigdig:options[:sigdig]}) } },
241
- {"NETWORK COST" => lambda {|it| format_money(it['networkCost'], 'usd', {sigdig:options[:sigdig]}) } },
242
- {"EXTRA COST" => lambda {|it| format_money(it['extraCost'], 'usd', {sigdig:options[:sigdig]}) } },
243
- {"MTD COST" => lambda {|it| format_money(it['runningCost'], 'usd', {sigdig:options[:sigdig]}) } },
240
+ {"STORAGE COST" => lambda {|it| format_money(it['storageCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
241
+ {"NETWORK COST" => lambda {|it| format_money(it['networkCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
242
+ {"EXTRA COST" => lambda {|it| format_money(it['extraCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
243
+ {"MTD COST" => lambda {|it| format_money(it['runningCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
244
244
  {"TOTAL COST" => lambda {|it|
245
- format_money(it['totalCost'], 'usd', {sigdig:options[:sigdig]}) + ((it['totalCost'].to_f > 0 && it['totalCost'] != it['runningCost']) ? " (Projected)" : "")
245
+ format_money(it['totalCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) + ((it['totalCost'].to_f > 0 && it['totalCost'] != it['runningCost']) ? " (Projected)" : "")
246
246
  } }
247
247
  ]
248
248
  end
249
249
  if options[:show_estimates]
250
250
  columns += [
251
- {"METERED COMPUTE PRICE" => lambda {|it| format_money(it['estimatedComputePrice'], 'usd', {sigdig:options[:sigdig]}) } },
252
- {"METERED MEMORY PRICE" => lambda {|it| format_money(it['estimatedMemoryPrice'], 'usd', {sigdig:options[:sigdig]}) } },
253
- {"METERED STORAGE PRICE" => lambda {|it| format_money(it['estimatedStoragePrice'], 'usd', {sigdig:options[:sigdig]}) } },
254
- {"METERED NETWORK PRICE" => lambda {|it| format_money(it['estimatedNetworkPrice'], 'usd', {sigdig:options[:sigdig]}) } },
255
- {"METERED EXTRA PRICE" => lambda {|it| format_money(it['estimatedExtraPrice'], 'usd', {sigdig:options[:sigdig]}) } },
256
- {"METERED MTD PRICE" => lambda {|it| format_money(it['estimatedRunningPrice'], 'usd', {sigdig:options[:sigdig]}) } },
251
+ {"METERED COMPUTE PRICE" => lambda {|it| format_money(it['estimatedComputePrice'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
252
+ {"METERED MEMORY PRICE" => lambda {|it| format_money(it['estimatedMemoryPrice'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
253
+ {"METERED STORAGE PRICE" => lambda {|it| format_money(it['estimatedStoragePrice'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
254
+ {"METERED NETWORK PRICE" => lambda {|it| format_money(it['estimatedNetworkPrice'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
255
+ {"METERED EXTRA PRICE" => lambda {|it| format_money(it['estimatedExtraPrice'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
256
+ {"METERED MTD PRICE" => lambda {|it| format_money(it['estimatedRunningPrice'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
257
257
  {"METERED TOTAL PRICE" => lambda {|it|
258
- format_money(it['estimatedTotalPrice'], 'usd', {sigdig:options[:sigdig]}) + ((it['estimatedTotalPrice'].to_f > 0 && it['estimatedTotalPrice'] != it['estimatedRunningPrice']) ? " (Projected)" : "")
258
+ format_money(it['estimatedTotalPrice'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) + ((it['estimatedTotalPrice'].to_f > 0 && it['estimatedTotalPrice'] != it['estimatedRunningPrice']) ? " (Projected)" : "")
259
259
  } },
260
260
  ]
261
261
  if options[:show_costs] && json_response['masterAccount'] != false
262
262
  columns += [
263
- {"METERED COMPUTE COST" => lambda {|it| format_money(it['estimatedComputeCost'], 'usd', {sigdig:options[:sigdig]}) } },
264
- {"METERED MEMORY COST" => lambda {|it| format_money(it['estimatedMemoryCost'], 'usd', {sigdig:options[:sigdig]}) } },
265
- {"METERED STORAGE COST" => lambda {|it| format_money(it['estimatedStorageCost'], 'usd', {sigdig:options[:sigdig]}) } },
266
- {"METERED NETWORK COST" => lambda {|it| format_money(it['estimatedNetworkCost'], 'usd', {sigdig:options[:sigdig]}) } },
267
- {"METERED EXTRA COST" => lambda {|it| format_money(it['estimatedExtraCost'], 'usd', {sigdig:options[:sigdig]}) } },
268
- {"METERED MTD COST" => lambda {|it| format_money(it['estimatedRunningCost'], 'usd', {sigdig:options[:sigdig]}) } },
263
+ {"METERED COMPUTE COST" => lambda {|it| format_money(it['estimatedComputeCost'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
264
+ {"METERED MEMORY COST" => lambda {|it| format_money(it['estimatedMemoryCost'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
265
+ {"METERED STORAGE COST" => lambda {|it| format_money(it['estimatedStorageCost'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
266
+ {"METERED NETWORK COST" => lambda {|it| format_money(it['estimatedNetworkCost'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
267
+ {"METERED EXTRA COST" => lambda {|it| format_money(it['estimatedExtraCost'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
268
+ {"METERED MTD COST" => lambda {|it| format_money(it['estimatedRunningCost'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) } },
269
269
  {"METERED TOTAL COST" => lambda {|it|
270
- format_money(it['estimatedTotalCost'], 'usd', {sigdig:options[:sigdig]}) + ((it['estimatedTotalCost'].to_f > 0 && it['estimatedTotalCost'] != it['estimatedRunningCost']) ? " (Projected)" : "")
270
+ format_money(it['estimatedTotalCost'], it['estimatedCurrency'] || 'USD', {sigdig:options[:sigdig]}) + ((it['estimatedTotalCost'].to_f > 0 && it['estimatedTotalCost'] != it['estimatedRunningCost']) ? " (Projected)" : "")
271
271
  } },
272
272
  ]
273
273
  end
@@ -306,36 +306,37 @@ class Morpheus::Cli::InvoicesCommand
306
306
 
307
307
  if invoice_totals
308
308
  cost_rows = [
309
- {label: 'Price'.upcase, compute: invoice_totals['actualComputePrice'], memory: invoice_totals['actualMemoryPrice'], storage: invoice_totals['actualStoragePrice'], network: invoice_totals['actualNetworkPrice'], license: invoice_totals['actualLicensePrice'], extra: invoice_totals['actualExtraPrice'], running: invoice_totals['actualRunningPrice'], total: invoice_totals['actualTotalPrice']},
309
+ {label: 'Price'.upcase, compute: invoice_totals['actualComputePrice'], memory: invoice_totals['actualMemoryPrice'], storage: invoice_totals['actualStoragePrice'], network: invoice_totals['actualNetworkPrice'], license: invoice_totals['actualLicensePrice'], extra: invoice_totals['actualExtraPrice'], running: invoice_totals['actualRunningPrice'], total: invoice_totals['actualTotalPrice'], currency: invoice['currency']},
310
310
  ]
311
311
  if options[:show_costs]
312
312
  cost_rows += [
313
- {label: 'Cost'.upcase, compute: invoice_totals['actualComputeCost'], memory: invoice_totals['actualMemoryCost'], storage: invoice_totals['actualStorageCost'], network: invoice_totals['actualNetworkCost'], license: invoice_totals['actualLicenseCost'], extra: invoice_totals['actualExtraCost'], running: invoice_totals['actualRunningCost'], total: invoice_totals['actualTotalCost']}
313
+ {label: 'Cost'.upcase, compute: invoice_totals['actualComputeCost'], memory: invoice_totals['actualMemoryCost'], storage: invoice_totals['actualStorageCost'], network: invoice_totals['actualNetworkCost'], license: invoice_totals['actualLicenseCost'], extra: invoice_totals['actualExtraCost'], running: invoice_totals['actualRunningCost'], total: invoice_totals['actualTotalCost'], currency: invoice['currency']}
314
314
  ]
315
315
  end
316
316
  if options[:show_estimates]
317
317
  cost_rows += [
318
- {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']}
318
+ {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'], currency: invoice['estimatedCurrency']}
319
319
  ]
320
320
  if options[:show_costs]
321
321
  cost_rows += [
322
- {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']}
322
+ {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'], currency: invoice['estimatedCurrency']}
323
323
  ]
324
324
  end
325
325
  end
326
326
  cost_columns = {
327
327
  "" => lambda {|it| it[:label] },
328
- "Compute".upcase => lambda {|it| format_money(it[:compute], 'usd', {sigdig:options[:sigdig]}) },
329
- "Memory".upcase => lambda {|it| format_money(it[:memory], 'usd', {sigdig:options[:sigdig]}) },
330
- "Storage".upcase => lambda {|it| format_money(it[:storage], 'usd', {sigdig:options[:sigdig]}) },
331
- "Network".upcase => lambda {|it| format_money(it[:network], 'usd', {sigdig:options[:sigdig]}) },
332
- "License".upcase => lambda {|it| format_money(it[:license], 'usd', {sigdig:options[:sigdig]}) },
333
- "Extra".upcase => lambda {|it| format_money(it[:extra], 'usd', {sigdig:options[:sigdig]}) },
334
- "MTD".upcase => lambda {|it| format_money(it[:running], 'usd', {sigdig:options[:sigdig]}) },
335
- "Total".upcase => lambda {|it|
336
- format_money(it[:total], 'usd', {sigdig:options[:sigdig]}) + ((it[:total].to_f > 0 && it[:total] != it[:running]) ? " (Projected)" : "")
328
+ "Compute" => lambda {|it| format_money(it[:compute], it[:currency] || it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
329
+ "Memory" => lambda {|it| format_money(it[:memory], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
330
+ "Storage" => lambda {|it| format_money(it[:storage], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
331
+ "Network" => lambda {|it| format_money(it[:network], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
332
+ "License" => lambda {|it| format_money(it[:license], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
333
+ "Extra" => lambda {|it| format_money(it[:extra], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
334
+ "MTD" => lambda {|it| format_money(it[:running], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
335
+ "Total" => lambda {|it|
336
+ format_money(it[:total], it[:currency] || 'USD', {sigdig:options[:sigdig]}) + ((it[:total].to_f > 0 && it[:total] != it[:running]) ? " (Projected)" : "")
337
337
  },
338
- }
338
+ "Currency" => lambda {|it| it[:currency] },
339
+ }.upcase_keys!
339
340
  # remove columns that rarely have data...
340
341
  if cost_rows.sum { |it| it[:memory].to_f } == 0
341
342
  cost_columns.delete("Memory".upcase)
@@ -433,6 +434,10 @@ EOT
433
434
  "End" => lambda {|it| format_date(it['endDate']) },
434
435
  "Ref Start" => lambda {|it| format_dt(it['refStart']) },
435
436
  "Ref End" => lambda {|it| format_dt(it['refEnd']) },
437
+ "Currency" => lambda {|it| (it['estimate'] ? it['estimatedCurrency'] : it['currency']) || 'USD' },
438
+ "Conversion Rate" => lambda {|it| (it['estimate'] ? it['estimatedConversionRate'] : it['conversionRate']) },
439
+ # "Estimated Currency" => lambda {|it| it['estimatedCurrency'] },
440
+ # "Estimated Conversion Rate" => lambda {|it| it['estimatedConversionRate'] },
436
441
  "Items" => lambda {|it| (it['lineItemCount'] ? it['lineItemCount'] : it['lineItems'].size) rescue '' },
437
442
  "Tags" => lambda {|it| (it['metadata'] || it['tags']) ? (it['metadata'] || it['tags']).collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
438
443
  "Project ID" => lambda {|it| it['project'] ? it['project']['id'] : '' },
@@ -457,39 +462,13 @@ EOT
457
462
  if !['ComputeServer','Instance','Container'].include?(invoice['refType'])
458
463
  description_cols.delete("Power State")
459
464
  end
465
+ # if invoice['currency'].nil? || invoice['currency'] == 'USD'
466
+ # description_cols.delete("Currency")
467
+ # end
468
+ # if invoice['actualConversionRate'].nil? || invoice['actualConversionRate'] == 1
469
+ # description_cols.delete("Conversion Rate")
470
+ # end
460
471
  print_description_list(description_cols, invoice)
461
- =begin
462
- print_h2 "Costs"
463
- cost_columns = {
464
- "Compute" => lambda {|it| format_money(it['computeCost'], 'usd', {sigdig:options[:sigdig]}) },
465
- "Memory" => lambda {|it| format_money(it['memoryCost'], 'usd', {sigdig:options[:sigdig]}) },
466
- "Storage" => lambda {|it| format_money(it['storageCost'], 'usd', {sigdig:options[:sigdig]}) },
467
- "Network" => lambda {|it| format_money(it['networkCost'], 'usd', {sigdig:options[:sigdig]}) },
468
- "License" => lambda {|it| format_money(it['licenseCost'], 'usd', {sigdig:options[:sigdig]}) },
469
- "Extra" => lambda {|it| format_money(it['extraCost'], 'usd', {sigdig:options[:sigdig]}) },
470
- "Running" => lambda {|it| format_money(it['runningCost'], 'usd', {sigdig:options[:sigdig]}) },
471
- "Total Cost" => lambda {|it| format_money(it['totalCost'], 'usd', {sigdig:options[:sigdig]}) },
472
- }
473
- print as_pretty_table([invoice], cost_columns, options)
474
-
475
- print_h2 "Prices"
476
- price_columns = {
477
- "Compute" => lambda {|it| format_money(it['computePrice'], 'usd', {sigdig:options[:sigdig]}) },
478
- "Memory" => lambda {|it| format_money(it['memoryPrice'], 'usd', {sigdig:options[:sigdig]}) },
479
- "Storage" => lambda {|it| format_money(it['storagePrice'], 'usd', {sigdig:options[:sigdig]}) },
480
- "Network" => lambda {|it| format_money(it['networkPrice'], 'usd', {sigdig:options[:sigdig]}) },
481
- "License" => lambda {|it| format_money(it['licensePrice'], 'usd', {sigdig:options[:sigdig]}) },
482
- "Extra" => lambda {|it| format_money(it['extraPrice'], 'usd', {sigdig:options[:sigdig]}) },
483
- "Running" => lambda {|it| format_money(it['runningPrice'], 'usd', {sigdig:options[:sigdig]}) },
484
- "Total Price" => lambda {|it| format_money(it['totalPrice'], 'usd', {sigdig:options[:sigdig]}) },
485
- }
486
- print as_pretty_table([invoice], price_columns, options)
487
- =end
488
-
489
- # current_date = Time.now
490
- # current_period = "#{current_date.year}#{current_date.month.to_s.rjust(2, '0')}"
491
-
492
-
493
472
 
494
473
  # Line Items
495
474
  line_items = invoice['lineItems']
@@ -507,9 +486,9 @@ EOT
507
486
  {"USAGE" => lambda {|it| it['itemUsage'] } },
508
487
  {"RATE" => lambda {|it| it['itemRate'] } },
509
488
  {"UNIT" => lambda {|it| it['rateUnit'] } },
510
- {"COST" => lambda {|it| format_money(it['itemCost'], 'usd', {sigdig:options[:sigdig]}) } },
511
- {"PRICE" => lambda {|it| format_money(it['itemPrice'], 'usd', {sigdig:options[:sigdig]}) } },
512
- #{"TAX" => lambda {|it| format_money(it['itemTax'], 'usd', {sigdig:options[:sigdig]}) } },
489
+ {"COST" => lambda {|it| format_money(it['itemCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
490
+ {"PRICE" => lambda {|it| format_money(it['itemPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
491
+ #{"TAX" => lambda {|it| format_money(it['itemTax'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
513
492
  # {"TERM" => lambda {|it| it['itemTerm'] } },
514
493
  {"ITEM ID" => lambda {|it| truncate_string_right(it['itemId'], 65) } },
515
494
  {"ITEM NAME" => lambda {|it| it['itemName'] } },
@@ -529,36 +508,37 @@ EOT
529
508
  print_h2 "Invoice Totals"
530
509
 
531
510
  cost_rows = [
532
- {label: 'Price'.upcase, compute: invoice['computePrice'], memory: invoice['memoryPrice'], storage: invoice['storagePrice'], network: invoice['networkPrice'], license: invoice['licensePrice'], extra: invoice['extraPrice'], running: invoice['runningPrice'], total: invoice['totalPrice']},
511
+ {label: 'Price'.upcase, compute: invoice['computePrice'], memory: invoice['memoryPrice'], storage: invoice['storagePrice'], network: invoice['networkPrice'], license: invoice['licensePrice'], extra: invoice['extraPrice'], running: invoice['runningPrice'], total: invoice['totalPrice'], currency: invoice['currency']},
533
512
  ]
534
513
  if options[:show_costs] # && json_response['masterAccount'] != false
535
514
  cost_rows += [
536
- {label: 'Cost'.upcase, compute: invoice['computeCost'], memory: invoice['memoryCost'], storage: invoice['storageCost'], network: invoice['networkCost'], license: invoice['licenseCost'], extra: invoice['extraCost'], running: invoice['runningCost'], total: invoice['totalCost']},
515
+ {label: 'Cost'.upcase, compute: invoice['computeCost'], memory: invoice['memoryCost'], storage: invoice['storageCost'], network: invoice['networkCost'], license: invoice['licenseCost'], extra: invoice['extraCost'], running: invoice['runningCost'], total: invoice['totalCost'], currency: invoice['currency']},
537
516
  ]
538
517
  end
539
518
  if options[:show_estimates]
540
519
  cost_rows += [
541
- {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']}
520
+ {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'], currency: invoice['estimatedCurrency']}
542
521
  ]
543
522
  if options[:show_costs] # && json_response['masterAccount'] != false
544
523
  cost_rows += [
545
- {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']},
524
+ {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'], currency: invoice['estimatedCurrency']},
546
525
  ]
547
526
  end
548
527
  end
549
528
  cost_columns = {
550
529
  "" => lambda {|it| it[:label] },
551
- "Compute".upcase => lambda {|it| format_money(it[:compute], 'usd', {sigdig:options[:sigdig]}) },
552
- "Memory".upcase => lambda {|it| format_money(it[:memory], 'usd', {sigdig:options[:sigdig]}) },
553
- "Storage".upcase => lambda {|it| format_money(it[:storage], 'usd', {sigdig:options[:sigdig]}) },
554
- "Network".upcase => lambda {|it| format_money(it[:network], 'usd', {sigdig:options[:sigdig]}) },
555
- "License".upcase => lambda {|it| format_money(it[:license], 'usd', {sigdig:options[:sigdig]}) },
556
- "Extra".upcase => lambda {|it| format_money(it[:extra], 'usd', {sigdig:options[:sigdig]}) },
557
- "MTD" => lambda {|it| format_money(it[:running], 'usd', {sigdig:options[:sigdig]}) },
558
- "Total".upcase => lambda {|it|
559
- format_money(it[:total], 'usd', {sigdig:options[:sigdig]}) + ((it[:total].to_f > 0 && it[:total] != it[:running]) ? " (Projected)" : "")
530
+ "Compute" => lambda {|it| format_money(it[:compute], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
531
+ "Memory" => lambda {|it| format_money(it[:memory], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
532
+ "Storage" => lambda {|it| format_money(it[:storage], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
533
+ "Network" => lambda {|it| format_money(it[:network], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
534
+ "License" => lambda {|it| format_money(it[:license], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
535
+ "Extra" => lambda {|it| format_money(it[:extra], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
536
+ "MTD" => lambda {|it| format_money(it[:running], it[:currency] || 'USD', {sigdig:options[:sigdig]}) },
537
+ "Total" => lambda {|it|
538
+ format_money(it[:total], it[:currency] || 'USD', {sigdig:options[:sigdig]}) + ((it[:total].to_f > 0 && it[:total] != it[:running]) ? " (Projected)" : "")
560
539
  },
561
- }
540
+ "Currency" => lambda {|it| it[:currency] },
541
+ }.upcase_keys!
562
542
  # remove columns that rarely have data...
563
543
  if cost_rows.sum { |it| it[:memory].to_f } == 0
564
544
  cost_columns.delete("Memory".upcase)
@@ -888,10 +868,10 @@ EOT
888
868
  {"USAGE" => lambda {|it| it['itemUsage'] } },
889
869
  {"RATE" => lambda {|it| it['itemRate'] } },
890
870
  {"UNIT" => lambda {|it| it['rateUnit'] } },
891
- {"PRICE" => lambda {|it| format_money(it['itemPrice'], 'usd', {sigdig:options[:sigdig]}) } },
871
+ {"PRICE" => lambda {|it| format_money(it['itemPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
892
872
  ] + (options[:show_costs] ? [
893
- {"COST" => lambda {|it| format_money(it['itemCost'], 'usd', {sigdig:options[:sigdig]}) } },
894
- {"TAX" => lambda {|it| format_money(it['itemTax'], 'usd', {sigdig:options[:sigdig]}) } },
873
+ {"COST" => lambda {|it| format_money(it['itemCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
874
+ {"TAX" => lambda {|it| format_money(it['itemTax'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
895
875
  ] : []) + [
896
876
  {"ITEM ID" => lambda {|it| truncate_string_right(it['itemId'], 65) } },
897
877
  {"ITEM NAME" => lambda {|it| it['itemName'] } },
@@ -923,10 +903,10 @@ EOT
923
903
  invoice_totals_columns = [
924
904
  {"Items" => lambda {|it| format_number(json_response['meta']['total']) rescue '' } },
925
905
  #{"Usage" => lambda {|it| it['itemUsage'] } },
926
- {"Price" => lambda {|it| format_money(it['itemPrice'], 'usd', {sigdig:options[:sigdig]}) } },
906
+ {"Price" => lambda {|it| format_money(it['itemPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
927
907
  ] + (options[:show_costs] ? [
928
- {"Cost" => lambda {|it| format_money(it['itemCost'], 'usd', {sigdig:options[:sigdig]}) } },
929
- #{"Tax" => lambda {|it| format_money(it['itemTax'], 'usd', {sigdig:options[:sigdig]}) } },
908
+ {"Cost" => lambda {|it| format_money(it['itemCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
909
+ #{"Tax" => lambda {|it| format_money(it['itemTax'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
930
910
 
931
911
  ] : [])
932
912
  print_description_list(invoice_totals_columns, line_item_totals)
@@ -993,9 +973,9 @@ EOT
993
973
  "Usage Category" => lambda {|it| it['usageCategory'] },
994
974
  "Item Usage" => lambda {|it| it['itemUsage'] },
995
975
  "Item Rate" => lambda {|it| it['itemRate'] },
996
- "Item Cost" => lambda {|it| format_money(it['itemCost'], 'usd', {sigdig:options[:sigdig]}) },
997
- "Item Price" => lambda {|it| format_money(it['itemPrice'], 'usd', {sigdig:options[:sigdig]}) },
998
- #"Item Tax" => lambda {|it| format_money(it['itemTax'], 'usd', {sigdig:options[:sigdig]}) },
976
+ "Item Cost" => lambda {|it| format_money(it['itemCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) },
977
+ "Item Price" => lambda {|it| format_money(it['itemPrice'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) },
978
+ #"Item Tax" => lambda {|it| format_money(it['itemTax'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) },
999
979
  #"Tax Type" => lambda {|it| it['taxType'] },
1000
980
  "Item Term" => lambda {|it| it['itemTerm'] },
1001
981
  "Item ID" => lambda {|it| it['itemId'] },
@@ -161,6 +161,7 @@ class Morpheus::Cli::LibraryClusterLayoutsCommand
161
161
  "Workflow" => lambda {|it| it['taskSets'] && it['taskSets'].count > 0 ? it['taskSets'][0]['name'] : nil},
162
162
  "Description" => lambda {|it| it['description']},
163
163
  "Horizontal Scaling" => lambda {|it| format_boolean(it['hasAutoScale'])},
164
+ "Install Docker" => lambda {|it| it['installContainerRuntime'].nil? ? nil : format_boolean(it['installContainerRuntime'])},
164
165
  }
165
166
 
166
167
  print_description_list(description_cols, layout)
@@ -248,6 +249,13 @@ class Morpheus::Cli::LibraryClusterLayoutsCommand
248
249
  opts.on('-s', '--auto-scale [on|off]', String, "Can be used to enable / disable horizontal scaling. Default is on") do |val|
249
250
  params['hasAutoScale'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
250
251
  end
252
+ opts.on('--install-docker [on|off]', String, "Install Docker container runtime. Default is off.") do |val|
253
+ params['installContainerRuntime'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
254
+ end
255
+ opts.on('--install-container-runtime [on|off]', String, "Install Docker container runtime. Default is off.") do |val|
256
+ params['installContainerRuntime'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
257
+ end
258
+ opts.add_hidden_option('--install-container-runtime')
251
259
  opts.on('--evars-json JSON', String, 'Environment variables JSON: {"name":"Foo", "value":"Bar", "masked":true, "export":true}' ) do |val|
252
260
  begin
253
261
  evars = JSON.parse(val.to_s)
@@ -374,6 +382,11 @@ class Morpheus::Cli::LibraryClusterLayoutsCommand
374
382
  params['hasAutoScale'] = Morpheus::Cli::OptionTypes.confirm("Enable scaling?", {:default => false}) == true
375
383
  end
376
384
 
385
+ # install docker
386
+ if params['installContainerRuntime'].nil?
387
+ params['installContainerRuntime'] = Morpheus::Cli::OptionTypes.confirm("Install Docker?", {:default => false}) == true
388
+ end
389
+
377
390
  # evars?
378
391
  if params['environmentVariables'].nil?
379
392
  evars = []
@@ -506,6 +519,13 @@ class Morpheus::Cli::LibraryClusterLayoutsCommand
506
519
  opts.on('-s', '--auto-scale [on|off]', String, "Can be used to enable / disable horizontal scaling. Default is on") do |val|
507
520
  params['hasAutoScale'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
508
521
  end
522
+ opts.on('--install-docker [on|off]', String, "Install Docker container runtime. Default is off.") do |val|
523
+ params['installContainerRuntime'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
524
+ end
525
+ opts.on('--install-container-runtime [on|off]', String, "Install Docker container runtime. Default is off.") do |val|
526
+ params['installContainerRuntime'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
527
+ end
528
+ opts.add_hidden_option('--install-container-runtime')
509
529
  opts.on('--evars-json JSON', String, 'Environment variables JSON: {"name":"Foo", "value":"Bar", "masked":true, "export":true}' ) do |val|
510
530
  begin
511
531
  evars = JSON.parse(val.to_s)
@@ -484,7 +484,7 @@ module Morpheus::Cli::ProvisioningHelper
484
484
  if options[:instance_type_code]
485
485
  instance_type_code = options[:instance_type_code]
486
486
  else
487
- instance_type_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'type' => 'select', 'fieldLabel' => 'Type', 'optionSource' => 'instanceTypes', 'required' => true, 'description' => 'Select Instance Type.'}],options[:options],api_client,{groupId: group_id})
487
+ instance_type_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'type' => 'select', 'fieldLabel' => 'Type', 'optionSource' => 'instanceTypes', 'required' => true, 'description' => 'Select Instance Type.'}],options[:options],api_client,{groupId: group_id}, no_prompt, true)
488
488
  instance_type_code = instance_type_prompt['type']
489
489
  end
490
490
  if instance_type_code.to_s =~ /\A\d{1,}\Z/
@@ -657,13 +657,11 @@ module Morpheus::Cli::ProvisioningHelper
657
657
  version_value = default_version_value
658
658
  version_is_required = default_layout_value.nil?
659
659
  if default_layout_value.nil? && options[:options]["layout"].nil? && options[:always_prompt] != true
660
- #version_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'version', 'type' => 'select', 'fieldLabel' => 'Version', 'optionSource' => 'instanceVersions', 'required' => true, 'skipSingleOption' => true, 'autoPickOption' => true, 'description' => 'Select which version of the instance type to be provisioned.', 'defaultValue' => default_version_value}],options[:options],api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id']})
661
660
  version_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'version', 'type' => 'select', 'fieldLabel' => 'Version', 'selectOptions' => available_versions, 'required' => version_is_required, 'skipSingleOption' => true, 'autoPickOption' => true, 'description' => 'Select which version of the instance type to be provisioned.', 'defaultValue' => default_version_value}],options[:options],api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id']})
662
661
  version_value = version_prompt['version']
663
662
  end
664
663
  end
665
-
666
- layout_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'layout', 'type' => 'select', 'fieldLabel' => 'Layout', 'optionSource' => 'layoutsForCloud', 'required' => true, 'description' => 'Select which configuration of the instance type to be provisioned.', 'defaultValue' => default_layout_value}],options[:options],api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], version: version_value, creatable: true})['layout']
664
+ layout_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'layout', 'type' => 'select', 'fieldLabel' => 'Layout', 'optionSource' => 'layoutsForCloud', 'required' => true, 'description' => 'Select which configuration of the instance type to be provisioned.', 'defaultValue' => default_layout_value}],options[:options],api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], version: version_value, creatable: true}, no_prompt, true)['layout']
667
665
  end
668
666
  end
669
667
 
@@ -679,7 +677,7 @@ module Morpheus::Cli::ProvisioningHelper
679
677
  end
680
678
  layout_id = layout['id']
681
679
  payload['instance']['layout'] = {'id' => layout['id'], 'code' => layout['code']}
682
-
680
+
683
681
  # need to GET provision type for optionTypes, and other settings...
684
682
  provision_type_code = layout['provisionTypeCode'] || layout['provisionType']['code']
685
683
  provision_type = nil
@@ -693,50 +691,6 @@ module Morpheus::Cli::ProvisioningHelper
693
691
  provision_type = get_provision_type_for_zone_type(cloud['zoneType']['id'])
694
692
  end
695
693
 
696
- # prompt for service plan
697
- plan_id = nil
698
- service_plan = nil
699
- service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id})
700
- service_plans = service_plans_json["plans"]
701
- if locked_fields.include?('plan.id')
702
- plan_id = options[:options]['plan']['id'] rescue nil
703
- if plan_id.nil?
704
- plan_id = options[:options]['instance']['plan']['id'] rescue nil
705
- end
706
- service_plan = service_plans.find {|sp| sp['id'] == plan_id }
707
- else
708
- service_plan = service_plans.find {|sp| sp['id'] == options[:service_plan].to_i} if options[:service_plan]
709
-
710
- if !service_plan
711
- service_plans_dropdown = service_plans.collect {|sp| {'name' => sp["name"], 'value' => sp["id"], 'code' => sp['code']} } # already sorted
712
- default_plan = nil
713
- if payload['plan']
714
- default_plan = payload['plan']
715
- elsif payload['instance'] && payload['instance']['plan']
716
- default_plan = payload['instance']['plan']
717
- end
718
-
719
- if options[:default_plan] && service_plans_dropdown.find {|sp| [sp["name"], sp["value"].to_s, sp["code"]].include?(options[:default_plan].to_s)}
720
- default_plan_value = options[:default_plan]
721
- else
722
- default_plan_value = options[:default_plan] || (default_plan.is_a?(Hash) ? default_plan['id'] : default_plan)
723
- end
724
- plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this instance', 'defaultValue' => default_plan_value}],options[:options])
725
- plan_id = plan_prompt['servicePlan']
726
- service_plan = service_plans.find {|sp| sp["id"] == plan_id.to_i }
727
- if !service_plan
728
- print_red_alert "Plan not found by id #{plan_id}"
729
- exit 1
730
- end
731
- end
732
- #todo: consolidate these, instances api looks for instance.plan.id and apps looks for plan.id
733
- if options[:for_app]
734
- payload['plan'] = {'id' => service_plan["id"], 'code' => service_plan["code"], 'name' => service_plan["name"]}
735
- else
736
- payload['instance']['plan'] = {'id' => service_plan["id"], 'code' => service_plan["code"], 'name' => service_plan["name"]}
737
- end
738
- end
739
-
740
694
  # build config option types
741
695
  option_type_list = []
742
696
  if !layout['optionTypes'].nil? && !layout['optionTypes'].empty?
@@ -745,47 +699,112 @@ module Morpheus::Cli::ProvisioningHelper
745
699
  if !instance_type['optionTypes'].nil? && !instance_type['optionTypes'].empty?
746
700
  option_type_list += instance_type['optionTypes']
747
701
  end
748
- if !provision_type.nil? && !provision_type['optionTypes'].nil? && !provision_type['optionTypes'].empty?
749
- option_type_list += provision_type['optionTypes']
750
- end
751
702
 
752
- # prompt for resource pool
703
+ api_params = {groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_value}
704
+
753
705
  pool_id = nil
754
706
  resource_pool = nil
755
- if locked_fields.include?('config.resourcePoolId')
756
- pool_id = payload['config']['resourcePoolId'] rescue nil
757
- elsif locked_fields.include?('config.resourcePool')
758
- pool_id = payload['config']['resourcePool'] rescue nil
759
- elsif locked_fields.include?('config.azureResourceGroupId')
760
- pool_id = payload['config']['azureResourceGroupId'] rescue nil
761
- else
762
- has_zone_pools = provision_type && provision_type["id"] && provision_type["hasZonePools"]
763
- if has_zone_pools
764
- # pluck out the resourcePoolId option type to prompt for
765
- resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
766
- option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
767
- resource_pool_options = options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], planId: service_plan["id"], layoutId: layout["id"]})['data']
768
- resource_pool = resource_pool_options.find {|opt| opt['id'] == options[:resource_pool].to_i} if options[:resource_pool]
769
-
770
- if resource_pool
771
- pool_id = resource_pool['id']
772
- else
773
- if options[:default_resource_pool]
774
- default_resource_pool = resource_pool_options.find {|rp| rp['id'] == options[:default_resource_pool]}
707
+ service_plan = nil
708
+
709
+ prompt_service_plan = -> {
710
+ service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id}.merge(resource_pool.nil? ? {} : {'resourcePoolId' => resource_pool['id']}))
711
+ service_plans = service_plans_json["plans"]
712
+ if locked_fields.include?('plan.id')
713
+ plan_id = options[:options]['plan']['id'] rescue nil
714
+ if plan_id.nil?
715
+ plan_id = options[:options]['instance']['plan']['id'] rescue nil
716
+ end
717
+ service_plan = service_plans.find {|sp| sp['id'] == plan_id }
718
+ else
719
+ service_plan = service_plans.find {|sp| sp['id'] == options[:service_plan].to_i} if options[:service_plan]
720
+
721
+ if !service_plan
722
+ service_plans_dropdown = service_plans.collect {|sp| {'name' => sp["name"], 'value' => sp["id"], 'code' => sp['code']} } # already sorted
723
+ default_plan = nil
724
+ if payload['plan']
725
+ default_plan = payload['plan']
726
+ elsif payload['instance'] && payload['instance']['plan']
727
+ default_plan = payload['instance']['plan']
775
728
  end
776
- resource_pool_option_type ||= {'fieldContext' => 'config', 'fieldName' => 'resourcePoolId', 'type' => 'select', 'fieldLabel' => 'Resource Pool', 'selectOptions' => resource_pool_options, 'required' => true, 'skipSingleOption' => true, 'description' => 'Select resource pool.', 'defaultValue' => default_resource_pool ? default_resource_pool['name'] : nil}
777
- resource_pool_prompt = Morpheus::Cli::OptionTypes.prompt([resource_pool_option_type],options[:options],api_client,{})
778
- resource_pool_prompt.deep_compact!
779
- payload.deep_merge!(resource_pool_prompt)
780
- resource_pool = Morpheus::Cli::OptionTypes.get_last_select()
781
- if resource_pool_option_type['fieldContext'] && resource_pool_prompt[resource_pool_option_type['fieldContext']]
782
- pool_id = resource_pool_prompt[resource_pool_option_type['fieldContext']][resource_pool_option_type['fieldName']]
783
- elsif resource_pool_prompt[resource_pool_option_type['fieldName']]
784
- pool_id = resource_pool_prompt[resource_pool_option_type['fieldName']]
729
+
730
+ if options[:default_plan] && service_plans_dropdown.find {|sp| [sp["name"], sp["value"].to_s, sp["code"]].include?(options[:default_plan].to_s)}
731
+ default_plan_value = options[:default_plan]
732
+ else
733
+ default_plan_value = options[:default_plan] || (default_plan.is_a?(Hash) ? default_plan['id'] : default_plan)
785
734
  end
786
- resource_pool ||= resource_pool_options.find {|it| it['id'] == pool_id}
735
+ plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this instance', 'defaultValue' => default_plan_value}],options[:options], api_client, {}, no_prompt, true)
736
+ plan_id = plan_prompt['servicePlan']
737
+ service_plan = service_plans.find {|sp| sp["id"] == plan_id.to_i }
738
+ if !service_plan
739
+ print_red_alert "Plan not found by id #{plan_id}"
740
+ exit 1
741
+ end
742
+ end
743
+ #todo: consolidate these, instances api looks for instance.plan.id and apps looks for plan.id
744
+ if options[:for_app]
745
+ payload['plan'] = {'id' => service_plan["id"], 'code' => service_plan["code"], 'name' => service_plan["name"]}
746
+ else
747
+ payload['instance']['plan'] = {'id' => service_plan["id"], 'code' => service_plan["code"], 'name' => service_plan["name"]}
787
748
  end
788
749
  end
750
+ }
751
+
752
+ prompt_resource_pool = -> {
753
+ # prompt for resource pool
754
+ if locked_fields.include?('config.resourcePoolId')
755
+ pool_id = payload['config']['resourcePoolId'] rescue nil
756
+ elsif locked_fields.include?('config.resourcePool')
757
+ pool_id = payload['config']['resourcePool'] rescue nil
758
+ elsif locked_fields.include?('config.azureResourceGroupId')
759
+ pool_id = payload['config']['azureResourceGroupId'] rescue nil
760
+ else
761
+ has_zone_pools = provision_type && provision_type["id"] && provision_type["hasZonePools"]
762
+ if has_zone_pools
763
+ # pluck out the resourcePoolId option type to prompt for
764
+ resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
765
+ option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
766
+
767
+ resource_pool_options = options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], layoutId: layout["id"]}.merge(service_plan.nil? ? {} : {planId: service_plan["id"]}))['data']
768
+ resource_pool = resource_pool_options.find {|opt| opt['id'] == options[:resource_pool].to_i} if options[:resource_pool]
769
+
770
+ if resource_pool
771
+ pool_id = resource_pool['id']
772
+ else
773
+ if options[:default_resource_pool]
774
+ default_resource_pool = resource_pool_options.find {|rp| rp['id'] == options[:default_resource_pool]}
775
+ end
776
+ resource_pool_option_type ||= {'fieldContext' => 'config', 'fieldName' => 'resourcePoolId', 'type' => 'select', 'fieldLabel' => 'Resource Pool', 'selectOptions' => resource_pool_options, 'required' => true, 'skipSingleOption' => true, 'description' => 'Select resource pool.', 'defaultValue' => default_resource_pool ? default_resource_pool['name'] : nil}
777
+ resource_pool_prompt = Morpheus::Cli::OptionTypes.prompt([resource_pool_option_type],options[:options],api_client,{}, no_prompt, true)
778
+ resource_pool_prompt.deep_compact!
779
+ payload.deep_merge!(resource_pool_prompt)
780
+ resource_pool = Morpheus::Cli::OptionTypes.get_last_select()
781
+ if resource_pool_option_type['fieldContext'] && resource_pool_prompt[resource_pool_option_type['fieldContext']]
782
+ pool_id = resource_pool_prompt[resource_pool_option_type['fieldContext']][resource_pool_option_type['fieldName']]
783
+ elsif resource_pool_prompt[resource_pool_option_type['fieldName']]
784
+ pool_id = resource_pool_prompt[resource_pool_option_type['fieldName']]
785
+ end
786
+ resource_pool ||= resource_pool_options.find {|it| it['id'] == pool_id}
787
+ end
788
+ end
789
+ end
790
+ }
791
+
792
+ prompt_provision_options = -> {
793
+ if !provision_type.nil? && !provision_type['optionTypes'].nil? && !provision_type['optionTypes'].empty?
794
+ option_type_list += provision_type['optionTypes'].reject {|it| (it['fieldGroup'] || '').downcase == 'provisiontype'}
795
+ provision_config_payload = Morpheus::Cli::OptionTypes.prompt(provision_type['optionTypes'].reject {|it| (it['fieldGroup'] || '').downcase != 'provisiontype'}, options[:options], @api_client, api_params, no_prompt, true)
796
+ payload.deep_merge!(provision_config_payload)
797
+ end
798
+ }
799
+
800
+ if ['openstack', 'huawei', 'opentelekom'].include?(cloud_type['zoneType']['code'])
801
+ prompt_resource_pool.call
802
+ prompt_provision_options.call
803
+ prompt_service_plan.call
804
+ else
805
+ prompt_service_plan.call
806
+ prompt_provision_options.call
807
+ prompt_resource_pool.call
789
808
  end
790
809
 
791
810
  # remove host selection for kubernetes
@@ -858,7 +877,7 @@ module Morpheus::Cli::ProvisioningHelper
858
877
  if provision_type && provision_type["hasNetworks"]
859
878
  # prompt for network interfaces (if supported)
860
879
  begin
861
- network_interfaces = prompt_network_interfaces(cloud_id, provision_type["id"], pool_id, options)
880
+ network_interfaces = prompt_network_interfaces(cloud_id, provision_type["id"], pool_id, options.merge({:api_params => payload['config']}))
862
881
  if !network_interfaces.empty?
863
882
  payload['networkInterfaces'] = network_interfaces
864
883
  end
@@ -921,7 +940,6 @@ module Morpheus::Cli::ProvisioningHelper
921
940
  end
922
941
 
923
942
  # prompt for option types
924
- api_params = {groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_value}
925
943
  api_params['config'] = payload['config'] if payload['config']
926
944
  api_params['poolId'] = payload['config']['resourcePoolId'] if payload['config'] && payload['config']['resourcePoolId']
927
945
 
@@ -935,10 +953,21 @@ module Morpheus::Cli::ProvisioningHelper
935
953
  end
936
954
  end
937
955
 
938
- instance_config_payload = Morpheus::Cli::OptionTypes.prompt(option_type_list, options[:options], @api_client, api_params)
939
- payload.deep_merge!(instance_config_payload)
956
+ option_type_list += [
957
+ {'fieldName' => 'userGroup.id', 'fieldLabel' => 'User Group', 'fieldGroup' => 'User Config', 'type' => 'select', 'optionSource' => 'userGroups', 'displayOrder' => 0, 'fieldContext' => 'instance'},
958
+ {'fieldName' => 'hostName', 'fieldLabel' => 'Hostname', 'fieldGroup' => 'Advanced', 'type' => 'string', 'displayOrder' => 1},
959
+ {'fieldName' => 'networkDomain.id', 'fieldLabel' => 'Domain', 'fieldGroup' => 'Advanced', 'type' => 'select', 'optionSource' => 'networkDomains', 'displayOrder' => 2, 'fieldContext' => 'instance'},
960
+ {'fieldName' => 'timezone', 'fieldLabel' => 'Time Zone', 'fieldGroup' => 'Advanced', 'type' => 'select', 'optionSource' => 'timezones', 'displayOrder' => 3, 'fieldContext' => 'config'}
961
+ ]
962
+
963
+ if instance_type['hasAutoScale']
964
+ option_type_list += [
965
+ {'fieldName' => 'layoutSize', 'fieldLabel' => 'Scale Factor', 'fieldGroup' => 'Advanced', 'type' => 'number', 'defaultValue' => 1, 'displayOrder' => 0},
966
+ ]
967
+ end
940
968
 
941
- ## Network Options
969
+ instance_config_payload = Morpheus::Cli::OptionTypes.prompt(option_type_list.reject {|ot| ot['type'] == 'exposedPorts'}, options[:options], @api_client, api_params, no_prompt, true)
970
+ payload.deep_merge!(instance_config_payload)
942
971
 
943
972
  # prompt for exposed ports
944
973
  if payload['ports'].nil?
@@ -950,10 +979,6 @@ module Morpheus::Cli::ProvisioningHelper
950
979
  end
951
980
  end
952
981
 
953
- ## Advanced Options
954
-
955
- # scale factor
956
-
957
982
  # prompt for environment variables
958
983
  evars = prompt_evars(options)
959
984
  if !evars.empty?
@@ -1486,10 +1511,11 @@ module Morpheus::Cli::ProvisioningHelper
1486
1511
  #puts "Configure Networks:"
1487
1512
  no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
1488
1513
  network_interfaces = []
1489
- api_params = {zoneId: zone_id, provisionTypeId: provision_type_id}
1514
+ api_params = {zoneId: zone_id, provisionTypeId: provision_type_id}.merge(options[:api_params] || {})
1490
1515
  if pool_id.to_s =~ /\A\d{1,}\Z/
1491
1516
  api_params[:poolId] = pool_id
1492
1517
  end
1518
+
1493
1519
  zone_network_options_json = api_client.options.options_for_source('zoneNetworkOptions', api_params)
1494
1520
  # puts "zoneNetworkOptions JSON"
1495
1521
  # puts JSON.pretty_generate(zone_network_options_json)
@@ -1571,7 +1597,7 @@ module Morpheus::Cli::ProvisioningHelper
1571
1597
  default_network_value = (network_options.find {|n| n['value'] == default_network_id} || {})['name']
1572
1598
 
1573
1599
  # choose network
1574
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'networkId', 'type' => 'select', 'fieldLabel' => "Network", 'selectOptions' => network_options, 'required' => true, 'skipSingleOption' => false, 'description' => 'Choose a network for this interface.', 'defaultValue' => default_network_value}], options[:options])
1600
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'networkId', 'type' => 'select', 'fieldLabel' => "Network", 'selectOptions' => network_options, 'required' => true, 'skipSingleOption' => false, 'description' => 'Choose a network for this interface.', 'defaultValue' => default_network_value}], options[:options], api_client, {}, no_prompt, true)
1575
1601
  network_interface['network'] = {}
1576
1602
  network_interface['network']['id'] = v_prompt[field_context]['networkId'].to_s
1577
1603
  selected_network = networks.find {|it| it["id"].to_s == network_interface['network']['id'] }