morpheus-cli 6.1.2 → 6.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/Dockerfile +1 -1
 - data/lib/morpheus/api/api_client.rb +8 -0
 - data/lib/morpheus/api/backup_jobs_interface.rb +4 -0
 - data/lib/morpheus/api/backup_restores_interface.rb +23 -0
 - data/lib/morpheus/api/backup_results_interface.rb +28 -0
 - data/lib/morpheus/api/backups_interface.rb +5 -4
 - data/lib/morpheus/api/monitoring_settings_interface.rb +0 -4
 - data/lib/morpheus/cli/cli_command.rb +176 -46
 - data/lib/morpheus/cli/commands/appliance_settings_command.rb +7 -19
 - data/lib/morpheus/cli/commands/apps.rb +1 -1
 - data/lib/morpheus/cli/commands/backup_jobs_command.rb +78 -20
 - data/lib/morpheus/cli/commands/backup_restores_command.rb +144 -0
 - data/lib/morpheus/cli/commands/backup_results_command.rb +149 -0
 - data/lib/morpheus/cli/commands/backups_command.rb +215 -93
 - data/lib/morpheus/cli/commands/hosts.rb +15 -2
 - data/lib/morpheus/cli/commands/instances.rb +18 -3
 - data/lib/morpheus/cli/commands/monitoring_settings.rb +0 -16
 - data/lib/morpheus/cli/commands/plugins.rb +2 -1
 - data/lib/morpheus/cli/commands/roles.rb +9 -9
 - data/lib/morpheus/cli/commands/service_catalog_command.rb +50 -83
 - data/lib/morpheus/cli/commands/user_sources_command.rb +36 -8
 - data/lib/morpheus/cli/commands/view.rb +20 -20
 - data/lib/morpheus/cli/mixins/backups_helper.rb +58 -0
 - data/lib/morpheus/cli/mixins/print_helper.rb +27 -4
 - data/lib/morpheus/cli/option_types.rb +10 -7
 - data/lib/morpheus/cli/version.rb +1 -1
 - data/lib/morpheus/formatters.rb +1 -1
 - data/lib/morpheus/routes.rb +18 -3
 - metadata +6 -2
 
| 
         @@ -1206,7 +1206,7 @@ EOT 
     | 
|
| 
       1206 
1206 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       1207 
1207 
     | 
    
         
             
                  exit 1 if role.nil?
         
     | 
| 
       1208 
1208 
     | 
    
         | 
| 
       1209 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 1209 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       1210 
1210 
     | 
    
         | 
| 
       1211 
1211 
     | 
    
         
             
                  cloud = nil
         
     | 
| 
       1212 
1212 
     | 
    
         
             
                  if !do_all
         
     | 
| 
         @@ -1355,7 +1355,7 @@ EOT 
     | 
|
| 
       1355 
1355 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       1356 
1356 
     | 
    
         
             
                  return 1 if role.nil?
         
     | 
| 
       1357 
1357 
     | 
    
         | 
| 
       1358 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 1358 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       1359 
1359 
     | 
    
         
             
                  instance_type = nil
         
     | 
| 
       1360 
1360 
     | 
    
         
             
                  if !do_all
         
     | 
| 
       1361 
1361 
     | 
    
         
             
                    instance_type = find_instance_type_by_name(instance_type_name)
         
     | 
| 
         @@ -1504,7 +1504,7 @@ EOT 
     | 
|
| 
       1504 
1504 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       1505 
1505 
     | 
    
         
             
                  return 1 if role.nil?
         
     | 
| 
       1506 
1506 
     | 
    
         | 
| 
       1507 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 1507 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       1508 
1508 
     | 
    
         
             
                  blueprint_global_access = role_json['globalAppTemplateAccess'] || role_json['globalBlueprintAccess']
         
     | 
| 
       1509 
1509 
     | 
    
         
             
                  blueprint_permissions = role_json['appTemplatePermissions'] || role_json['blueprintPermissions'] || []
         
     | 
| 
       1510 
1510 
     | 
    
         | 
| 
         @@ -1666,7 +1666,7 @@ EOT 
     | 
|
| 
       1666 
1666 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       1667 
1667 
     | 
    
         
             
                  return 1 if role.nil?
         
     | 
| 
       1668 
1668 
     | 
    
         | 
| 
       1669 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 1669 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       1670 
1670 
     | 
    
         
             
                  catalog_item_type_global_access = role_json['globalCatalogItemTypeAccess']
         
     | 
| 
       1671 
1671 
     | 
    
         
             
                  catalog_item_type_permissions = role_json['catalogItemTypePermissions'] || role_json['catalogItemTypes'] []
         
     | 
| 
       1672 
1672 
     | 
    
         | 
| 
         @@ -1821,7 +1821,7 @@ Update default persona access for a role. 
     | 
|
| 
       1821 
1821 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       1822 
1822 
     | 
    
         
             
                  return 1 if role.nil?
         
     | 
| 
       1823 
1823 
     | 
    
         | 
| 
       1824 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 1824 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       1825 
1825 
     | 
    
         | 
| 
       1826 
1826 
     | 
    
         
             
                  # no lookup right now, pass the code serviceCatalog|standard
         
     | 
| 
       1827 
1827 
     | 
    
         
             
                  persona_code = persona_id
         
     | 
| 
         @@ -1963,7 +1963,7 @@ EOT 
     | 
|
| 
       1963 
1963 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       1964 
1964 
     | 
    
         
             
                  return 1 if role.nil?
         
     | 
| 
       1965 
1965 
     | 
    
         | 
| 
       1966 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 1966 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       1967 
1967 
     | 
    
         
             
                  vdi_pool_global_access = role_json['globalVdiPoolAccess']
         
     | 
| 
       1968 
1968 
     | 
    
         
             
                  vdi_pool_permissions = role_json['vdiPoolPermissions'] || role_json['vdiPools'] || []
         
     | 
| 
       1969 
1969 
     | 
    
         | 
| 
         @@ -2119,7 +2119,7 @@ EOT 
     | 
|
| 
       2119 
2119 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       2120 
2120 
     | 
    
         
             
                  return 1 if role.nil?
         
     | 
| 
       2121 
2121 
     | 
    
         | 
| 
       2122 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 2122 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       2123 
2123 
     | 
    
         
             
                  report_type_global_access = role_json['globalReportTypeAccess']
         
     | 
| 
       2124 
2124 
     | 
    
         
             
                  report_type_permissions = role_json['reportTypePermissions'] || role_json['reportTypes'] || []
         
     | 
| 
       2125 
2125 
     | 
    
         | 
| 
         @@ -2273,7 +2273,7 @@ Update default task access for a role. 
     | 
|
| 
       2273 
2273 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       2274 
2274 
     | 
    
         
             
                  return 1 if role.nil?
         
     | 
| 
       2275 
2275 
     | 
    
         | 
| 
       2276 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 2276 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       2277 
2277 
     | 
    
         
             
                  task_permissions = role_json['taskPermissions'] || role_json['tasks'] || []
         
     | 
| 
       2278 
2278 
     | 
    
         | 
| 
       2279 
2279 
     | 
    
         
             
                  # hacky, but support name or code lookup via the list returned in the show payload
         
     | 
| 
         @@ -2425,7 +2425,7 @@ Update default workflow access for a role. 
     | 
|
| 
       2425 
2425 
     | 
    
         
             
                  role = find_role_by_name_or_id(account_id, name)
         
     | 
| 
       2426 
2426 
     | 
    
         
             
                  return 1 if role.nil?
         
     | 
| 
       2427 
2427 
     | 
    
         | 
| 
       2428 
     | 
    
         
            -
                  role_json = @roles_interface.get(account_id, role['id'])
         
     | 
| 
      
 2428 
     | 
    
         
            +
                  role_json = @roles_interface.get(account_id, role['id'], {'includeDefaultAccess' => true})
         
     | 
| 
       2429 
2429 
     | 
    
         
             
                  workflow_permissions = role_json['taskSetPermissions'] || role_json['taskSets'] || []
         
     | 
| 
       2430 
2430 
     | 
    
         | 
| 
       2431 
2431 
     | 
    
         
             
                  # hacky, but support name or code lookup via the list returned in the show payload
         
     | 
| 
         @@ -560,27 +560,17 @@ EOT 
     | 
|
| 
       560 
560 
     | 
    
         
             
                # fetch current cart
         
     | 
| 
       561 
561 
     | 
    
         
             
                # cart = @service_catalog_interface.get_cart()['cart']
         
     | 
| 
       562 
562 
     | 
    
         
             
                update_cart_object_key = 'order'
         
     | 
| 
       563 
     | 
    
         
            -
                 
     | 
| 
      
 563 
     | 
    
         
            +
                parse_payload(options, update_cart_object_key) do |payload|
         
     | 
| 
       564 
564 
     | 
    
         
             
                  payload.deep_merge!({update_cart_object_key => parse_passed_options(options)})
         
     | 
| 
       565 
565 
     | 
    
         
             
                  if payload[update_cart_object_key].empty? # || options[:no_prompt]
         
     | 
| 
       566 
566 
     | 
    
         
             
                    raise_command_error "Specify at least one option to update.\n#{optparse}"
         
     | 
| 
       567 
567 
     | 
    
         
             
                  end
         
     | 
| 
       568 
568 
     | 
    
         
             
                end
         
     | 
| 
       569 
     | 
    
         
            -
                 
     | 
| 
       570 
     | 
    
         
            -
                   
     | 
| 
       571 
     | 
    
         
            -
                   
     | 
| 
       572 
     | 
    
         
            -
             
     | 
| 
       573 
     | 
    
         
            -
                    next
         
     | 
| 
       574 
     | 
    
         
            -
                  end
         
     | 
| 
       575 
     | 
    
         
            -
                  json_response = @service_catalog_interface.update_cart(payload)
         
     | 
| 
       576 
     | 
    
         
            -
                  #cart = json_response['cart']
         
     | 
| 
       577 
     | 
    
         
            -
                  #cart = @service_catalog_interface.get_cart()['cart']
         
     | 
| 
       578 
     | 
    
         
            -
                  render_response(json_response, options, 'cart') do
         
     | 
| 
       579 
     | 
    
         
            -
                    print_green_success "Updated cart"
         
     | 
| 
       580 
     | 
    
         
            -
                    get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
         
     | 
| 
       581 
     | 
    
         
            -
                  end
         
     | 
| 
      
 569 
     | 
    
         
            +
                execute_api(@service_catalog_interface, :update_cart, [params], options, "cart") do |json_response|
         
     | 
| 
      
 570 
     | 
    
         
            +
                  #cart = json_response["cart"]
         
     | 
| 
      
 571 
     | 
    
         
            +
                  print_green_success "Updated cart"
         
     | 
| 
      
 572 
     | 
    
         
            +
                  get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
         
     | 
| 
       582 
573 
     | 
    
         
             
                end
         
     | 
| 
       583 
     | 
    
         
            -
                return 0, nil
         
     | 
| 
       584 
574 
     | 
    
         
             
              end
         
     | 
| 
       585 
575 
     | 
    
         | 
| 
       586 
576 
     | 
    
         
             
              def add(args)
         
     | 
| 
         @@ -600,6 +590,7 @@ EOT 
     | 
|
| 
       600 
590 
     | 
    
         
             
                  end
         
     | 
| 
       601 
591 
     | 
    
         
             
                  opts.on('--validate','--validate', "Validate Only. Validates the configuration and skips adding the item.") do
         
     | 
| 
       602 
592 
     | 
    
         
             
                    options[:validate_only] = true
         
     | 
| 
      
 593 
     | 
    
         
            +
                    params['validate'] = true
         
     | 
| 
       603 
594 
     | 
    
         
             
                  end
         
     | 
| 
       604 
595 
     | 
    
         
             
                  opts.on('--context [instance|server]', String, "Context Type for operational workflow types") do |val|
         
     | 
| 
       605 
596 
     | 
    
         
             
                    workflow_context = val.to_s
         
     | 
| 
         @@ -608,7 +599,7 @@ EOT 
     | 
|
| 
       608 
599 
     | 
    
         
             
                    workflow_target = val.to_s
         
     | 
| 
       609 
600 
     | 
    
         
             
                  end
         
     | 
| 
       610 
601 
     | 
    
         
             
                  opts.add_hidden_option('--sigdig')
         
     | 
| 
       611 
     | 
    
         
            -
                   
     | 
| 
      
 602 
     | 
    
         
            +
                  build_standard_add_many_options(opts, options, [:sigdig])
         
     | 
| 
       612 
603 
     | 
    
         
             
                  opts.footer = <<-EOT
         
     | 
| 
       613 
604 
     | 
    
         
             
            Add an item to your cart
         
     | 
| 
       614 
605 
     | 
    
         
             
            [type] is required, this is name or id of a catalog item type.
         
     | 
| 
         @@ -622,7 +613,7 @@ EOT 
     | 
|
| 
       622 
613 
     | 
    
         
             
                  type_id = args.join(" ")
         
     | 
| 
       623 
614 
     | 
    
         
             
                end
         
     | 
| 
       624 
615 
     | 
    
         
             
                add_item_object_key = 'item'
         
     | 
| 
       625 
     | 
    
         
            -
                 
     | 
| 
      
 616 
     | 
    
         
            +
                parse_payload(options, add_item_object_key) do |payload|
         
     | 
| 
       626 
617 
     | 
    
         
             
                  payload.deep_merge!({add_item_object_key => parse_passed_options(options)})
         
     | 
| 
       627 
618 
     | 
    
         
             
                  # prompt for Type
         
     | 
| 
       628 
619 
     | 
    
         
             
                  if type_id
         
     | 
| 
         @@ -712,46 +703,35 @@ EOT 
     | 
|
| 
       712 
703 
     | 
    
         
             
                    end
         
     | 
| 
       713 
704 
     | 
    
         
             
                  end
         
     | 
| 
       714 
705 
     | 
    
         
             
                end
         
     | 
| 
       715 
     | 
    
         
            -
                 
     | 
| 
       716 
     | 
    
         
            -
                  params['validate'] = true
         
     | 
| 
       717 
     | 
    
         
            -
                end
         
     | 
| 
       718 
     | 
    
         
            -
                process_payloads(payloads, options) do |payload|
         
     | 
| 
       719 
     | 
    
         
            -
                  @service_catalog_interface.setopts(options)
         
     | 
| 
       720 
     | 
    
         
            -
                  if options[:dry_run]
         
     | 
| 
       721 
     | 
    
         
            -
                    print_dry_run @service_catalog_interface.dry.create_cart_item(payload, params)
         
     | 
| 
       722 
     | 
    
         
            -
                    next
         
     | 
| 
       723 
     | 
    
         
            -
                  end
         
     | 
| 
       724 
     | 
    
         
            -
                  json_response = @service_catalog_interface.create_cart_item(payload, params)
         
     | 
| 
      
 706 
     | 
    
         
            +
                execute_api(@service_catalog_interface, :create_cart_item, [params], options, 'item') do |json_response|
         
     | 
| 
       725 
707 
     | 
    
         
             
                  cart_item = json_response['item']
         
     | 
| 
       726 
     | 
    
         
            -
                   
     | 
| 
       727 
     | 
    
         
            -
                    if  
     | 
| 
       728 
     | 
    
         
            -
                       
     | 
| 
       729 
     | 
    
         
            -
             
     | 
| 
       730 
     | 
    
         
            -
                         
     | 
| 
       731 
     | 
    
         
            -
             
     | 
| 
       732 
     | 
    
         
            -
             
     | 
| 
       733 
     | 
    
         
            -
             
     | 
| 
       734 
     | 
    
         
            -
                           
     | 
| 
       735 
     | 
    
         
            -
             
     | 
| 
       736 
     | 
    
         
            -
                             
     | 
| 
       737 
     | 
    
         
            -
             
     | 
| 
       738 
     | 
    
         
            -
             
     | 
| 
       739 
     | 
    
         
            -
             
     | 
| 
       740 
     | 
    
         
            -
             
     | 
| 
       741 
     | 
    
         
            -
             
     | 
| 
       742 
     | 
    
         
            -
             
     | 
| 
       743 
     | 
    
         
            -
             
     | 
| 
       744 
     | 
    
         
            -
             
     | 
| 
       745 
     | 
    
         
            -
             
     | 
| 
       746 
     | 
    
         
            -
                        print reset, "\n"
         
     | 
| 
       747 
     | 
    
         
            -
                      else
         
     | 
| 
       748 
     | 
    
         
            -
                        # not needed because it will be http 400
         
     | 
| 
       749 
     | 
    
         
            -
                        print_rest_errors(json_response, options)
         
     | 
| 
       750 
     | 
    
         
            -
                      end
         
     | 
| 
      
 708 
     | 
    
         
            +
                  if options[:validate_only]
         
     | 
| 
      
 709 
     | 
    
         
            +
                    if json_response['success']
         
     | 
| 
      
 710 
     | 
    
         
            +
                      print_h2 "Validated Cart Item", [], options
         
     | 
| 
      
 711 
     | 
    
         
            +
                      cart_item_columns = {
         
     | 
| 
      
 712 
     | 
    
         
            +
                        "Type" => lambda {|it| it['type']['name'] rescue '' },
         
     | 
| 
      
 713 
     | 
    
         
            +
                        #"Qty" => lambda {|it| it['quantity'] },
         
     | 
| 
      
 714 
     | 
    
         
            +
                        "Price" => lambda {|it| it['price'] ? format_money(it['price'] , it['currency'], {sigdig:options[:sigdig] || default_sigdig}) : "No pricing configured" },
         
     | 
| 
      
 715 
     | 
    
         
            +
                        "Status" => lambda {|it| 
         
     | 
| 
      
 716 
     | 
    
         
            +
                          status_string = format_catalog_item_status(it)
         
     | 
| 
      
 717 
     | 
    
         
            +
                          if it['errorMessage'].to_s != ""
         
     | 
| 
      
 718 
     | 
    
         
            +
                            status_string << " - #{it['errorMessage']}"
         
     | 
| 
      
 719 
     | 
    
         
            +
                          end
         
     | 
| 
      
 720 
     | 
    
         
            +
                          status_string
         
     | 
| 
      
 721 
     | 
    
         
            +
                        },
         
     | 
| 
      
 722 
     | 
    
         
            +
                        #"Config" => lambda {|it| truncate_string(format_name_values(it['config']), 50) }
         
     | 
| 
      
 723 
     | 
    
         
            +
                      }
         
     | 
| 
      
 724 
     | 
    
         
            +
                      print as_pretty_table([cart_item], cart_item_columns.upcase_keys!)
         
     | 
| 
      
 725 
     | 
    
         
            +
                      print reset, "\n"
         
     | 
| 
      
 726 
     | 
    
         
            +
                      print_green_success(json_response['msg'] || "Item is valid")
         
     | 
| 
      
 727 
     | 
    
         
            +
                      print reset, "\n"
         
     | 
| 
       751 
728 
     | 
    
         
             
                    else
         
     | 
| 
       752 
     | 
    
         
            -
                       
     | 
| 
       753 
     | 
    
         
            -
                       
     | 
| 
      
 729 
     | 
    
         
            +
                      # not needed because it will be http 400
         
     | 
| 
      
 730 
     | 
    
         
            +
                      print_rest_errors(json_response, options)
         
     | 
| 
       754 
731 
     | 
    
         
             
                    end
         
     | 
| 
      
 732 
     | 
    
         
            +
                  else
         
     | 
| 
      
 733 
     | 
    
         
            +
                    print_green_success "Added item to cart"
         
     | 
| 
      
 734 
     | 
    
         
            +
                    get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
         
     | 
| 
       755 
735 
     | 
    
         
             
                  end
         
     | 
| 
       756 
736 
     | 
    
         
             
                end
         
     | 
| 
       757 
737 
     | 
    
         
             
              end
         
     | 
| 
         @@ -935,6 +915,7 @@ EOT 
     | 
|
| 
       935 
915 
     | 
    
         
             
                  end
         
     | 
| 
       936 
916 
     | 
    
         
             
                  opts.on('--validate','--validate', "Validate Only. Validates the configuration and skips creating the order.") do
         
     | 
| 
       937 
917 
     | 
    
         
             
                    options[:validate_only] = true
         
     | 
| 
      
 918 
     | 
    
         
            +
                    params['validate'] = true
         
     | 
| 
       938 
919 
     | 
    
         
             
                  end
         
     | 
| 
       939 
920 
     | 
    
         
             
                  opts.on('-a', '--details', "Display all details: item configuration." ) do
         
     | 
| 
       940 
921 
     | 
    
         
             
                    options[:details] = true
         
     | 
| 
         @@ -962,7 +943,7 @@ EOT 
     | 
|
| 
       962 
943 
     | 
    
         
             
                end
         
     | 
| 
       963 
944 
     | 
    
         
             
                payload = {}
         
     | 
| 
       964 
945 
     | 
    
         
             
                order_object_key = 'order'
         
     | 
| 
       965 
     | 
    
         
            -
                 
     | 
| 
      
 946 
     | 
    
         
            +
                parse_payload(options, order_object_key) do |payload|
         
     | 
| 
       966 
947 
     | 
    
         
             
                  payload.deep_merge!({order_object_key => {}})
         
     | 
| 
       967 
948 
     | 
    
         
             
                  # Prompt for 1-N Types
         
     | 
| 
       968 
949 
     | 
    
         
             
                  # still_prompting = options[:no_prompt] != true
         
     | 
| 
         @@ -1076,38 +1057,24 @@ EOT 
     | 
|
| 
       1076 
1057 
     | 
    
         
             
                      end
         
     | 
| 
       1077 
1058 
     | 
    
         
             
                    end
         
     | 
| 
       1078 
1059 
     | 
    
         | 
| 
       1079 
     | 
    
         
            -
                  end
         
     | 
| 
       1080 
     | 
    
         
            -
                  
         
     | 
| 
       1081 
     | 
    
         
            -
                  
         
     | 
| 
      
 1060 
     | 
    
         
            +
                  end      
         
     | 
| 
       1082 
1061 
     | 
    
         
             
                end
         
     | 
| 
       1083 
     | 
    
         
            -
                 
     | 
| 
       1084 
     | 
    
         
            -
                  params['validate'] = true
         
     | 
| 
       1085 
     | 
    
         
            -
                  #payload['validate'] = true
         
     | 
| 
       1086 
     | 
    
         
            -
                end
         
     | 
| 
       1087 
     | 
    
         
            -
                process_payloads(payloads, options) do |payload|
         
     | 
| 
       1088 
     | 
    
         
            -
                  @service_catalog_interface.setopts(options)
         
     | 
| 
       1089 
     | 
    
         
            -
                  if options[:dry_run]
         
     | 
| 
       1090 
     | 
    
         
            -
                    print_dry_run @service_catalog_interface.dry.create_order(payload, params)
         
     | 
| 
       1091 
     | 
    
         
            -
                    next
         
     | 
| 
       1092 
     | 
    
         
            -
                  end
         
     | 
| 
       1093 
     | 
    
         
            -
                  json_response = @service_catalog_interface.create_order(payload, params)
         
     | 
| 
      
 1062 
     | 
    
         
            +
                execute_api(@service_catalog_interface, :create_order, [params], options, "order") do |json_response|
         
     | 
| 
       1094 
1063 
     | 
    
         
             
                  order = json_response['order'] || json_response['cart']
         
     | 
| 
       1095 
     | 
    
         
            -
                   
     | 
| 
       1096 
     | 
    
         
            -
                    if  
     | 
| 
       1097 
     | 
    
         
            -
                       
     | 
| 
       1098 
     | 
    
         
            -
                        print_h2 "Review Order", [], options
         
     | 
| 
       1099 
     | 
    
         
            -
                        print_order_details(order, options)
         
     | 
| 
       1100 
     | 
    
         
            -
                        print_green_success(json_response['msg'] || "Order is valid")
         
     | 
| 
       1101 
     | 
    
         
            -
                        print reset, "\n"
         
     | 
| 
       1102 
     | 
    
         
            -
                      else
         
     | 
| 
       1103 
     | 
    
         
            -
                        # not needed because it will be http 400
         
     | 
| 
       1104 
     | 
    
         
            -
                        print_rest_errors(json_response, options)
         
     | 
| 
       1105 
     | 
    
         
            -
                      end
         
     | 
| 
       1106 
     | 
    
         
            -
                    else
         
     | 
| 
       1107 
     | 
    
         
            -
                      print_green_success "Order placed"
         
     | 
| 
       1108 
     | 
    
         
            -
                      print_h2 "Order Details", [], options
         
     | 
| 
      
 1064 
     | 
    
         
            +
                  if options[:validate_only]
         
     | 
| 
      
 1065 
     | 
    
         
            +
                    if json_response['success']
         
     | 
| 
      
 1066 
     | 
    
         
            +
                      print_h2 "Review Order", [], options
         
     | 
| 
       1109 
1067 
     | 
    
         
             
                      print_order_details(order, options)
         
     | 
| 
      
 1068 
     | 
    
         
            +
                      print_green_success(json_response['msg'] || "Order is valid")
         
     | 
| 
      
 1069 
     | 
    
         
            +
                      print reset, "\n"
         
     | 
| 
      
 1070 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1071 
     | 
    
         
            +
                      # not needed because it will be http 400
         
     | 
| 
      
 1072 
     | 
    
         
            +
                      print_rest_errors(json_response, options)
         
     | 
| 
       1110 
1073 
     | 
    
         
             
                    end
         
     | 
| 
      
 1074 
     | 
    
         
            +
                  else
         
     | 
| 
      
 1075 
     | 
    
         
            +
                    print_green_success "Order placed"
         
     | 
| 
      
 1076 
     | 
    
         
            +
                    print_h2 "Order Details", [], options
         
     | 
| 
      
 1077 
     | 
    
         
            +
                    print_order_details(order, options)
         
     | 
| 
       1111 
1078 
     | 
    
         
             
                  end
         
     | 
| 
       1112 
1079 
     | 
    
         
             
                end
         
     | 
| 
       1113 
1080 
     | 
    
         
             
              end
         
     | 
| 
         @@ -158,7 +158,8 @@ EOT 
     | 
|
| 
       158 
158 
     | 
    
         
             
                    "Login URL" => lambda {|it| it['loginURL'] },
         
     | 
| 
       159 
159 
     | 
    
         
             
                    "Default Role" => lambda {|it| it['defaultAccountRole'] ? it['defaultAccountRole']['authority'] : '' },
         
     | 
| 
       160 
160 
     | 
    
         
             
                    "External Login" => lambda {|it| format_boolean it['externalLogin'] },
         
     | 
| 
       161 
     | 
    
         
            -
                    " 
     | 
| 
      
 161 
     | 
    
         
            +
                    "Enable Role Mapping Permission" => lambda {|it| format_boolean it['allowCustomMappings'] },
         
     | 
| 
      
 162 
     | 
    
         
            +
                    "Manual Role Assignment" => lambda {|it| it['manualRoleAssignment'].nil? ? '' : format_boolean(it['manualRoleAssignment']) },
         
     | 
| 
       162 
163 
     | 
    
         
             
                    "Active" => lambda {|it| format_boolean it['active'] },
         
     | 
| 
       163 
164 
     | 
    
         
             
                  }
         
     | 
| 
       164 
165 
     | 
    
         
             
                  print_description_list(description_cols, user_source)
         
     | 
| 
         @@ -235,13 +236,27 @@ EOT 
     | 
|
| 
       235 
236 
     | 
    
         
             
                  opts.on('--description VALUE', String, "Description") do |val|
         
     | 
| 
       236 
237 
     | 
    
         
             
                    params['description'] = val
         
     | 
| 
       237 
238 
     | 
    
         
             
                  end
         
     | 
| 
       238 
     | 
    
         
            -
                  opts.on("--allow-custom-mappings [on|off]", ['on','off'], " 
     | 
| 
      
 239 
     | 
    
         
            +
                  opts.on("--allow-custom-mappings [on|off]", ['on','off'], "Enable Role Mapping Permissions") do |val|
         
     | 
| 
       239 
240 
     | 
    
         
             
                    params['allowCustomMappings'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
         
     | 
| 
       240 
241 
     | 
    
         
             
                  end
         
     | 
| 
       241 
     | 
    
         
            -
                  opts.on("--allowCustomMappings [on|off]", ['on','off'], " 
     | 
| 
      
 242 
     | 
    
         
            +
                  opts.on("--allowCustomMappings [on|off]", ['on','off'], "Enable Role Mapping Permissions") do |val|
         
     | 
| 
       242 
243 
     | 
    
         
             
                    params['allowCustomMappings'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
         
     | 
| 
       243 
244 
     | 
    
         
             
                  end
         
     | 
| 
       244 
245 
     | 
    
         
             
                  opts.add_hidden_option('--allowCustomMappings')
         
     | 
| 
      
 246 
     | 
    
         
            +
                  opts.on("--manual-role-assignment [on|off]", ['on','off'], "Manual Role Assignment") do |val|
         
     | 
| 
      
 247 
     | 
    
         
            +
                    params['manualRoleAssignment'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
         
     | 
| 
      
 248 
     | 
    
         
            +
                  end
         
     | 
| 
      
 249 
     | 
    
         
            +
                  opts.on("--manualRoleAssignment [on|off]", ['on','off'], "Manual Role Assignment") do |val|
         
     | 
| 
      
 250 
     | 
    
         
            +
                    params['manualRoleAssignment'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
         
     | 
| 
      
 251 
     | 
    
         
            +
                  end
         
     | 
| 
      
 252 
     | 
    
         
            +
                  opts.add_hidden_option('--manualRoleAssignment')
         
     | 
| 
      
 253 
     | 
    
         
            +
                  opts.on("--manual-role-assignment [on|off]", ['on','off'], "Manual Role Assignment") do |val|
         
     | 
| 
      
 254 
     | 
    
         
            +
                    params['manualRoleAssignment'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
         
     | 
| 
      
 255 
     | 
    
         
            +
                  end
         
     | 
| 
      
 256 
     | 
    
         
            +
                  opts.on("--manualRoleAssignment [on|off]", ['on','off'], "Manual Role Assignment") do |val|
         
     | 
| 
      
 257 
     | 
    
         
            +
                    params['manualRoleAssignment'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
         
     | 
| 
      
 258 
     | 
    
         
            +
                  end
         
     | 
| 
      
 259 
     | 
    
         
            +
                  opts.add_hidden_option('--manualRoleAssignment')
         
     | 
| 
       245 
260 
     | 
    
         
             
                  opts.on('--role-mappings MAPPINGS', String, "Role Mappings FQN in the format id1:FQN1,id2:FQN2") do |val|
         
     | 
| 
       246 
261 
     | 
    
         
             
                    role_mappings = {}
         
     | 
| 
       247 
262 
     | 
    
         
             
                    val.split(',').collect {|it| it.strip.split(':') }.each do |pair|
         
     | 
| 
         @@ -386,14 +401,22 @@ EOT 
     | 
|
| 
       386 
401 
     | 
    
         
             
                    end
         
     | 
| 
       387 
402 
     | 
    
         
             
                    payload['userSource']['defaultAccountRole'] = {'id' => default_role_id }
         
     | 
| 
       388 
403 
     | 
    
         | 
| 
       389 
     | 
    
         
            -
                    #  
     | 
| 
      
 404 
     | 
    
         
            +
                    # Enable Role Mapping Permissions
         
     | 
| 
       390 
405 
     | 
    
         
             
                    if !params['allowCustomMappings'].nil?
         
     | 
| 
       391 
406 
     | 
    
         
             
                      payload['userSource']['allowCustomMappings'] = ["on","true"].include?(params['allowCustomMappings'].to_s)
         
     | 
| 
       392 
407 
     | 
    
         
             
                    else
         
     | 
| 
       393 
     | 
    
         
            -
                      v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'allowCustomMappings', 'type' => 'checkbox', 'fieldLabel' => ' 
     | 
| 
      
 408 
     | 
    
         
            +
                      v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'allowCustomMappings', 'type' => 'checkbox', 'fieldLabel' => 'Enable Role Mapping Permissions', 'defaultValue' => false}], options[:options])
         
     | 
| 
       394 
409 
     | 
    
         
             
                      payload['userSource']['allowCustomMappings'] = ["on","true"].include?(v_prompt['allowCustomMappings'].to_s)
         
     | 
| 
       395 
410 
     | 
    
         
             
                    end
         
     | 
| 
       396 
411 
     | 
    
         | 
| 
      
 412 
     | 
    
         
            +
                    # Manual Role Assignment
         
     | 
| 
      
 413 
     | 
    
         
            +
                    if !params['manualRoleAssignment'].nil?
         
     | 
| 
      
 414 
     | 
    
         
            +
                      payload['userSource']['manualRoleAssignment'] = ["on","true"].include?(params['allowCustomMappings'].to_s)
         
     | 
| 
      
 415 
     | 
    
         
            +
                    else
         
     | 
| 
      
 416 
     | 
    
         
            +
                      v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'manualRoleAssignment', 'type' => 'checkbox', 'fieldLabel' => 'Manual Role Assignment', 'defaultValue' => false}], options[:options])
         
     | 
| 
      
 417 
     | 
    
         
            +
                      payload['userSource']['manualRoleAssignment'] = ["on","true"].include?(v_prompt['manualRoleAssignment'].to_s)
         
     | 
| 
      
 418 
     | 
    
         
            +
                    end
         
     | 
| 
      
 419 
     | 
    
         
            +
             
     | 
| 
       397 
420 
     | 
    
         
             
                    if role_mappings
         
     | 
| 
       398 
421 
     | 
    
         
             
                      payload['roleMappings'] = role_mappings
         
     | 
| 
       399 
422 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -435,10 +458,10 @@ EOT 
     | 
|
| 
       435 
458 
     | 
    
         
             
                  opts.on('--description VALUE', String, "Description") do |val|
         
     | 
| 
       436 
459 
     | 
    
         
             
                    params['description'] = val
         
     | 
| 
       437 
460 
     | 
    
         
             
                  end
         
     | 
| 
       438 
     | 
    
         
            -
                  opts.on("--allow-custom-mappings [on|off]", ['on','off'], " 
     | 
| 
      
 461 
     | 
    
         
            +
                  opts.on("--allow-custom-mappings [on|off]", ['on','off'], "Enable Role Mapping Permissions") do |val|
         
     | 
| 
       439 
462 
     | 
    
         
             
                    params['allowCustomMappings'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
         
     | 
| 
       440 
463 
     | 
    
         
             
                  end
         
     | 
| 
       441 
     | 
    
         
            -
                  opts.on("--allowCustomMappings [on|off]", ['on','off'], " 
     | 
| 
      
 464 
     | 
    
         
            +
                  opts.on("--allowCustomMappings [on|off]", ['on','off'], "Enable Role Mapping Permissions") do |val|
         
     | 
| 
       442 
465 
     | 
    
         
             
                    params['allowCustomMappings'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
         
     | 
| 
       443 
466 
     | 
    
         
             
                  end
         
     | 
| 
       444 
467 
     | 
    
         
             
                  opts.add_hidden_option('--allowCustomMappings')
         
     | 
| 
         @@ -493,11 +516,16 @@ EOT 
     | 
|
| 
       493 
516 
     | 
    
         
             
                      payload['userSource']['description'] = params['description']
         
     | 
| 
       494 
517 
     | 
    
         
             
                    end
         
     | 
| 
       495 
518 
     | 
    
         | 
| 
       496 
     | 
    
         
            -
                    #  
     | 
| 
      
 519 
     | 
    
         
            +
                    # Enable Role Mapping Permissions
         
     | 
| 
       497 
520 
     | 
    
         
             
                    if !params['allowCustomMappings'].nil?
         
     | 
| 
       498 
521 
     | 
    
         
             
                      payload['userSource']['allowCustomMappings'] = params['allowCustomMappings']
         
     | 
| 
       499 
522 
     | 
    
         
             
                    end
         
     | 
| 
       500 
523 
     | 
    
         | 
| 
      
 524 
     | 
    
         
            +
                    # Manual Role Assignment
         
     | 
| 
      
 525 
     | 
    
         
            +
                    if !params['manualRoleAssignment'].nil?
         
     | 
| 
      
 526 
     | 
    
         
            +
                      payload['userSource']['manualRoleAssignment'] = params['manualRoleAssignment']
         
     | 
| 
      
 527 
     | 
    
         
            +
                    end
         
     | 
| 
      
 528 
     | 
    
         
            +
             
     | 
| 
       501 
529 
     | 
    
         
             
                    if role_mappings
         
     | 
| 
       502 
530 
     | 
    
         
             
                      payload['roleMappings'] = role_mappings
         
     | 
| 
       503 
531 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -46,20 +46,22 @@ Examples: 
     | 
|
| 
       46 
46 
     | 
    
         
             
            EOT
         
     | 
| 
       47 
47 
     | 
    
         
             
                end
         
     | 
| 
       48 
48 
     | 
    
         
             
                optparse.parse!(args)
         
     | 
| 
       49 
     | 
    
         
            -
                 
     | 
| 
      
 49 
     | 
    
         
            +
                verify_args!(args:args, optparse:optparse, min: 0, max: 2)
         
     | 
| 
       50 
50 
     | 
    
         
             
                connect(options)
         
     | 
| 
       51 
51 
     | 
    
         
             
                # todo: it would actually be cool to use the params and include them on the path..
         
     | 
| 
       52 
52 
     | 
    
         
             
                # params.merge!(parse_query_options(options))
         
     | 
| 
       53 
     | 
    
         
            -
                 
     | 
| 
      
 53 
     | 
    
         
            +
                # input, *ids = args
         
     | 
| 
      
 54 
     | 
    
         
            +
                input = args[0]
         
     | 
| 
      
 55 
     | 
    
         
            +
                id = args[1]
         
     | 
| 
       54 
56 
     | 
    
         
             
                # default to index page "/"
         
     | 
| 
       55 
     | 
    
         
            -
                path =  
     | 
| 
      
 57 
     | 
    
         
            +
                path = input || "/"
         
     | 
| 
       56 
58 
     | 
    
         
             
                if options[:absolute_path] != true
         
     | 
| 
       57 
59 
     | 
    
         
             
                  if path.start_with?("/")
         
     | 
| 
       58 
60 
     | 
    
         
             
                    # treat like absolute path, no lookup
         
     | 
| 
       59 
61 
     | 
    
         
             
                  else
         
     | 
| 
       60 
62 
     | 
    
         
             
                    # lookup best matching route from sitemap
         
     | 
| 
       61 
63 
     | 
    
         
             
                    # lookup plural routes first, so 'app' finds apps and not approvals
         
     | 
| 
       62 
     | 
    
         
            -
                    found_route = Morpheus::Routes.lookup(path)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    found_route = Morpheus::Routes.lookup(path, id)
         
     | 
| 
       63 
65 
     | 
    
         
             
                    if found_route
         
     | 
| 
       64 
66 
     | 
    
         
             
                      # Morpheus::Logging::DarkPrinter.puts "Found matching route: '#{path}' => '#{found_route}'" if Morpheus::Logging.debug?
         
     | 
| 
       65 
67 
     | 
    
         
             
                      path = found_route
         
     | 
| 
         @@ -69,26 +71,24 @@ EOT 
     | 
|
| 
       69 
71 
     | 
    
         
             
                  end
         
     | 
| 
       70 
72 
     | 
    
         
             
                  # always add a leading slash
         
     | 
| 
       71 
73 
     | 
    
         
             
                  path = path.start_with?("/") ? path : "/#{path}"
         
     | 
| 
       72 
     | 
    
         
            -
                  # append id 
     | 
| 
       73 
     | 
    
         
            -
                  if  
     | 
| 
       74 
     | 
    
         
            -
                    # convert  
     | 
| 
      
 74 
     | 
    
         
            +
                  # append id to path if passed
         
     | 
| 
      
 75 
     | 
    
         
            +
                  if id
         
     | 
| 
      
 76 
     | 
    
         
            +
                    # convert name to id
         
     | 
| 
       75 
77 
     | 
    
         
             
                    # assume the last part of path is the type and use generic finder
         
     | 
| 
       76 
78 
     | 
    
         
             
                    # only lookup names, and allow any id
         
     | 
| 
       77 
     | 
    
         
            -
                     
     | 
| 
       78 
     | 
    
         
            -
                       
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                         
     | 
| 
       86 
     | 
    
         
            -
                        record['id'].to_s
         
     | 
| 
       87 
     | 
    
         
            -
                      else
         
     | 
| 
       88 
     | 
    
         
            -
                        id
         
     | 
| 
      
 79 
     | 
    
         
            +
                    if id.to_s !~ /\A\d{1,}\Z/
         
     | 
| 
      
 80 
     | 
    
         
            +
                      # record type is just args[0]
         
     | 
| 
      
 81 
     | 
    
         
            +
                      record_type = input
         
     | 
| 
      
 82 
     | 
    
         
            +
                      # assume the last part of path is the type
         
     | 
| 
      
 83 
     | 
    
         
            +
                      # record_type = path.split("/").last
         
     | 
| 
      
 84 
     | 
    
         
            +
                      # record_type.sub!('#!', '')
         
     | 
| 
      
 85 
     | 
    
         
            +
                      record = find_by_name(record_type, id)
         
     | 
| 
      
 86 
     | 
    
         
            +
                      if record.nil?
         
     | 
| 
      
 87 
     | 
    
         
            +
                        raise_command_error("[id] is invalid. No #{record_type} found for '#{id}'", args, optparse)
         
     | 
| 
       89 
88 
     | 
    
         
             
                      end
         
     | 
| 
      
 89 
     | 
    
         
            +
                      id = record['id'].to_s
         
     | 
| 
       90 
90 
     | 
    
         
             
                    end
         
     | 
| 
       91 
     | 
    
         
            -
                    path = "#{path} 
     | 
| 
      
 91 
     | 
    
         
            +
                    path = "#{path}/#{id}"
         
     | 
| 
       92 
92 
     | 
    
         
             
                  end
         
     | 
| 
       93 
93 
     | 
    
         
             
                end
         
     | 
| 
       94 
94 
     | 
    
         
             
                # build the link to use, either our path or oauth-redirect to that path
         
     | 
| 
         @@ -110,4 +110,62 @@ module Morpheus::Cli::BackupsHelper 
     | 
|
| 
       110 
110 
     | 
    
         
             
                  return backup_jobs[0]
         
     | 
| 
       111 
111 
     | 
    
         
             
                end
         
     | 
| 
       112 
112 
     | 
    
         
             
              end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
              ## Backup Results
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
              def backup_result_list_column_definitions()
         
     | 
| 
      
 117 
     | 
    
         
            +
                {
         
     | 
| 
      
 118 
     | 
    
         
            +
                  "ID" => 'id',
         
     | 
| 
      
 119 
     | 
    
         
            +
                  "Backup" => lambda {|it| it['backup']['name'] rescue '' },
         
     | 
| 
      
 120 
     | 
    
         
            +
                  "Status" => lambda {|it| format_backup_result_status(it) },
         
     | 
| 
      
 121 
     | 
    
         
            +
                  #"Duration" => lambda {|it| format_duration(it['startDate'], it['endDate']) },
         
     | 
| 
      
 122 
     | 
    
         
            +
                  "Duration" => lambda {|it| format_duration_milliseconds(it['durationMillis']) },
         
     | 
| 
      
 123 
     | 
    
         
            +
                  "Start Date" => lambda {|it| format_local_dt(it['startDate']) },
         
     | 
| 
      
 124 
     | 
    
         
            +
                  "End Date" => lambda {|it| format_local_dt(it['endDate']) },
         
     | 
| 
      
 125 
     | 
    
         
            +
                  "Size" => lambda {|it| format_bytes(it['sizeInMb'], 'MB') },
         
     | 
| 
      
 126 
     | 
    
         
            +
                }
         
     | 
| 
      
 127 
     | 
    
         
            +
              end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
              def backup_result_column_definitions()
         
     | 
| 
      
 130 
     | 
    
         
            +
                backup_result_list_column_definitions()
         
     | 
| 
      
 131 
     | 
    
         
            +
              end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
              def format_backup_result_status(backup_result, return_color=cyan)
         
     | 
| 
      
 134 
     | 
    
         
            +
                out = ""
         
     | 
| 
      
 135 
     | 
    
         
            +
                status_string = backup_result['status'].to_s.upcase
         
     | 
| 
      
 136 
     | 
    
         
            +
                if status_string == 'SUCCEEDED' || status_string == 'SUCCESS'
         
     | 
| 
      
 137 
     | 
    
         
            +
                  out <<  "#{green}#{status_string.upcase}#{return_color}"
         
     | 
| 
      
 138 
     | 
    
         
            +
                elsif status_string == 'FAILED'
         
     | 
| 
      
 139 
     | 
    
         
            +
                  out <<  "#{red}#{status_string.upcase}#{return_color}"
         
     | 
| 
      
 140 
     | 
    
         
            +
                elsif status_string
         
     | 
| 
      
 141 
     | 
    
         
            +
                  out <<  "#{cyan}#{status_string.upcase}#{return_color}"
         
     | 
| 
      
 142 
     | 
    
         
            +
                else
         
     | 
| 
      
 143 
     | 
    
         
            +
                  out <<  ""
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
                out
         
     | 
| 
      
 146 
     | 
    
         
            +
              end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
              ## Backup Restores
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
              def backup_restore_list_column_definitions()
         
     | 
| 
      
 151 
     | 
    
         
            +
                {
         
     | 
| 
      
 152 
     | 
    
         
            +
                  "ID" => 'id',
         
     | 
| 
      
 153 
     | 
    
         
            +
                  "Backup" => lambda {|it| it['backup']['name'] rescue '' },
         
     | 
| 
      
 154 
     | 
    
         
            +
                  "Backup Result ID" => lambda {|it| it['backupResultId'] rescue '' },
         
     | 
| 
      
 155 
     | 
    
         
            +
                  "Target" => lambda {|it| it['instance']['name'] rescue '' },
         
     | 
| 
      
 156 
     | 
    
         
            +
                  "Status" => lambda {|it| format_backup_result_status(it) },
         
     | 
| 
      
 157 
     | 
    
         
            +
                  #"Duration" => lambda {|it| format_duration(it['startDate'], it['endDate']) },
         
     | 
| 
      
 158 
     | 
    
         
            +
                  "Duration" => lambda {|it| format_duration_milliseconds(it['durationMillis']) },
         
     | 
| 
      
 159 
     | 
    
         
            +
                  "Start Date" => lambda {|it| format_local_dt(it['startDate']) },
         
     | 
| 
      
 160 
     | 
    
         
            +
                  "End Date" => lambda {|it| format_local_dt(it['endDate']) },
         
     | 
| 
      
 161 
     | 
    
         
            +
                }
         
     | 
| 
      
 162 
     | 
    
         
            +
              end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
              def backup_restore_column_definitions()
         
     | 
| 
      
 165 
     | 
    
         
            +
                backup_restore_list_column_definitions()
         
     | 
| 
      
 166 
     | 
    
         
            +
              end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
              def format_backup_restore_status(backup_restore, return_color=cyan)
         
     | 
| 
      
 169 
     | 
    
         
            +
                format_backup_result_status(backup_restore, return_color)
         
     | 
| 
      
 170 
     | 
    
         
            +
              end
         
     | 
| 
       113 
171 
     | 
    
         
             
            end
         
     | 
| 
         @@ -191,7 +191,24 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       191 
191 
     | 
    
         
             
                output = ""
         
     | 
| 
       192 
192 
     | 
    
         
             
                if api_request[:curl] || options[:curl]
         
     | 
| 
       193 
193 
     | 
    
         
             
                  output = format_curl_command(http_method, url, headers, payload, options)
         
     | 
| 
      
 194 
     | 
    
         
            +
                elsif options[:json]
         
     | 
| 
      
 195 
     | 
    
         
            +
                  # --dry --json should print the payload only
         
     | 
| 
      
 196 
     | 
    
         
            +
                  payload_object = payload.is_a?(String) ? JSON.parse(payload) : payload
         
     | 
| 
      
 197 
     | 
    
         
            +
                  output = as_json(payload_object, options)
         
     | 
| 
      
 198 
     | 
    
         
            +
                elsif options[:yaml]
         
     | 
| 
      
 199 
     | 
    
         
            +
                  # --dry --yaml should print the payload only as yaml
         
     | 
| 
      
 200 
     | 
    
         
            +
                  payload_object = payload.is_a?(String) ? JSON.parse(payload) : payload
         
     | 
| 
      
 201 
     | 
    
         
            +
                  output = as_yaml(payload_object, options)
         
     | 
| 
       194 
202 
     | 
    
         
             
                else
         
     | 
| 
      
 203 
     | 
    
         
            +
                  # default format is 
         
     | 
| 
      
 204 
     | 
    
         
            +
                  # DRY RUN
         
     | 
| 
      
 205 
     | 
    
         
            +
                  # REQUEST
         
     | 
| 
      
 206 
     | 
    
         
            +
                  # GET https://server/api/things
         
     | 
| 
      
 207 
     | 
    
         
            +
                  #
         
     | 
| 
      
 208 
     | 
    
         
            +
                  # JSON
         
     | 
| 
      
 209 
     | 
    
         
            +
                  # {
         
     | 
| 
      
 210 
     | 
    
         
            +
                  #    "thing": { ... }
         
     | 
| 
      
 211 
     | 
    
         
            +
                  # }
         
     | 
| 
       195 
212 
     | 
    
         
             
                  output = format_api_request(http_method, url, headers, payload, options)
         
     | 
| 
       196 
213 
     | 
    
         
             
                end
         
     | 
| 
       197 
214 
     | 
    
         
             
                # this is an extra scrub, should remove
         
     | 
| 
         @@ -210,14 +227,20 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       210 
227 
     | 
    
         
             
                if api_request[:curl] || options[:curl]
         
     | 
| 
       211 
228 
     | 
    
         
             
                  print "\n"
         
     | 
| 
       212 
229 
     | 
    
         
             
                  print "#{cyan}#{bold}#{dark}CURL COMMAND#{reset}\n"
         
     | 
| 
      
 230 
     | 
    
         
            +
                  print output
         
     | 
| 
      
 231 
     | 
    
         
            +
                  print reset, "\n"
         
     | 
| 
      
 232 
     | 
    
         
            +
                  print reset
         
     | 
| 
      
 233 
     | 
    
         
            +
                elsif options[:json] || options[:yaml]
         
     | 
| 
      
 234 
     | 
    
         
            +
                  # print just the just payload
         
     | 
| 
      
 235 
     | 
    
         
            +
                  print output, "\n"
         
     | 
| 
       213 
236 
     | 
    
         
             
                else
         
     | 
| 
       214 
237 
     | 
    
         
             
                  print "\n"
         
     | 
| 
       215 
238 
     | 
    
         
             
                  print "#{cyan}#{bold}#{dark}REQUEST#{reset}\n"
         
     | 
| 
      
 239 
     | 
    
         
            +
                  print output
         
     | 
| 
      
 240 
     | 
    
         
            +
                  print reset, "\n"
         
     | 
| 
      
 241 
     | 
    
         
            +
                  print reset
         
     | 
| 
       216 
242 
     | 
    
         
             
                end
         
     | 
| 
       217 
     | 
    
         
            -
                 
     | 
| 
       218 
     | 
    
         
            -
                print reset, "\n"
         
     | 
| 
       219 
     | 
    
         
            -
                print reset
         
     | 
| 
       220 
     | 
    
         
            -
                return
         
     | 
| 
      
 243 
     | 
    
         
            +
                return output
         
     | 
| 
       221 
244 
     | 
    
         
             
              end
         
     | 
| 
       222 
245 
     | 
    
         | 
| 
       223 
246 
     | 
    
         
             
              def print_system_command_dry_run(cmd, options={})
         
     | 
| 
         @@ -48,6 +48,7 @@ module Morpheus 
     | 
|
| 
       48 
48 
     | 
    
         | 
| 
       49 
49 
     | 
    
         
             
                  # supresses prompting unless --prompt has been passed
         
     | 
| 
       50 
50 
     | 
    
         
             
                  def self.no_prompt(option_types, options={}, api_client=nil,api_params={})
         
     | 
| 
      
 51 
     | 
    
         
            +
                    options[:edit_mode] = true # hack used for updates to avoid default values being used
         
     | 
| 
       51 
52 
     | 
    
         
             
                    if options[:always_prompt]
         
     | 
| 
       52 
53 
     | 
    
         
             
                      prompt(option_types, options, api_client, api_params)
         
     | 
| 
       53 
54 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -218,7 +219,7 @@ module Morpheus 
     | 
|
| 
       218 
219 
     | 
    
         | 
| 
       219 
220 
     | 
    
         
             
                      # credential type
         
     | 
| 
       220 
221 
     | 
    
         
             
                      handle_credential_type = -> {
         
     | 
| 
       221 
     | 
    
         
            -
                        credential_type = select_prompt(option_type.merge({'defaultValue' => value}), api_client, option_params.merge({'credentialTypes' => option_type['config']['credentialTypes']}), !value.nil?, nil, paging_enabled, ignore_empty)
         
     | 
| 
      
 222 
     | 
    
         
            +
                        credential_type = select_prompt(option_type.merge({'defaultValue' => value}), api_client, option_params.merge({'credentialTypes' => option_type['config']['credentialTypes']}), !value.nil?, nil, paging_enabled, ignore_empty, options[:edit_mode])
         
     | 
| 
       222 
223 
     | 
    
         
             
                        # continue prompting for local creds
         
     | 
| 
       223 
224 
     | 
    
         
             
                        if credential_type == 'local'
         
     | 
| 
       224 
225 
     | 
    
         
             
                          parent_context_map.reject! {|k,v| k == 'credential'}
         
     | 
| 
         @@ -247,14 +248,14 @@ module Morpheus 
     | 
|
| 
       247 
248 
     | 
    
         
             
                          end
         
     | 
| 
       248 
249 
     | 
    
         
             
                        # these select prompts should just fall down through below, with the extra params no_prompt, use_value
         
     | 
| 
       249 
250 
     | 
    
         
             
                        elsif option_type['type'] == 'select'
         
     | 
| 
       250 
     | 
    
         
            -
                          value = select_prompt(option_type.merge({'defaultValue' => value, 'defaultInputValue' => input_value}), api_client, option_params, true, nil, false, ignore_empty)
         
     | 
| 
      
 251 
     | 
    
         
            +
                          value = select_prompt(option_type.merge({'defaultValue' => value, 'defaultInputValue' => input_value}), api_client, option_params, true, nil, false, ignore_empty, options[:edit_mode])
         
     | 
| 
       251 
252 
     | 
    
         
             
                        elsif option_type['type'] == 'multiSelect'
         
     | 
| 
       252 
253 
     | 
    
         
             
                          # support value as csv like "thing1, thing2"
         
     | 
| 
       253 
254 
     | 
    
         
             
                          value_list = value.is_a?(String) ? value.parse_csv.collect {|v| v ? v.to_s.strip : v } : [value].flatten
         
     | 
| 
       254 
255 
     | 
    
         
             
                          input_value_list = input_value.is_a?(String) ? input_value.parse_csv.collect {|v| v ? v.to_s.strip : v } : [input_value].flatten
         
     | 
| 
       255 
256 
     | 
    
         
             
                          select_value_list = []
         
     | 
| 
       256 
257 
     | 
    
         
             
                          value_list.each_with_index do |v, i|
         
     | 
| 
       257 
     | 
    
         
            -
                            select_value_list << select_prompt(option_type.merge({'defaultValue' => v, 'defaultInputValue' => input_value_list[i]}), api_client, option_params, true, nil, false, ignore_empty)
         
     | 
| 
      
 258 
     | 
    
         
            +
                            select_value_list << select_prompt(option_type.merge({'defaultValue' => v, 'defaultInputValue' => input_value_list[i]}), api_client, option_params, true, nil, false, ignore_empty, options[:edit_mode])
         
     | 
| 
       258 
259 
     | 
    
         
             
                          end
         
     | 
| 
       259 
260 
     | 
    
         
             
                          value = select_value_list
         
     | 
| 
       260 
261 
     | 
    
         
             
                        elsif option_type['type'] == 'typeahead'
         
     | 
| 
         @@ -302,7 +303,7 @@ module Morpheus 
     | 
|
| 
       302 
303 
     | 
    
         
             
                              next
         
     | 
| 
       303 
304 
     | 
    
         
             
                            end
         
     | 
| 
       304 
305 
     | 
    
         
             
                            if ['select', 'multiSelect'].include?(option_type['type'])
         
     | 
| 
       305 
     | 
    
         
            -
                              value = select_prompt(option_type, api_client, option_params, true, nil, false, ignore_empty)
         
     | 
| 
      
 306 
     | 
    
         
            +
                              value = select_prompt(option_type, api_client, option_params, true, nil, false, ignore_empty, options[:edit_mode])
         
     | 
| 
       306 
307 
     | 
    
         
             
                              value_found = !!value
         
     | 
| 
       307 
308 
     | 
    
         
             
                            end
         
     | 
| 
       308 
309 
     | 
    
         
             
                            if ['typeahead', 'multiTypeahead'].include?(option_type['type'])
         
     | 
| 
         @@ -347,12 +348,12 @@ module Morpheus 
     | 
|
| 
       347 
348 
     | 
    
         
             
                          # I suppose the entered value should take precedence
         
     | 
| 
       348 
349 
     | 
    
         
             
                          # api_params = api_params.merge(options) # this might be good enough
         
     | 
| 
       349 
350 
     | 
    
         
             
                          # dup it
         
     | 
| 
       350 
     | 
    
         
            -
                          value = select_prompt(option_type, api_client, option_params, options[:no_prompt], nil, paging_enabled, ignore_empty)
         
     | 
| 
      
 351 
     | 
    
         
            +
                          value = select_prompt(option_type, api_client, option_params, options[:no_prompt], nil, paging_enabled, ignore_empty, options[:edit_mode])
         
     | 
| 
       351 
352 
     | 
    
         
             
                          if value && option_type['type'] == 'multiSelect'
         
     | 
| 
       352 
353 
     | 
    
         
             
                            value = [value]
         
     | 
| 
       353 
354 
     | 
    
         
             
                            recommended_count = (option_type['config'] || {})['recommendedCount'] || 0
         
     | 
| 
       354 
355 
     | 
    
         
             
                            while self.confirm("Add another #{option_type['fieldLabel']}?", {:default => recommended_count > value.count}) do
         
     | 
| 
       355 
     | 
    
         
            -
                              if addn_value = select_prompt(option_type, api_client, option_params, options[:no_prompt], nil, paging_enabled, ignore_empty)
         
     | 
| 
      
 356 
     | 
    
         
            +
                              if addn_value = select_prompt(option_type, api_client, option_params, options[:no_prompt], nil, paging_enabled, ignore_empty, options[:edit_mode])
         
     | 
| 
       356 
357 
     | 
    
         
             
                                value << addn_value
         
     | 
| 
       357 
358 
     | 
    
         
             
                              else
         
     | 
| 
       358 
359 
     | 
    
         
             
                                break
         
     | 
| 
         @@ -476,7 +477,7 @@ module Morpheus 
     | 
|
| 
       476 
477 
     | 
    
         
             
                    Thread.current[:_last_select]
         
     | 
| 
       477 
478 
     | 
    
         
             
                  end
         
     | 
| 
       478 
479 
     | 
    
         | 
| 
       479 
     | 
    
         
            -
                  def self.select_prompt(option_type, api_client, api_params={}, no_prompt=false, use_value=nil, paging_enabled=false, ignore_empty=false)
         
     | 
| 
      
 480 
     | 
    
         
            +
                  def self.select_prompt(option_type, api_client, api_params={}, no_prompt=false, use_value=nil, paging_enabled=false, ignore_empty=false, edit_mode=false)
         
     | 
| 
       480 
481 
     | 
    
         
             
                    paging_enabled = false if Morpheus::Cli.windows?
         
     | 
| 
       481 
482 
     | 
    
         
             
                    field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
         
     | 
| 
       482 
483 
     | 
    
         
             
                    help_field_key = option_type[:help_field_prefix] ? "#{option_type[:help_field_prefix]}.#{field_key}" : field_key
         
     | 
| 
         @@ -550,6 +551,8 @@ module Morpheus 
     | 
|
| 
       550 
551 
     | 
    
         
             
                        print "\n"
         
     | 
| 
       551 
552 
     | 
    
         
             
                        exit 1
         
     | 
| 
       552 
553 
     | 
    
         
             
                      end
         
     | 
| 
      
 554 
     | 
    
         
            +
                    elsif edit_mode
         
     | 
| 
      
 555 
     | 
    
         
            +
                      # do not use a default value for edit mode
         
     | 
| 
       553 
556 
     | 
    
         
             
                    # skipSingleOption is no longer supported
         
     | 
| 
       554 
557 
     | 
    
         
             
                    # elsif !select_options.nil? && select_options.count == 1 && option_type['skipSingleOption'] == true
         
     | 
| 
       555 
558 
     | 
    
         
             
                    #   value_found = true
         
     | 
    
        data/lib/morpheus/cli/version.rb
    CHANGED
    
    
    
        data/lib/morpheus/formatters.rb
    CHANGED
    
    | 
         @@ -134,7 +134,7 @@ end 
     | 
|
| 
       134 
134 
     | 
    
         | 
| 
       135 
135 
     | 
    
         
             
            def format_duration_milliseconds(milliseconds, format="human", ms_threshold=1000)
         
     | 
| 
       136 
136 
     | 
    
         
             
              out = ""
         
     | 
| 
       137 
     | 
    
         
            -
              milliseconds = milliseconds.abs 
     | 
| 
      
 137 
     | 
    
         
            +
              milliseconds = milliseconds.to_i.abs
         
     | 
| 
       138 
138 
     | 
    
         
             
              if ms_threshold && ms_threshold > milliseconds
         
     | 
| 
       139 
139 
     | 
    
         
             
                out = "#{milliseconds}ms"
         
     | 
| 
       140 
140 
     | 
    
         
             
              else
         
     |