morpheus-cli 5.4.4.2 → 5.5.0
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/apps_interface.rb +18 -4
 - data/lib/morpheus/api/instances_interface.rb +16 -2
 - data/lib/morpheus/api/prices_interface.rb +6 -0
 - data/lib/morpheus/cli/cli_command.rb +16 -3
 - data/lib/morpheus/cli/commands/apps.rb +366 -47
 - data/lib/morpheus/cli/commands/clouds.rb +51 -27
 - data/lib/morpheus/cli/commands/clusters.rb +70 -10
 - data/lib/morpheus/cli/commands/cypher_command.rb +22 -23
 - data/lib/morpheus/cli/commands/dashboard_command.rb +1 -1
 - data/lib/morpheus/cli/commands/execution_request_command.rb +9 -4
 - data/lib/morpheus/cli/commands/file_copy_request_command.rb +2 -1
 - data/lib/morpheus/cli/commands/instances.rb +307 -24
 - data/lib/morpheus/cli/commands/library_layouts_command.rb +15 -0
 - data/lib/morpheus/cli/commands/library_option_lists_command.rb +18 -8
 - data/lib/morpheus/cli/commands/prices_command.rb +25 -11
 - data/lib/morpheus/cli/commands/provisioning_licenses_command.rb +1 -1
 - data/lib/morpheus/cli/commands/tasks.rb +45 -10
 - data/lib/morpheus/cli/mixins/execution_request_helper.rb +50 -0
 - data/lib/morpheus/cli/mixins/provisioning_helper.rb +5 -4
 - data/lib/morpheus/cli/option_types.rb +32 -1
 - data/lib/morpheus/cli/version.rb +1 -1
 - data/lib/morpheus/formatters.rb +12 -0
 - data/lib/morpheus/routes.rb +3 -5
 - metadata +3 -2
 
| 
         @@ -187,6 +187,7 @@ EOT 
     | 
|
| 
       187 
187 
     | 
    
         
             
                      ""
         
     | 
| 
       188 
188 
     | 
    
         
             
                    end
         
     | 
| 
       189 
189 
     | 
    
         
             
                  },
         
     | 
| 
      
 190 
     | 
    
         
            +
                  "Tfvar Secret" => lambda {|it| it['tfvarSecret'] },
         
     | 
| 
       190 
191 
     | 
    
         
             
                  # "Category" => lambda {|it| it['category'].to_s.capitalize },
         
     | 
| 
       191 
192 
     | 
    
         
             
                  # # "Logo" => lambda {|it| it['logo'].to_s },
         
     | 
| 
       192 
193 
     | 
    
         
             
                  # "Visiblity" => lambda {|it| it['visibility'].to_s.capitalize },
         
     | 
| 
         @@ -200,6 +201,7 @@ EOT 
     | 
|
| 
       200 
201 
     | 
    
         
             
                  # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
         
     | 
| 
       201 
202 
     | 
    
         
             
                  # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
         
     | 
| 
       202 
203 
     | 
    
         
             
                }
         
     | 
| 
      
 204 
     | 
    
         
            +
                description_cols.delete("Tfvar Secret") if !(layout['provisionType'] && layout['provisionType']['code'] == 'terraform')
         
     | 
| 
       203 
205 
     | 
    
         
             
                print_description_list(description_cols, layout)
         
     | 
| 
       204 
206 
     | 
    
         | 
| 
       205 
207 
     | 
    
         | 
| 
         @@ -338,6 +340,9 @@ EOT 
     | 
|
| 
       338 
340 
     | 
    
         
             
                      params['specTemplates'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
         
     | 
| 
       339 
341 
     | 
    
         
             
                    end
         
     | 
| 
       340 
342 
     | 
    
         
             
                  end
         
     | 
| 
      
 343 
     | 
    
         
            +
                  opts.on('--tfvar-secret VALUE', String, "Tfvar Secret name, eg. 'tfvars/dev-key'") do |val|
         
     | 
| 
      
 344 
     | 
    
         
            +
                    params['tfvarSecret'] = val == 'null' ? nil : val
         
     | 
| 
      
 345 
     | 
    
         
            +
                  end
         
     | 
| 
       341 
346 
     | 
    
         
             
                  add_perms_options(opts, options, layout_permission_excludes)
         
     | 
| 
       342 
347 
     | 
    
         
             
                  build_standard_add_options(opts, options)
         
     | 
| 
       343 
348 
     | 
    
         
             
                  opts.footer = <<-EOT
         
     | 
| 
         @@ -453,6 +458,13 @@ EOT 
     | 
|
| 
       453 
458 
     | 
    
         
             
                      return 1
         
     | 
| 
       454 
459 
     | 
    
         
             
                    end
         
     | 
| 
       455 
460 
     | 
    
         | 
| 
      
 461 
     | 
    
         
            +
                    # TFVAR SECRET
         
     | 
| 
      
 462 
     | 
    
         
            +
                    if !params['tfvarSecret']
         
     | 
| 
      
 463 
     | 
    
         
            +
                      if provision_type && provision_type['code'] == 'terraform'
         
     | 
| 
      
 464 
     | 
    
         
            +
                        v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'tfvarSecret', 'type' => 'select', 'optionSource' => 'tfvarSecrets', 'fieldLabel' => 'Tfvar Secret', 'required' => false}], options[:options], @api_client)
         
     | 
| 
      
 465 
     | 
    
         
            +
                        params['tfvarSecret'] = v_prompt['tfvarSecret'] if v_prompt['tfvarSecret']
         
     | 
| 
      
 466 
     | 
    
         
            +
                      end
         
     | 
| 
      
 467 
     | 
    
         
            +
                    end
         
     | 
| 
       456 
468 
     | 
    
         | 
| 
       457 
469 
     | 
    
         
             
                    payload = {'instanceTypeLayout' => params}
         
     | 
| 
       458 
470 
     | 
    
         | 
| 
         @@ -544,6 +556,9 @@ EOT 
     | 
|
| 
       544 
556 
     | 
    
         
             
                      params['specTemplates'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
         
     | 
| 
       545 
557 
     | 
    
         
             
                    end
         
     | 
| 
       546 
558 
     | 
    
         
             
                  end
         
     | 
| 
      
 559 
     | 
    
         
            +
                  opts.on('--tfvar-secret VALUE', String, "Tfvar Secret name, eg. 'tfvars/dev-key'") do |val|
         
     | 
| 
      
 560 
     | 
    
         
            +
                    params['tfvarSecret'] = val == 'null' ? nil : val
         
     | 
| 
      
 561 
     | 
    
         
            +
                  end
         
     | 
| 
       547 
562 
     | 
    
         
             
                  add_perms_options(opts, options, layout_permission_excludes)
         
     | 
| 
       548 
563 
     | 
    
         
             
                  build_standard_update_options(opts, options)
         
     | 
| 
       549 
564 
     | 
    
         
             
                        opts.footer = <<-EOT
         
     | 
| 
         @@ -156,9 +156,15 @@ class Morpheus::Cli::LibraryOptionListsCommand 
     | 
|
| 
       156 
156 
     | 
    
         
             
                      "Source URL" => 'sourceUrl',
         
     | 
| 
       157 
157 
     | 
    
         
             
                      "Real Time" => lambda {|it| format_boolean it['realTime'] },
         
     | 
| 
       158 
158 
     | 
    
         
             
                      "Ignore SSL Errors" => lambda {|it| format_boolean it['ignoreSSLErrors'] },
         
     | 
| 
       159 
     | 
    
         
            -
                      "Source Method" => lambda {|it| it['sourceMethod'].to_s.upcase }
         
     | 
| 
      
 159 
     | 
    
         
            +
                      "Source Method" => lambda {|it| it['sourceMethod'].to_s.upcase },
         
     | 
| 
      
 160 
     | 
    
         
            +
                      "Credentials" => lambda {|it| it['credential'] ? (it['credential']['type'] == 'local' ? '(Local)' : it['credential']['name']) : nil },
         
     | 
| 
      
 161 
     | 
    
         
            +
                      "Username" => 'serviceUsername',
         
     | 
| 
      
 162 
     | 
    
         
            +
                      "Password" => 'servicePassword',
         
     | 
| 
       160 
163 
     | 
    
         
             
                    }
         
     | 
| 
       161 
164 
     | 
    
         
             
                    option_list_columns.delete("API Type") if option_type_list['type'] != 'api'
         
     | 
| 
      
 165 
     | 
    
         
            +
                    option_list_columns.delete("Credentials") if !['rest','ldap'].include?(option_type_list['type']) # || !(option_type_list['credential'] && option_type_list['credential']['id'])
         
     | 
| 
      
 166 
     | 
    
         
            +
                    option_list_columns.delete("Username") if !['rest','ldap'].include?(option_type_list['type']) || !(option_type_list['serviceUsername'])
         
     | 
| 
      
 167 
     | 
    
         
            +
                    option_list_columns.delete("Password") if !['rest','ldap'].include?(option_type_list['type']) || !(option_type_list['servicePassword'])
         
     | 
| 
       162 
168 
     | 
    
         
             
                    source_headers = []
         
     | 
| 
       163 
169 
     | 
    
         
             
                    if option_type_list['config'] && option_type_list['config']['sourceHeaders']
         
     | 
| 
       164 
170 
     | 
    
         
             
                      source_headers = option_type_list['config']['sourceHeaders'].collect do |header|
         
     | 
| 
         @@ -420,14 +426,18 @@ class Morpheus::Cli::LibraryOptionListsCommand 
     | 
|
| 
       420 
426 
     | 
    
         
             
                    {'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'ignoreSSLErrors', 'fieldLabel' => 'Ignore SSL Errors', 'type' => 'checkbox', 'defaultValue' => false, 'displayOrder' => 6},
         
     | 
| 
       421 
427 
     | 
    
         
             
                    {'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'realTime', 'fieldLabel' => 'Real Time', 'type' => 'checkbox', 'defaultValue' => false, 'displayOrder' => 7},
         
     | 
| 
       422 
428 
     | 
    
         
             
                    {'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'sourceMethod', 'fieldLabel' => 'Source Method', 'type' => 'select', 'selectOptions' => [{'name' => 'GET', 'value' => 'GET'}, {'name' => 'POST', 'value' => 'POST'}], 'defaultValue' => 'GET', 'required' => true, 'displayOrder' => 8},
         
     | 
| 
      
 429 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:rest|ldap', 'fieldName' => 'credential', 'fieldLabel' => 'Credentials', 'type' => 'select', 'optionSource' => 'credentials', 'description' => 'Credential ID or use "local" to specify username and password', 'displayOrder' => 9, 'defaultValue' => "local", 'required' => true, :for_help_only => true}, # hacky way to render this but not prompt for it
         
     | 
| 
      
 430 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'serviceUsername', 'fieldLabel' => 'Username', 'type' => 'text', 'description' => "A Basic Auth Username for use when type is 'rest'.", 'displayOrder' => 9, "credentialFieldContext" => 'credential', "credentialFieldName" => 'username', "credentialType" => "username-password,oauth2"},
         
     | 
| 
      
 431 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'servicePassword', 'fieldLabel' => 'Password', 'type' => 'password', 'description' => "A Basic Auth Password for use when type is 'rest'.", 'displayOrder' => 10, "credentialFieldContext" => 'credential', "credentialFieldName" => 'password', "credentialType" => "username-password,oauth2"},
         
     | 
| 
       423 
432 
     | 
    
         
             
                    # sourceHeaders component (is done afterwards manually)
         
     | 
| 
       424 
     | 
    
         
            -
                    {'dependsOnCode' => 'optionTypeList.type:api', 'fieldName' => 'apiType', 'fieldLabel' => 'Option List', 'type' => 'select', 'optionSource' => 'apiOptionLists', 'required' => true, 'description' => 'The code of the api option list to use, eg. clouds, environments, groups, instances, instance-wiki, networks, servicePlans, resourcePools, securityGroups, servers, server-wiki', 'displayOrder' =>  
     | 
| 
       425 
     | 
    
         
            -
                    {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => ' 
     | 
| 
       426 
     | 
    
         
            -
                    {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => ' 
     | 
| 
       427 
     | 
    
         
            -
                    {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => ' 
     | 
| 
       428 
     | 
    
         
            -
                    {'dependsOnCode' => 'optionTypeList.type: 
     | 
| 
       429 
     | 
    
         
            -
                    {'dependsOnCode' => 'optionTypeList.type:rest|api| 
     | 
| 
       430 
     | 
    
         
            -
                    {'dependsOnCode' => 'optionTypeList.type:rest|api', 'fieldName' => ' 
     | 
| 
      
 433 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:api', 'fieldName' => 'apiType', 'fieldLabel' => 'Option List', 'type' => 'select', 'optionSource' => 'apiOptionLists', 'required' => true, 'description' => 'The code of the api option list to use, eg. clouds, environments, groups, instances, instance-wiki, networks, servicePlans, resourcePools, securityGroups, servers, server-wiki', 'displayOrder' => 10},
         
     | 
| 
      
 434 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:rest|ldap', 'fieldName' => 'credential', 'fieldLabel' => 'Credentials', 'type' => 'select', 'optionSource' => 'credentials', 'description' => 'Credential ID or use "local" to specify username and password', 'displayOrder' => 9, 'defaultValue' => "local", 'required' => true, :for_help_only => true}, # hacky way to render this but not prompt for it
         
     | 
| 
      
 435 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'serviceUsername', 'fieldLabel' => 'Username', 'type' => 'text', 'description' => "An LDAP Username for use when type is 'ldap'.", 'displayOrder' => 11, "credentialFieldContext" => 'credential', "credentialFieldName" => 'username', "credentialType" => "username-password"},
         
     | 
| 
      
 436 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'servicePassword', 'fieldLabel' => 'Password', 'type' => 'password', 'description' => "An LDAP Password for use when type is 'ldap'.", 'displayOrder' => 12, "credentialFieldContext" => 'credential', "credentialFieldName" => 'password', "credentialType" => "username-password"},
         
     | 
| 
      
 437 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'ldapQuery', 'fieldLabel' => 'LDAP Query', 'type' => 'text', 'description' => "LDAP Queries are standard LDAP formatted queries where different objects can be searched. Dependent parameters can be loaded into the query using the <%=phrase%> syntax.", 'displayOrder' => 13},
         
     | 
| 
      
 438 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:rest|api|manual', 'fieldName' => 'initialDataset', 'fieldLabel' => 'Initial Dataset', 'type' => 'code-editor', 'description' => "Create an initial json dataset to be used as the collection for this option list. It should be a list containing objects with properties 'name', and 'value'. However, if there is a translation script, that will also be passed through.", 'displayOrder' => 14, 'dataType' => 'string'},
         
     | 
| 
      
 439 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:rest|api|ldap', 'fieldName' => 'translationScript', 'fieldLabel' => 'Translation Script', 'type' => 'code-editor', 'description' => "Create a js script to translate the result data object into an Array containing objects with properties name, and value. The input data is provided as data and the result should be put on the global variable results.", 'displayOrder' => 15, 'dataType' => 'string'},
         
     | 
| 
      
 440 
     | 
    
         
            +
                    {'dependsOnCode' => 'optionTypeList.type:rest|api', 'fieldName' => 'requestScript', 'fieldLabel' => 'Request Script', 'type' => 'code-editor', 'description' => "Create a js script to prepare the request. Return a data object as the body for a post, and return an array containing properties name and value for a get. The input data is provided as data and the result should be put on the global variable results.", 'displayOrder' => 16, 'dataType' => 'string'},
         
     | 
| 
       431 
441 
     | 
    
         
             
                  ]
         
     | 
| 
       432 
442 
     | 
    
         | 
| 
       433 
443 
     | 
    
         
             
              end
         
     | 
| 
         @@ -238,11 +238,7 @@ class Morpheus::Cli::PricesCommand 
     | 
|
| 
       238 
238 
     | 
    
         
             
                    end
         
     | 
| 
       239 
239 
     | 
    
         
             
                  end
         
     | 
| 
       240 
240 
     | 
    
         
             
                  opts.on("--currency [CURRENCY]", String, "Price currency") do |val|
         
     | 
| 
       241 
     | 
    
         
            -
                     
     | 
| 
       242 
     | 
    
         
            -
                      params['currency'] = val.upcase
         
     | 
| 
       243 
     | 
    
         
            -
                    else
         
     | 
| 
       244 
     | 
    
         
            -
                      raise_command_error "Unsupported currency '#{val}'. Available currencies: #{avail_currencies.join(', ')}"
         
     | 
| 
       245 
     | 
    
         
            -
                    end
         
     | 
| 
      
 241 
     | 
    
         
            +
                    options[:currency] = val
         
     | 
| 
       246 
242 
     | 
    
         
             
                  end
         
     | 
| 
       247 
243 
     | 
    
         
             
                  opts.on("--cost [AMOUNT]", Float, "Price cost") do |val|
         
     | 
| 
       248 
244 
     | 
    
         
             
                    params['cost'] = val
         
     | 
| 
         @@ -269,6 +265,15 @@ class Morpheus::Cli::PricesCommand 
     | 
|
| 
       269 
265 
     | 
    
         
             
                  return 1
         
     | 
| 
       270 
266 
     | 
    
         
             
                end
         
     | 
| 
       271 
267 
     | 
    
         | 
| 
      
 268 
     | 
    
         
            +
                if options[:currency]
         
     | 
| 
      
 269 
     | 
    
         
            +
                  if avail_currencies.include?(options[:currency].upcase)
         
     | 
| 
      
 270 
     | 
    
         
            +
                    params['currency'] = options[:currency].upcase
         
     | 
| 
      
 271 
     | 
    
         
            +
                  else
         
     | 
| 
      
 272 
     | 
    
         
            +
                    raise_command_error "Unsupported currency '#{options[:currency]}'. Available currencies: #{avail_currencies.join(', ')}"
         
     | 
| 
      
 273 
     | 
    
         
            +
                    return 1
         
     | 
| 
      
 274 
     | 
    
         
            +
                  end
         
     | 
| 
      
 275 
     | 
    
         
            +
                end
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
       272 
277 
     | 
    
         
             
                begin
         
     | 
| 
       273 
278 
     | 
    
         
             
                  payload = parse_payload(options)
         
     | 
| 
       274 
279 
     | 
    
         | 
| 
         @@ -402,11 +407,7 @@ class Morpheus::Cli::PricesCommand 
     | 
|
| 
       402 
407 
     | 
    
         
             
                    end
         
     | 
| 
       403 
408 
     | 
    
         
             
                  end
         
     | 
| 
       404 
409 
     | 
    
         
             
                  opts.on("--currency [CURRENCY]", String, "Price currency") do |val|
         
     | 
| 
       405 
     | 
    
         
            -
                     
     | 
| 
       406 
     | 
    
         
            -
                      params['currency'] = val.upcase
         
     | 
| 
       407 
     | 
    
         
            -
                    else
         
     | 
| 
       408 
     | 
    
         
            -
                      raise_command_error "Unsupported currency '#{val}'. Available currencies: #{avail_currencies.join(', ')}"
         
     | 
| 
       409 
     | 
    
         
            -
                    end
         
     | 
| 
      
 410 
     | 
    
         
            +
                    options[:currency] = val
         
     | 
| 
       410 
411 
     | 
    
         
             
                  end
         
     | 
| 
       411 
412 
     | 
    
         
             
                  opts.on("--cost [AMOUNT]", Float, "Price cost") do |val|
         
     | 
| 
       412 
413 
     | 
    
         
             
                    params['cost'] = val
         
     | 
| 
         @@ -431,11 +432,21 @@ class Morpheus::Cli::PricesCommand 
     | 
|
| 
       431 
432 
     | 
    
         
             
                end
         
     | 
| 
       432 
433 
     | 
    
         
             
                optparse.parse!(args)
         
     | 
| 
       433 
434 
     | 
    
         
             
                connect(options)
         
     | 
| 
      
 435 
     | 
    
         
            +
             
     | 
| 
       434 
436 
     | 
    
         
             
                if args.count != 1
         
     | 
| 
       435 
437 
     | 
    
         
             
                  raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
         
     | 
| 
       436 
438 
     | 
    
         
             
                  return 1
         
     | 
| 
       437 
439 
     | 
    
         
             
                end
         
     | 
| 
       438 
440 
     | 
    
         | 
| 
      
 441 
     | 
    
         
            +
                if options[:currency]
         
     | 
| 
      
 442 
     | 
    
         
            +
                  if avail_currencies.include?(options[:currency].upcase)
         
     | 
| 
      
 443 
     | 
    
         
            +
                    params['currency'] = options[:currency].upcase
         
     | 
| 
      
 444 
     | 
    
         
            +
                  else
         
     | 
| 
      
 445 
     | 
    
         
            +
                    raise_command_error "Unsupported currency '#{options[:currency]}'. Available currencies: #{avail_currencies.join(', ')}"
         
     | 
| 
      
 446 
     | 
    
         
            +
                    return 1
         
     | 
| 
      
 447 
     | 
    
         
            +
                  end
         
     | 
| 
      
 448 
     | 
    
         
            +
                end
         
     | 
| 
      
 449 
     | 
    
         
            +
             
     | 
| 
       439 
450 
     | 
    
         
             
                begin
         
     | 
| 
       440 
451 
     | 
    
         
             
                  price = find_price(args[0])
         
     | 
| 
       441 
452 
     | 
    
         | 
| 
         @@ -608,7 +619,10 @@ class Morpheus::Cli::PricesCommand 
     | 
|
| 
       608 
619 
     | 
    
         
             
              end
         
     | 
| 
       609 
620 
     | 
    
         | 
| 
       610 
621 
     | 
    
         
             
              def avail_currencies
         
     | 
| 
       611 
     | 
    
         
            -
                 
     | 
| 
      
 622 
     | 
    
         
            +
                if @avail_currencies.nil?
         
     | 
| 
      
 623 
     | 
    
         
            +
                  @avail_currencies = @prices_interface.list_currencies()['currencies'].collect {|it| it['value']}
         
     | 
| 
      
 624 
     | 
    
         
            +
                end
         
     | 
| 
      
 625 
     | 
    
         
            +
                @avail_currencies
         
     | 
| 
       612 
626 
     | 
    
         
             
              end
         
     | 
| 
       613 
627 
     | 
    
         | 
| 
       614 
628 
     | 
    
         
             
              def prompt_for_price_type(params, options, price={})
         
     | 
| 
         @@ -489,7 +489,7 @@ class Morpheus::Cli::ProvisioningLicensesCommand 
     | 
|
| 
       489 
489 
     | 
    
         
             
                  {'fieldName' => 'licenseVersion', 'fieldLabel' => 'Version', 'type' => 'text', 'displayOrder' => 6},
         
     | 
| 
       490 
490 
     | 
    
         
             
                  {'fieldName' => 'copies', 'fieldLabel' => 'Copies', 'type' => 'number', 'required' => true, 'defaultValue' => 1, 'displayOrder' => 7},
         
     | 
| 
       491 
491 
     | 
    
         
             
                  {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 8},
         
     | 
| 
       492 
     | 
    
         
            -
                  {'fieldName' => 'virtualImages', 'fieldLabel' => 'Virtual Images', 'type' => 'multiSelect', 'optionSource' => lambda { 
         
     | 
| 
      
 492 
     | 
    
         
            +
                  {'fieldName' => 'virtualImages', 'fieldLabel' => 'Virtual Images', 'type' => 'multiSelect', 'optionSource' => lambda { |api_client, api_params| 
         
     | 
| 
       493 
493 
     | 
    
         
             
                    # @options_interface.options_for_source("virtualImages", {})['data']
         
     | 
| 
       494 
494 
     | 
    
         
             
                    get_virtual_images_dropdown()
         
     | 
| 
       495 
495 
     | 
    
         
             
                  }, 'displayOrder' => 9},
         
     | 
| 
         @@ -297,6 +297,9 @@ class Morpheus::Cli::Tasks 
     | 
|
| 
       297 
297 
     | 
    
         
             
                  opts.on('--execute-target VALUE', String, "Execute Target" ) do |val|
         
     | 
| 
       298 
298 
     | 
    
         
             
                    options[:options]['executeTarget'] = val
         
     | 
| 
       299 
299 
     | 
    
         
             
                  end
         
     | 
| 
      
 300 
     | 
    
         
            +
                  opts.on('--credential VALUE', String, "Credential ID or \"local\"" ) do |val|
         
     | 
| 
      
 301 
     | 
    
         
            +
                    options[:options]['credential'] = val
         
     | 
| 
      
 302 
     | 
    
         
            +
                  end
         
     | 
| 
       300 
303 
     | 
    
         
             
                  opts.on('--target-host VALUE', String, "Target Host" ) do |val|
         
     | 
| 
       301 
304 
     | 
    
         
             
                    options[:options]['taskOptions'] ||= {}
         
     | 
| 
       302 
305 
     | 
    
         
             
                    options[:options]['taskOptions']['host'] = val
         
     | 
| 
         @@ -313,6 +316,10 @@ class Morpheus::Cli::Tasks 
     | 
|
| 
       313 
316 
     | 
    
         
             
                    options[:options]['taskOptions'] ||= {}
         
     | 
| 
       314 
317 
     | 
    
         
             
                    options[:options]['taskOptions']['password'] = val
         
     | 
| 
       315 
318 
     | 
    
         
             
                  end
         
     | 
| 
      
 319 
     | 
    
         
            +
                  opts.on('--target-ssh-key VALUE', String, "Target SSH Key" ) do |val|
         
     | 
| 
      
 320 
     | 
    
         
            +
                    options[:options]['taskOptions'] ||= {}
         
     | 
| 
      
 321 
     | 
    
         
            +
                    options[:options]['taskOptions']['sshKey'] = val
         
     | 
| 
      
 322 
     | 
    
         
            +
                  end
         
     | 
| 
       316 
323 
     | 
    
         
             
                  opts.on('--git-repo VALUE', String, "Git Repo ID" ) do |val|
         
     | 
| 
       317 
324 
     | 
    
         
             
                    options[:options]['taskOptions'] ||= {}
         
     | 
| 
       318 
325 
     | 
    
         
             
                    options[:options]['taskOptions']['localScriptGitId'] = val
         
     | 
| 
         @@ -521,17 +528,38 @@ class Morpheus::Cli::Tasks 
     | 
|
| 
       521 
528 
     | 
    
         
             
                        payload['task']['taskOptions'] ||= {}
         
     | 
| 
       522 
529 
     | 
    
         
             
                        payload['task']['taskOptions']['port'] = v_prompt['taskOptions']['port']
         
     | 
| 
       523 
530 
     | 
    
         
             
                      end
         
     | 
| 
       524 
     | 
    
         
            -
                      #  
     | 
| 
       525 
     | 
    
         
            -
                       
     | 
| 
       526 
     | 
    
         
            -
                       
     | 
| 
       527 
     | 
    
         
            -
             
     | 
| 
       528 
     | 
    
         
            -
             
     | 
| 
      
 531 
     | 
    
         
            +
                      # Credentials
         
     | 
| 
      
 532 
     | 
    
         
            +
                      credential_code = "credential"
         
     | 
| 
      
 533 
     | 
    
         
            +
                      credential_option_type = {'code' => credential_code, 'fieldName' => credential_code, 'fieldLabel' => 'Credentials', 'type' => 'select', 'optionSource' => 'credentials', 'description' => 'Enter an existing credential ID or choose "local"', 'defaultValue' => "local", 'required' => true}
         
     | 
| 
      
 534 
     | 
    
         
            +
                      supported_credential_types = ['username-keypair', 'username-password', 'username-password-keypair'].compact.flatten.join(",").split(",").collect {|it| it.strip }
         
     | 
| 
      
 535 
     | 
    
         
            +
                      credential_params = {"new" => false, "credentialTypes" => supported_credential_types}
         
     | 
| 
      
 536 
     | 
    
         
            +
                      credential_value = Morpheus::Cli::OptionTypes.select_prompt(credential_option_type, @api_client, credential_params, options[:no_prompt], options[:options][credential_code])
         
     | 
| 
      
 537 
     | 
    
         
            +
                      if !credential_value.to_s.empty?
         
     | 
| 
      
 538 
     | 
    
         
            +
                        if credential_value == "local"
         
     | 
| 
      
 539 
     | 
    
         
            +
                          payload['task'][credential_code] = {"type" => credential_value}
         
     | 
| 
      
 540 
     | 
    
         
            +
                        elsif credential_value.to_s =~ /\A\d{1,}\Z/
         
     | 
| 
      
 541 
     | 
    
         
            +
                          payload['task'][credential_code] = {"id" => credential_value.to_i}
         
     | 
| 
      
 542 
     | 
    
         
            +
                        end
         
     | 
| 
       529 
543 
     | 
    
         
             
                      end
         
     | 
| 
       530 
     | 
    
         
            -
                       
     | 
| 
       531 
     | 
    
         
            -
             
     | 
| 
       532 
     | 
    
         
            -
             
     | 
| 
       533 
     | 
    
         
            -
                         
     | 
| 
       534 
     | 
    
         
            -
             
     | 
| 
      
 544 
     | 
    
         
            +
                      if credential_value == "local"
         
     | 
| 
      
 545 
     | 
    
         
            +
                        # Username
         
     | 
| 
      
 546 
     | 
    
         
            +
                        v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'taskOptions', 'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'description' => 'Username for remote execution'}], options[:options], @api_client)
         
     | 
| 
      
 547 
     | 
    
         
            +
                        if v_prompt['taskOptions'] && !v_prompt['taskOptions']['username'].to_s.empty?
         
     | 
| 
      
 548 
     | 
    
         
            +
                          payload['task']['taskOptions'] ||= {}
         
     | 
| 
      
 549 
     | 
    
         
            +
                          payload['task']['taskOptions']['username'] = v_prompt['taskOptions']['username']
         
     | 
| 
      
 550 
     | 
    
         
            +
                        end
         
     | 
| 
      
 551 
     | 
    
         
            +
                        # Password
         
     | 
| 
      
 552 
     | 
    
         
            +
                        v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'taskOptions', 'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'description' => 'Password for remote execution'}], options[:options], @api_client)
         
     | 
| 
      
 553 
     | 
    
         
            +
                        if v_prompt['taskOptions'] && !v_prompt['taskOptions']['password'].to_s.empty?
         
     | 
| 
      
 554 
     | 
    
         
            +
                          payload['task']['taskOptions'] ||= {}
         
     | 
| 
      
 555 
     | 
    
         
            +
                          payload['task']['taskOptions']['password'] = v_prompt['taskOptions']['password']
         
     | 
| 
      
 556 
     | 
    
         
            +
                        end
         
     | 
| 
      
 557 
     | 
    
         
            +
                        # SSH Key
         
     | 
| 
      
 558 
     | 
    
         
            +
                        v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'taskOptions', 'fieldName' => 'sshKey', 'fieldLabel' => 'Key', 'type' => 'select', 'optionSource' => 'keyPairs', 'description' => 'SSH Key for remote execution'}], options[:options], @api_client)
         
     | 
| 
      
 559 
     | 
    
         
            +
                        if v_prompt['taskOptions'] && !v_prompt['taskOptions']['sshKey'].to_s.empty?
         
     | 
| 
      
 560 
     | 
    
         
            +
                          payload['task']['taskOptions'] ||= {}
         
     | 
| 
      
 561 
     | 
    
         
            +
                          payload['task']['taskOptions']['sshKey'] = v_prompt['taskOptions']['sshKey']
         
     | 
| 
      
 562 
     | 
    
         
            +
                        end
         
     | 
| 
       535 
563 
     | 
    
         
             
                      end
         
     | 
| 
       536 
564 
     | 
    
         
             
                    end
         
     | 
| 
       537 
565 
     | 
    
         | 
| 
         @@ -639,6 +667,9 @@ class Morpheus::Cli::Tasks 
     | 
|
| 
       639 
667 
     | 
    
         
             
                  opts.on('--execute-target VALUE', String, "Execute Target" ) do |val|
         
     | 
| 
       640 
668 
     | 
    
         
             
                    options[:options]['executeTarget'] = val
         
     | 
| 
       641 
669 
     | 
    
         
             
                  end
         
     | 
| 
      
 670 
     | 
    
         
            +
                  opts.on('--credential VALUE', String, "Credential ID or \"local\"" ) do |val|
         
     | 
| 
      
 671 
     | 
    
         
            +
                    options[:options]['credential'] = val
         
     | 
| 
      
 672 
     | 
    
         
            +
                  end
         
     | 
| 
       642 
673 
     | 
    
         
             
                  opts.on('--target-host VALUE', String, "Target Host" ) do |val|
         
     | 
| 
       643 
674 
     | 
    
         
             
                    options[:options]['taskOptions'] ||= {}
         
     | 
| 
       644 
675 
     | 
    
         
             
                    options[:options]['taskOptions']['host'] = val
         
     | 
| 
         @@ -655,6 +686,10 @@ class Morpheus::Cli::Tasks 
     | 
|
| 
       655 
686 
     | 
    
         
             
                    options[:options]['taskOptions'] ||= {}
         
     | 
| 
       656 
687 
     | 
    
         
             
                    options[:options]['taskOptions']['password'] = val
         
     | 
| 
       657 
688 
     | 
    
         
             
                  end
         
     | 
| 
      
 689 
     | 
    
         
            +
                  opts.on('--target-ssh-key VALUE', String, "Target SSH Key" ) do |val|
         
     | 
| 
      
 690 
     | 
    
         
            +
                    options[:options]['taskOptions'] ||= {}
         
     | 
| 
      
 691 
     | 
    
         
            +
                    options[:options]['taskOptions']['sshKey'] = val
         
     | 
| 
      
 692 
     | 
    
         
            +
                  end
         
     | 
| 
       658 
693 
     | 
    
         
             
                  opts.on('--git-repo VALUE', String, "Git Repo ID" ) do |val|
         
     | 
| 
       659 
694 
     | 
    
         
             
                    options[:options]['taskOptions'] ||= {}
         
     | 
| 
       660 
695 
     | 
    
         
             
                    options[:options]['taskOptions']['localScriptGitId'] = val
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'morpheus/cli/mixins/print_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Mixin for Morpheus::Cli command classes
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Provides common methods for provisioning instances
         
     | 
| 
      
 4 
     | 
    
         
            +
            module Morpheus::Cli::ExecutionRequestHelper
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def self.included(klass)
         
     | 
| 
      
 7 
     | 
    
         
            +
                klass.send :include, Morpheus::Cli::PrintHelper
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def api_client
         
     | 
| 
      
 11 
     | 
    
         
            +
                raise "#{self.class} has not defined @api_client" if @api_client.nil?
         
     | 
| 
      
 12 
     | 
    
         
            +
                @api_client
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def execution_request_interface
         
     | 
| 
      
 16 
     | 
    
         
            +
                # get_interface('execution_request')
         
     | 
| 
      
 17 
     | 
    
         
            +
                api_client.execution_request
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              # refresh execution request until it is finished
         
     | 
| 
      
 21 
     | 
    
         
            +
              # returns json response data of the last execution request when status reached 'completed' or 'failed'
         
     | 
| 
      
 22 
     | 
    
         
            +
              def wait_for_execution_request(execution_request_id, options={}, print_output = true)
         
     | 
| 
      
 23 
     | 
    
         
            +
                refresh_interval = 10
         
     | 
| 
      
 24 
     | 
    
         
            +
                if options[:refresh_interval].to_i > 0
         
     | 
| 
      
 25 
     | 
    
         
            +
                  refresh_interval = options[:refresh_interval]
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
                execution_request = execution_request_interface.get(execution_request_id)['executionRequest']
         
     | 
| 
      
 28 
     | 
    
         
            +
                refresh_display_seconds = refresh_interval % 1.0 == 0 ? refresh_interval.to_i : refresh_interval
         
     | 
| 
      
 29 
     | 
    
         
            +
                # unless options[:quiet]
         
     | 
| 
      
 30 
     | 
    
         
            +
                #   print cyan, "Execution request has not yet finished. Refreshing every #{refresh_display_seconds} seconds...", "\n", reset
         
     | 
| 
      
 31 
     | 
    
         
            +
                # end
         
     | 
| 
      
 32 
     | 
    
         
            +
                while execution_request['status'] == 'pending' || execution_request['status'] == 'new' do
         
     | 
| 
      
 33 
     | 
    
         
            +
                  sleep(refresh_interval)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  execution_request = execution_request_interface.get(execution_request_id)['executionRequest']
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
                if print_output && options[:quiet] != true
         
     | 
| 
      
 37 
     | 
    
         
            +
                  if execution_request['stdErr'].to_s.strip != '' && execution_request['stdErr'] != "stdin: is not a tty\n"
         
     | 
| 
      
 38 
     | 
    
         
            +
                    print_h2 "Error"
         
     | 
| 
      
 39 
     | 
    
         
            +
                    print execution_request['stdErr'].to_s.strip, reset, "\n"
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
                  if execution_request['stdOut'].to_s.strip != ''
         
     | 
| 
      
 42 
     | 
    
         
            +
                    print_h2 "Output"
         
     | 
| 
      
 43 
     | 
    
         
            +
                    print execution_request['stdOut'].to_s.strip, reset, "\n"
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                  print reset, "\n"
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
                return execution_request
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1120,7 +1120,7 @@ module Morpheus::Cli::ProvisioningHelper 
     | 
|
| 
       1120 
1120 
     | 
    
         
             
                  storage_type = nil
         
     | 
| 
       1121 
1121 
     | 
    
         
             
                else
         
     | 
| 
       1122 
1122 
     | 
    
         
             
                  default_storage_type = root_storage_types.find {|t| t['value'].to_s == volume['storageType'].to_s}
         
     | 
| 
       1123 
     | 
    
         
            -
                  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => 'Root Storage Type', 'selectOptions' => root_storage_types, 'required' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.', 'defaultValue' => default_storage_type ? default_storage_type['name'] : volume['storageType']}], options[:options])
         
     | 
| 
      
 1123 
     | 
    
         
            +
                  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => 'Root Storage Type', 'selectOptions' => root_storage_types, 'required' => true, 'defaultFirstOption' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.', 'defaultValue' => default_storage_type ? default_storage_type['name'] : volume['storageType']}], options[:options])
         
     | 
| 
       1124 
1124 
     | 
    
         
             
                  storage_type_id = v_prompt[field_context]['storageType']
         
     | 
| 
       1125 
1125 
     | 
    
         
             
                  storage_type = plan_info['storageTypes'].find {|i| i['id'] == storage_type_id.to_i }
         
     | 
| 
       1126 
1126 
     | 
    
         
             
                  volume['storageType'] = storage_type_id
         
     | 
| 
         @@ -1160,6 +1160,7 @@ module Morpheus::Cli::ProvisioningHelper 
     | 
|
| 
       1160 
1160 
     | 
    
         
             
                  #volume['size'] = plan_size
         
     | 
| 
       1161 
1161 
     | 
    
         
             
                  #volume['sizeId'] = nil #volume.delete('sizeId')
         
     | 
| 
       1162 
1162 
     | 
    
         
             
                end
         
     | 
| 
      
 1163 
     | 
    
         
            +
                
         
     | 
| 
       1163 
1164 
     | 
    
         
             
                if !datastore_options.empty?
         
     | 
| 
       1164 
1165 
     | 
    
         
             
                  default_datastore = datastore_options.find {|ds| ds['value'].to_s == volume['datastoreId'].to_s}
         
     | 
| 
       1165 
1166 
     | 
    
         
             
                  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'datastoreId', 'type' => 'select', 'fieldLabel' => 'Root Datastore', 'selectOptions' => datastore_options, 'required' => true, 'description' => 'Choose a datastore.', 'defaultValue' => default_datastore ? default_datastore['name'] : volume['datastoreId']}], options[:options])
         
     | 
| 
         @@ -1191,7 +1192,7 @@ module Morpheus::Cli::ProvisioningHelper 
     | 
|
| 
       1191 
1192 
     | 
    
         
             
                        volume = options[:options]['volumes'][volume_index]
         
     | 
| 
       1192 
1193 
     | 
    
         
             
                      end
         
     | 
| 
       1193 
1194 
     | 
    
         | 
| 
       1194 
     | 
    
         
            -
                      v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => "Disk #{volume_index} Storage Type", 'selectOptions' => storage_types, 'required' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.', 'defaultValue' => volume['storageType']}], options[:options])
         
     | 
| 
      
 1195 
     | 
    
         
            +
                      v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => "Disk #{volume_index} Storage Type", 'selectOptions' => storage_types, 'required' => true, 'defaultFirstOption' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.', 'defaultValue' => volume['storageType']}], options[:options])
         
     | 
| 
       1195 
1196 
     | 
    
         
             
                      storage_type_id = v_prompt[field_context]['storageType']
         
     | 
| 
       1196 
1197 
     | 
    
         
             
                      volume['storageType'] = storage_type_id
         
     | 
| 
       1197 
1198 
     | 
    
         
             
                      storage_type = plan_info['storageTypes'].find {|i| i['id'] == storage_type_id.to_i }
         
     | 
| 
         @@ -1313,7 +1314,7 @@ module Morpheus::Cli::ProvisioningHelper 
     | 
|
| 
       1313 
1314 
     | 
    
         
             
                    storage_type_id = nil
         
     | 
| 
       1314 
1315 
     | 
    
         
             
                    storage_type = nil
         
     | 
| 
       1315 
1316 
     | 
    
         
             
                  else
         
     | 
| 
       1316 
     | 
    
         
            -
                    #v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => 'Root Storage Type', 'selectOptions' => root_storage_types, 'required' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.'}], options[:options])
         
     | 
| 
      
 1317 
     | 
    
         
            +
                    #v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => 'Root Storage Type', 'selectOptions' => root_storage_types, 'required' => true, 'defaultFirstOption' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.'}], options[:options])
         
     | 
| 
       1317 
1318 
     | 
    
         
             
                    #storage_type_id = v_prompt[field_context]['storageType']
         
     | 
| 
       1318 
1319 
     | 
    
         
             
                    storage_type_id = current_root_volume['type'] || current_root_volume['storageType']
         
     | 
| 
       1319 
1320 
     | 
    
         
             
                    storage_type = plan_info['storageTypes'].find {|i| i['id'] == storage_type_id.to_i }
         
     | 
| 
         @@ -1461,7 +1462,7 @@ module Morpheus::Cli::ProvisioningHelper 
     | 
|
| 
       1461 
1462 
     | 
    
         | 
| 
       1462 
1463 
     | 
    
         
             
                        field_context = "dataVolume#{volume_index}"
         
     | 
| 
       1463 
1464 
     | 
    
         | 
| 
       1464 
     | 
    
         
            -
                        v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => "Disk #{volume_index} Storage Type", 'selectOptions' => storage_types, 'required' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.'}], options[:options])
         
     | 
| 
      
 1465 
     | 
    
         
            +
                        v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => "Disk #{volume_index} Storage Type", 'selectOptions' => storage_types, 'required' => true, 'defaultFirstOption' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.'}], options[:options])
         
     | 
| 
       1465 
1466 
     | 
    
         
             
                        storage_type_id = v_prompt[field_context]['storageType']
         
     | 
| 
       1466 
1467 
     | 
    
         
             
                        storage_type = plan_info['storageTypes'].find {|i| i['id'] == storage_type_id.to_i }
         
     | 
| 
       1467 
1468 
     | 
    
         | 
| 
         @@ -62,10 +62,12 @@ module Morpheus 
     | 
|
| 
       62 
62 
     | 
    
         
             
                        option_type['type'] = 'multiText'
         
     | 
| 
       63 
63 
     | 
    
         
             
                      end
         
     | 
| 
       64 
64 
     | 
    
         
             
                    end
         
     | 
| 
      
 65 
     | 
    
         
            +
                    credential_option_types = {}
         
     | 
| 
       65 
66 
     | 
    
         
             
                    # puts "Options Prompt #{options}"
         
     | 
| 
       66 
67 
     | 
    
         
             
                    # Sort options by default, group, advanced
         
     | 
| 
       67 
68 
     | 
    
         
             
                    cur_field_group = 'default'
         
     | 
| 
       68 
69 
     | 
    
         
             
                    self.sorted_option_types(option_types).each do |option_type|
         
     | 
| 
      
 70 
     | 
    
         
            +
                      next if option_type[:for_help_only] == true # hacky
         
     | 
| 
       69 
71 
     | 
    
         
             
                      context_map = results
         
     | 
| 
       70 
72 
     | 
    
         
             
                      value = nil
         
     | 
| 
       71 
73 
     | 
    
         
             
                      value_found = false
         
     | 
| 
         @@ -145,6 +147,29 @@ module Morpheus 
     | 
|
| 
       145 
147 
     | 
    
         
             
                        next if !found_dep_value
         
     | 
| 
       146 
148 
     | 
    
         
             
                      end
         
     | 
| 
       147 
149 
     | 
    
         | 
| 
      
 150 
     | 
    
         
            +
                      # inject a Credentials prompt for optionTypes that have been replaced by credentials
         
     | 
| 
      
 151 
     | 
    
         
            +
                      credential_code = option_type['credentialFieldContext']
         
     | 
| 
      
 152 
     | 
    
         
            +
                      if !credential_code.to_s.empty?
         
     | 
| 
      
 153 
     | 
    
         
            +
                        if !credential_option_types[credential_code]
         
     | 
| 
      
 154 
     | 
    
         
            +
                          credential_option_type = {'code' => credential_code, 'fieldName' => credential_code, 'fieldLabel' => 'Credentials', 'type' => 'select', 'optionSource' => 'credentials', 'description' => 'Credential ID or use "local" to specify username and password', 'defaultValue' => "local", 'required' => true}
         
     | 
| 
      
 155 
     | 
    
         
            +
                          credential_option_types[credential_code] = credential_option_type
         
     | 
| 
      
 156 
     | 
    
         
            +
                          supported_credential_types = [option_type['credentialType'], option_type['credentialTypes']].compact.flatten.join(",").split(",").collect {|it| it.strip }
         
     | 
| 
      
 157 
     | 
    
         
            +
                          credential_params = {"new" => false, "credentialTypes" => supported_credential_types}
         
     | 
| 
      
 158 
     | 
    
         
            +
                          credential_value = select_prompt(credential_option_type, api_client, credential_params, no_prompt, options[credential_code])
         
     | 
| 
      
 159 
     | 
    
         
            +
                          if !credential_value.to_s.empty?
         
     | 
| 
      
 160 
     | 
    
         
            +
                            if credential_value == "local"
         
     | 
| 
      
 161 
     | 
    
         
            +
                              context_map[credential_code] = {"type" => credential_value}
         
     | 
| 
      
 162 
     | 
    
         
            +
                            elsif credential_value.to_s =~ /\A\d{1,}\Z/
         
     | 
| 
      
 163 
     | 
    
         
            +
                              context_map[credential_code] = {"id" => credential_value.to_i}
         
     | 
| 
      
 164 
     | 
    
         
            +
                            end
         
     | 
| 
      
 165 
     | 
    
         
            +
                          end
         
     | 
| 
      
 166 
     | 
    
         
            +
                        end
         
     | 
| 
      
 167 
     | 
    
         
            +
                        # skip this option unless using local credentials
         
     | 
| 
      
 168 
     | 
    
         
            +
                        if context_map[credential_code].is_a?(Hash) && context_map[credential_code]["type"] != "local"
         
     | 
| 
      
 169 
     | 
    
         
            +
                          next
         
     | 
| 
      
 170 
     | 
    
         
            +
                        end
         
     | 
| 
      
 171 
     | 
    
         
            +
                      end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
       148 
173 
     | 
    
         
             
                      cur_namespace = options
         
     | 
| 
       149 
174 
     | 
    
         
             
                      parent_context_map = context_map
         
     | 
| 
       150 
175 
     | 
    
         
             
                      parent_ns = field_name
         
     | 
| 
         @@ -457,6 +482,12 @@ module Morpheus 
     | 
|
| 
       457 
482 
     | 
    
         
             
                        end
         
     | 
| 
       458 
483 
     | 
    
         
             
                      end
         
     | 
| 
       459 
484 
     | 
    
         
             
                    end
         
     | 
| 
      
 485 
     | 
    
         
            +
                    # default to the first option
         
     | 
| 
      
 486 
     | 
    
         
            +
                    if !value_found && default_value.nil? && option_type['defaultFirstOption'] && select_options && select_options[0]
         
     | 
| 
      
 487 
     | 
    
         
            +
                      # default_value = select_options[0][value_field]
         
     | 
| 
      
 488 
     | 
    
         
            +
                      # nicer to display name instead, it will match and replace with value
         
     | 
| 
      
 489 
     | 
    
         
            +
                      default_value = select_options[0]['name'] ? select_options[0]['name'] : select_options[0][value_field]
         
     | 
| 
      
 490 
     | 
    
         
            +
                    end
         
     | 
| 
       460 
491 
     | 
    
         | 
| 
       461 
492 
     | 
    
         
             
                    if no_prompt
         
     | 
| 
       462 
493 
     | 
    
         
             
                      if !value_found
         
     | 
| 
         @@ -822,7 +853,7 @@ module Morpheus 
     | 
|
| 
       822 
853 
     | 
    
         
             
                  def self.password_prompt(option_type)
         
     | 
| 
       823 
854 
     | 
    
         
             
                    value_found = false
         
     | 
| 
       824 
855 
     | 
    
         
             
                    while !value_found do
         
     | 
| 
       825 
     | 
    
         
            -
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+ 
     | 
| 
      
 856 
     | 
    
         
            +
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+'************'+']' : ''}: "
         
     | 
| 
       826 
857 
     | 
    
         
             
                      input = $stdin.noecho(&:gets).chomp!
         
     | 
| 
       827 
858 
     | 
    
         
             
                      value = input
         
     | 
| 
       828 
859 
     | 
    
         
             
                      print "\n"
         
     | 
    
        data/lib/morpheus/cli/version.rb
    CHANGED
    
    
    
        data/lib/morpheus/formatters.rb
    CHANGED
    
    | 
         @@ -476,3 +476,15 @@ end 
     | 
|
| 
       476 
476 
     | 
    
         
             
            def a_or_an(v)
         
     | 
| 
       477 
477 
     | 
    
         
             
              v.to_s =~ /^[aeiou]/i ? "an" : "a"
         
     | 
| 
       478 
478 
     | 
    
         
             
            end
         
     | 
| 
      
 479 
     | 
    
         
            +
             
     | 
| 
      
 480 
     | 
    
         
            +
            def format_ok_status(status)
         
     | 
| 
      
 481 
     | 
    
         
            +
              color = cyan
         
     | 
| 
      
 482 
     | 
    
         
            +
              if ['ok'].include? status
         
     | 
| 
      
 483 
     | 
    
         
            +
                color = green
         
     | 
| 
      
 484 
     | 
    
         
            +
              elsif ['error'].include? status
         
     | 
| 
      
 485 
     | 
    
         
            +
                color = red
         
     | 
| 
      
 486 
     | 
    
         
            +
              elsif ['warning'].include? status
         
     | 
| 
      
 487 
     | 
    
         
            +
                color = yellow
         
     | 
| 
      
 488 
     | 
    
         
            +
              end
         
     | 
| 
      
 489 
     | 
    
         
            +
              "#{color}#{status.to_s.upcase}#{cyan}"
         
     | 
| 
      
 490 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/morpheus/routes.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: morpheus-cli
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 5. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 5.5.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - David Estes
         
     | 
| 
         @@ -11,7 +11,7 @@ authors: 
     | 
|
| 
       11 
11 
     | 
    
         
             
            autorequire:
         
     | 
| 
       12 
12 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       13 
13 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       14 
     | 
    
         
            -
            date: 2022- 
     | 
| 
      
 14 
     | 
    
         
            +
            date: 2022-05-13 00:00:00.000000000 Z
         
     | 
| 
       15 
15 
     | 
    
         
             
            dependencies:
         
     | 
| 
       16 
16 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       17 
17 
     | 
    
         
             
              name: bundler
         
     | 
| 
         @@ -498,6 +498,7 @@ files: 
     | 
|
| 
       498 
498 
     | 
    
         
             
            - lib/morpheus/cli/mixins/accounts_helper.rb
         
     | 
| 
       499 
499 
     | 
    
         
             
            - lib/morpheus/cli/mixins/backups_helper.rb
         
     | 
| 
       500 
500 
     | 
    
         
             
            - lib/morpheus/cli/mixins/deployments_helper.rb
         
     | 
| 
      
 501 
     | 
    
         
            +
            - lib/morpheus/cli/mixins/execution_request_helper.rb
         
     | 
| 
       501 
502 
     | 
    
         
             
            - lib/morpheus/cli/mixins/infrastructure_helper.rb
         
     | 
| 
       502 
503 
     | 
    
         
             
            - lib/morpheus/cli/mixins/library_helper.rb
         
     | 
| 
       503 
504 
     | 
    
         
             
            - lib/morpheus/cli/mixins/load_balancers_helper.rb
         
     |