morpheus-cli 2.12.5 → 3.1.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 +5 -0
- data/lib/morpheus/api/api_client.rb +15 -30
- data/lib/morpheus/api/app_templates_interface.rb +34 -7
- data/lib/morpheus/api/apps_interface.rb +20 -1
- data/lib/morpheus/api/archive_buckets_interface.rb +124 -0
- data/lib/morpheus/api/archive_files_interface.rb +182 -0
- data/lib/morpheus/api/{network_pools_interface.rb → image_builder_boot_scripts_interface.rb} +6 -6
- data/lib/morpheus/api/{policies_interface.rb → image_builder_image_builds_interface.rb} +20 -15
- data/lib/morpheus/api/image_builder_interface.rb +26 -0
- data/lib/morpheus/api/{network_proxies_interface.rb → image_builder_preseed_scripts_interface.rb} +6 -6
- data/lib/morpheus/cli.rb +10 -9
- data/lib/morpheus/cli/alias_command.rb +10 -9
- data/lib/morpheus/cli/app_templates.rb +1566 -457
- data/lib/morpheus/cli/apps.rb +284 -108
- data/lib/morpheus/cli/archives_command.rb +2184 -0
- data/lib/morpheus/cli/boot_scripts_command.rb +382 -0
- data/lib/morpheus/cli/cli_command.rb +9 -35
- data/lib/morpheus/cli/error_handler.rb +2 -0
- data/lib/morpheus/cli/hosts.rb +15 -3
- data/lib/morpheus/cli/image_builder_command.rb +1208 -0
- data/lib/morpheus/cli/instances.rb +118 -47
- data/lib/morpheus/cli/man_command.rb +27 -24
- data/lib/morpheus/cli/mixins/print_helper.rb +19 -5
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +20 -20
- data/lib/morpheus/cli/option_types.rb +45 -14
- data/lib/morpheus/cli/preseed_scripts_command.rb +381 -0
- data/lib/morpheus/cli/remote.rb +1 -0
- data/lib/morpheus/cli/roles.rb +2 -2
- data/lib/morpheus/cli/shell.rb +3 -2
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/ext/hash.rb +22 -0
- data/lib/morpheus/formatters.rb +33 -0
- data/lib/morpheus/terminal.rb +1 -1
- metadata +13 -21
- data/lib/morpheus/api/cloud_policies_interface.rb +0 -47
- data/lib/morpheus/api/group_policies_interface.rb +0 -47
- data/lib/morpheus/api/network_domains_interface.rb +0 -47
- data/lib/morpheus/api/network_groups_interface.rb +0 -47
- data/lib/morpheus/api/network_pool_servers_interface.rb +0 -47
- data/lib/morpheus/api/network_services_interface.rb +0 -47
- data/lib/morpheus/api/networks_interface.rb +0 -54
- data/lib/morpheus/cli/network_domains_command.rb +0 -571
- data/lib/morpheus/cli/network_groups_command.rb +0 -602
- data/lib/morpheus/cli/network_pool_servers_command.rb +0 -430
- data/lib/morpheus/cli/network_pools_command.rb +0 -495
- data/lib/morpheus/cli/network_proxies_command.rb +0 -594
- data/lib/morpheus/cli/network_services_command.rb +0 -148
- data/lib/morpheus/cli/networks_command.rb +0 -855
- data/lib/morpheus/cli/policies_command.rb +0 -847
- data/scripts/generate_morpheus_commands_help.morpheus +0 -1313
| @@ -218,11 +218,13 @@ module Morpheus::Cli::ProvisioningHelper | |
| 218 218 |  | 
| 219 219 | 
             
                payload = {
         | 
| 220 220 | 
             
                  'zoneId' => cloud_id,
         | 
| 221 | 
            +
                  # 'siteId' => siteId,
         | 
| 221 222 | 
             
                  'instance' => {
         | 
| 222 223 | 
             
                    'name' => instance_name,
         | 
| 223 224 | 
             
                    'site' => {
         | 
| 224 225 | 
             
                      'id' => group_id
         | 
| 225 226 | 
             
                    },
         | 
| 227 | 
            +
                    'type' => instance_type_code,
         | 
| 226 228 | 
             
                    'instanceType' => {
         | 
| 227 229 | 
             
                      'code' => instance_type_code
         | 
| 228 230 | 
             
                    }
         | 
| @@ -263,7 +265,7 @@ module Morpheus::Cli::ProvisioningHelper | |
| 263 265 | 
             
                payload['instance']['layout'] = {'id' => layout['id']}
         | 
| 264 266 |  | 
| 265 267 | 
             
                # prompt for service plan
         | 
| 266 | 
            -
                service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, layoutId: layout_id})
         | 
| 268 | 
            +
                service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, layoutId: layout_id, siteId: group_id})
         | 
| 267 269 | 
             
                service_plans = service_plans_json["plans"]
         | 
| 268 270 | 
             
                service_plans_dropdown = service_plans.collect {|sp| {'name' => sp["name"], 'value' => sp["id"]} } # already sorted
         | 
| 269 271 | 
             
                plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this instance'}],options[:options])
         | 
| @@ -289,29 +291,27 @@ module Morpheus::Cli::ProvisioningHelper | |
| 289 291 | 
             
                  end
         | 
| 290 292 | 
             
                end
         | 
| 291 293 |  | 
| 292 | 
            -
                
         | 
| 294 | 
            +
                # build option types
         | 
| 295 | 
            +
                option_type_list = []
         | 
| 293 296 | 
             
                if !layout['optionTypes'].nil? && !layout['optionTypes'].empty?
         | 
| 294 | 
            -
                   | 
| 295 | 
            -
             | 
| 296 | 
            -
                 | 
| 297 | 
            -
                   | 
| 298 | 
            -
                  payload.deep_merge!(type_payload)
         | 
| 297 | 
            +
                  option_type_list += layout['optionTypes']
         | 
| 298 | 
            +
                end
         | 
| 299 | 
            +
                if !instance_type['optionTypes'].nil? && !instance_type['optionTypes'].empty?
         | 
| 300 | 
            +
                  option_type_list += instance_type['optionTypes']
         | 
| 299 301 | 
             
                end
         | 
| 300 | 
            -
                
         | 
| 301 302 | 
             
                if !layout['provisionType'].nil? && !layout['provisionType']['optionTypes'].nil? && !layout['provisionType']['optionTypes'].empty?
         | 
| 302 | 
            -
                   | 
| 303 | 
            -
             | 
| 304 | 
            -
             | 
| 305 | 
            -
             | 
| 306 | 
            -
                  end
         | 
| 307 | 
            -
                  # remove networkId option if networks were configured above
         | 
| 308 | 
            -
                  if !payload['networkInterfaces'].empty?
         | 
| 309 | 
            -
                    instance_type_option_types = reject_networking_option_types(instance_type_option_types)
         | 
| 310 | 
            -
                  end
         | 
| 311 | 
            -
                  #print "#{dark} #=> gathering instance type option types for layout provision type...#{reset}\n" if Morpheus::Logging.debug?
         | 
| 312 | 
            -
                  provision_payload = Morpheus::Cli::OptionTypes.prompt(instance_type_option_types,options[:options],api_client,{groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
         | 
| 313 | 
            -
                  payload.deep_merge!(provision_payload)
         | 
| 303 | 
            +
                  option_type_list += layout['provisionType']['optionTypes']
         | 
| 304 | 
            +
                end
         | 
| 305 | 
            +
                if !payload['volumes'].empty?
         | 
| 306 | 
            +
                  option_type_list = reject_volume_option_types(option_type_list)
         | 
| 314 307 | 
             
                end
         | 
| 308 | 
            +
                # remove networkId option if networks were configured above
         | 
| 309 | 
            +
                if !payload['networkInterfaces'].empty?
         | 
| 310 | 
            +
                  option_type_list = reject_networking_option_types(option_type_list)
         | 
| 311 | 
            +
                end
         | 
| 312 | 
            +
             | 
| 313 | 
            +
                instance_config_payload = Morpheus::Cli::OptionTypes.prompt(option_type_list, options[:options], @api_client, {groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
         | 
| 314 | 
            +
                payload.deep_merge!(instance_config_payload)
         | 
| 315 315 |  | 
| 316 316 | 
             
                ## Advanced Options
         | 
| 317 317 |  | 
| @@ -194,7 +194,7 @@ module Morpheus | |
| 194 194 | 
             
                    value_found = false
         | 
| 195 195 | 
             
                    value = nil
         | 
| 196 196 | 
             
                    while !value_found do
         | 
| 197 | 
            -
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{ | 
| 197 | 
            +
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
         | 
| 198 198 | 
             
                      input = $stdin.gets.chomp!
         | 
| 199 199 | 
             
                      value = input.empty? ? option_type['defaultValue'] : input
         | 
| 200 200 | 
             
                      value = value.to_s.include?('.') ? value.to_f : value.to_i
         | 
| @@ -233,7 +233,7 @@ module Morpheus | |
| 233 233 | 
             
                      else
         | 
| 234 234 | 
             
                        print Term::ANSIColor.red, "\nInvalid Option #{option_type['fieldLabel']}: [#{use_value}]\n\n", Term::ANSIColor.reset
         | 
| 235 235 | 
             
                        print Term::ANSIColor.red, "  * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - #{option_type['description']}\n", Term::ANSIColor.reset
         | 
| 236 | 
            -
                        display_select_options(select_options)
         | 
| 236 | 
            +
                        display_select_options(opt, select_options)
         | 
| 237 237 | 
             
                        print "\n"
         | 
| 238 238 | 
             
                        exit 1
         | 
| 239 239 | 
             
                      end
         | 
| @@ -247,7 +247,7 @@ module Morpheus | |
| 247 247 | 
             
                        if option_type['required']
         | 
| 248 248 | 
             
                          print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
         | 
| 249 249 | 
             
                          print Term::ANSIColor.red, "  * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - #{option_type['description']}\n", Term::ANSIColor.reset
         | 
| 250 | 
            -
                          display_select_options(select_options)
         | 
| 250 | 
            +
                          display_select_options(option_type, select_options)
         | 
| 251 251 | 
             
                          print "\n"
         | 
| 252 252 | 
             
                          exit 1
         | 
| 253 253 | 
             
                        else
         | 
| @@ -258,8 +258,20 @@ module Morpheus | |
| 258 258 | 
             
                    while !value_found do
         | 
| 259 259 | 
             
                      Readline.completion_append_character = ""
         | 
| 260 260 | 
             
                      Readline.basic_word_break_characters = ''
         | 
| 261 | 
            -
                      Readline.completion_proc = proc {|s|  | 
| 262 | 
            -
             | 
| 261 | 
            +
                      Readline.completion_proc = proc {|s| 
         | 
| 262 | 
            +
                        matches = []
         | 
| 263 | 
            +
                        available_options = (select_options || [])
         | 
| 264 | 
            +
                        available_options.each{|option| 
         | 
| 265 | 
            +
                          if option['name'] && option['name'] =~ /^#{Regexp.escape(s)}/
         | 
| 266 | 
            +
                            matches << option['name']
         | 
| 267 | 
            +
                          # elsif option['id'] && option['id'].to_s =~ /^#{Regexp.escape(s)}/
         | 
| 268 | 
            +
                          elsif option['value'] && option['value'].to_s == s
         | 
| 269 | 
            +
                            matches << option['name']
         | 
| 270 | 
            +
                          end
         | 
| 271 | 
            +
                        }
         | 
| 272 | 
            +
                        matches
         | 
| 273 | 
            +
                      }
         | 
| 274 | 
            +
                      input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
         | 
| 263 275 | 
             
                      input = input.chomp.strip
         | 
| 264 276 | 
             
                      if input.empty?
         | 
| 265 277 | 
             
                        value = option_type['defaultValue']
         | 
| @@ -273,7 +285,7 @@ module Morpheus | |
| 273 285 | 
             
                      end
         | 
| 274 286 | 
             
                      if input == '?'
         | 
| 275 287 | 
             
                        help_prompt(option_type)
         | 
| 276 | 
            -
                        display_select_options(select_options)
         | 
| 288 | 
            +
                        display_select_options(option_type, select_options)
         | 
| 277 289 | 
             
                      elsif !value.nil? || option_type['required'] != true
         | 
| 278 290 | 
             
                        value_found = true
         | 
| 279 291 | 
             
                      end
         | 
| @@ -323,7 +335,7 @@ module Morpheus | |
| 323 335 | 
             
                    value_found = false
         | 
| 324 336 | 
             
                    value = nil
         | 
| 325 337 | 
             
                    while !value_found do
         | 
| 326 | 
            -
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{ | 
| 338 | 
            +
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
         | 
| 327 339 | 
             
                      input = $stdin.gets.chomp!
         | 
| 328 340 | 
             
                      value = input.empty? ? option_type['defaultValue'] : input
         | 
| 329 341 | 
             
                      if input == '?'
         | 
| @@ -340,7 +352,7 @@ module Morpheus | |
| 340 352 | 
             
                    value = nil
         | 
| 341 353 | 
             
                    while !value_found do
         | 
| 342 354 | 
             
                      if value.nil?
         | 
| 343 | 
            -
                        print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{ | 
| 355 | 
            +
                        print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)} [Type 'EOF' to stop input]: \n"
         | 
| 344 356 | 
             
                      end
         | 
| 345 357 | 
             
                      input = $stdin.gets.chomp!
         | 
| 346 358 | 
             
                      # value = input.empty? ? option_type['defaultValue'] : input
         | 
| @@ -361,12 +373,15 @@ module Morpheus | |
| 361 373 | 
             
                  def self.password_prompt(option_type)
         | 
| 362 374 | 
             
                    value_found = false
         | 
| 363 375 | 
             
                    while !value_found do
         | 
| 364 | 
            -
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{ | 
| 376 | 
            +
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
         | 
| 365 377 | 
             
                      input = $stdin.noecho(&:gets).chomp!
         | 
| 366 378 | 
             
                      value = input
         | 
| 367 379 | 
             
                      print "\n"
         | 
| 368 380 | 
             
                      if input == '?'
         | 
| 369 381 | 
             
                        help_prompt(option_type)
         | 
| 382 | 
            +
                      elsif input == "" && option_type['defaultValue'] != nil
         | 
| 383 | 
            +
                        value = option_type['defaultValue'].to_s
         | 
| 384 | 
            +
                        value_found = true
         | 
| 370 385 | 
             
                      elsif !value.empty? || option_type['required'] != true
         | 
| 371 386 | 
             
                        value_found = true
         | 
| 372 387 | 
             
                      end
         | 
| @@ -378,11 +393,11 @@ module Morpheus | |
| 378 393 | 
             
                    value_found = false
         | 
| 379 394 | 
             
                    value = nil
         | 
| 380 395 | 
             
                    while !value_found do
         | 
| 381 | 
            -
                      print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{ | 
| 396 | 
            +
                      #print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
         | 
| 382 397 | 
             
                      Readline.completion_append_character = ""
         | 
| 383 398 | 
             
                      Readline.basic_word_break_characters = ''
         | 
| 384 399 | 
             
                      Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
         | 
| 385 | 
            -
                      input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{ | 
| 400 | 
            +
                      input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
         | 
| 386 401 | 
             
                      input = input.chomp.strip
         | 
| 387 402 | 
             
                      #input = $stdin.gets.chomp!
         | 
| 388 403 | 
             
                      value = input.empty? ? option_type['defaultValue'] : input.to_s
         | 
| @@ -409,7 +424,14 @@ module Morpheus | |
| 409 424 | 
             
                  end
         | 
| 410 425 |  | 
| 411 426 | 
             
                  def self.help_prompt(option_type)
         | 
| 412 | 
            -
                     | 
| 427 | 
            +
                    full_field_name = option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''
         | 
| 428 | 
            +
                    full_field_name << option_type['fieldName'].to_s
         | 
| 429 | 
            +
                    # an attempt at prompting help for natural options without the -O switch
         | 
| 430 | 
            +
                    if option_type[:fmt] == :natural
         | 
| 431 | 
            +
                      print Term::ANSIColor.green,"  * #{option_type['fieldLabel']} [--#{full_field_name}=] ", Term::ANSIColor.reset , "#{option_type['description']}\n"
         | 
| 432 | 
            +
                    else
         | 
| 433 | 
            +
                      print Term::ANSIColor.green,"  * #{option_type['fieldLabel']} [-O #{full_field_name}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
         | 
| 434 | 
            +
                    end
         | 
| 413 435 | 
             
                  end
         | 
| 414 436 |  | 
| 415 437 |  | 
| @@ -417,8 +439,9 @@ module Morpheus | |
| 417 439 | 
             
                    api_client.options.options_for_source(source,params)['data']
         | 
| 418 440 | 
             
                  end
         | 
| 419 441 |  | 
| 420 | 
            -
                  def self.display_select_options(select_options = [])
         | 
| 421 | 
            -
                     | 
| 442 | 
            +
                  def self.display_select_options(opt, select_options = [])
         | 
| 443 | 
            +
                    header = opt['fieldLabel'] ? "#{opt['fieldLabel']} Options" : "Options"
         | 
| 444 | 
            +
                    puts "\n#{header}"
         | 
| 422 445 | 
             
                    puts "==============="
         | 
| 423 446 | 
             
                    select_options.each do |option|
         | 
| 424 447 | 
             
                      puts " * #{option['name']} [#{option['value']}]"
         | 
| @@ -438,6 +461,14 @@ module Morpheus | |
| 438 461 | 
             
                    puts self.format_option_types_help(option_types)
         | 
| 439 462 | 
             
                  end
         | 
| 440 463 |  | 
| 464 | 
            +
                  def self.optional_label(option_type)
         | 
| 465 | 
            +
                    # removing this for now, for the sake of providing less to look at
         | 
| 466 | 
            +
                    if option_type[:fmt] == :natural # || true
         | 
| 467 | 
            +
                      return ""
         | 
| 468 | 
            +
                    else
         | 
| 469 | 
            +
                      return option_type['required'] ? '' : ' (optional)'
         | 
| 470 | 
            +
                    end
         | 
| 471 | 
            +
                  end
         | 
| 441 472 | 
             
                end
         | 
| 442 473 | 
             
              end
         | 
| 443 474 | 
             
            end
         | 
| @@ -0,0 +1,381 @@ | |
| 1 | 
            +
            require 'rest_client'
         | 
| 2 | 
            +
            require 'optparse'
         | 
| 3 | 
            +
            require 'filesize'
         | 
| 4 | 
            +
            require 'table_print'
         | 
| 5 | 
            +
            require 'morpheus/cli/cli_command'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class Morpheus::Cli::PreseedScriptsCommand
         | 
| 8 | 
            +
              include Morpheus::Cli::CliCommand
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              #set_command_name :'preseed-scripts'
         | 
| 11 | 
            +
              # lives under image-builder domain right now
         | 
| 12 | 
            +
              set_command_hidden
         | 
| 13 | 
            +
              def command_name
         | 
| 14 | 
            +
                "image-builder preseed-scripts"
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              register_subcommands :list, :get, :add, :update, :remove
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              # set_default_subcommand :list
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
              def initialize()
         | 
| 22 | 
            +
                # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              def connect(opts)
         | 
| 26 | 
            +
                @api_client = establish_remote_appliance_connection(opts)
         | 
| 27 | 
            +
                @image_builder_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).image_builder
         | 
| 28 | 
            +
                @preseed_scripts_interface = @image_builder_interface.preseed_scripts
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              def handle(args)
         | 
| 32 | 
            +
                handle_subcommand(args)
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              def list(args)
         | 
| 36 | 
            +
                options = {}
         | 
| 37 | 
            +
                optparse = OptionParser.new do|opts|
         | 
| 38 | 
            +
                  opts.banner = subcommand_usage()
         | 
| 39 | 
            +
                  build_common_options(opts, options, [:list, :json, :dry_run])
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
                optparse.parse!(args)
         | 
| 42 | 
            +
                connect(options)
         | 
| 43 | 
            +
                begin
         | 
| 44 | 
            +
                  params = {}
         | 
| 45 | 
            +
                  [:phrase, :offset, :max, :sort, :direction].each do |k|
         | 
| 46 | 
            +
                    params[k] = options[k] unless options[k].nil?
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  if options[:dry_run]
         | 
| 50 | 
            +
                    print_dry_run @preseed_scripts_interface.dry.list(params)
         | 
| 51 | 
            +
                    return
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  json_response = @preseed_scripts_interface.list(params)
         | 
| 55 | 
            +
                  if options[:json]
         | 
| 56 | 
            +
                    print JSON.pretty_generate(json_response)
         | 
| 57 | 
            +
                    print "\n"
         | 
| 58 | 
            +
                    return
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                  preseed_scripts = json_response['preseedScripts']
         | 
| 61 | 
            +
                  title = "Morpheus Preseed Scripts"
         | 
| 62 | 
            +
                  subtitles = []
         | 
| 63 | 
            +
                  if params[:phrase]
         | 
| 64 | 
            +
                    subtitles << "Search: #{params[:phrase]}".strip
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
                  print_h1 title, subtitles
         | 
| 67 | 
            +
                  if preseed_scripts.empty?
         | 
| 68 | 
            +
                    print cyan,"No preseed scripts found.",reset,"\n"
         | 
| 69 | 
            +
                  else
         | 
| 70 | 
            +
                    rows = preseed_scripts.collect {|preseed_script| 
         | 
| 71 | 
            +
                        row = {
         | 
| 72 | 
            +
                          id: preseed_script['id'],
         | 
| 73 | 
            +
                          name: preseed_script['fileName']
         | 
| 74 | 
            +
                        }
         | 
| 75 | 
            +
                        row
         | 
| 76 | 
            +
                      }
         | 
| 77 | 
            +
                      columns = [:id, :name]
         | 
| 78 | 
            +
                      if options[:include_fields]
         | 
| 79 | 
            +
                        columns = options[:include_fields]
         | 
| 80 | 
            +
                      end
         | 
| 81 | 
            +
                      print cyan
         | 
| 82 | 
            +
                      print as_pretty_table(rows, columns, options)
         | 
| 83 | 
            +
                      print reset
         | 
| 84 | 
            +
                      print_results_pagination(json_response)
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
                  print reset,"\n"
         | 
| 87 | 
            +
                rescue RestClient::Exception => e
         | 
| 88 | 
            +
                  print_rest_exception(e, options)
         | 
| 89 | 
            +
                  exit 1
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              def get(args)
         | 
| 94 | 
            +
                options = {}
         | 
| 95 | 
            +
                optparse = OptionParser.new do|opts|
         | 
| 96 | 
            +
                  opts.banner = subcommand_usage("[preseed-script]")
         | 
| 97 | 
            +
                  build_common_options(opts, options, [:json, :dry_run])
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
                optparse.parse!(args)
         | 
| 100 | 
            +
                if args.count < 1
         | 
| 101 | 
            +
                  print_error Morpheus::Terminal.angry_prompt
         | 
| 102 | 
            +
                  puts_error  "#{command_name} missing argument: [preseed-script]\n#{optparse}"
         | 
| 103 | 
            +
                  return 1
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
                connect(options)
         | 
| 106 | 
            +
                begin
         | 
| 107 | 
            +
                  if options[:dry_run]
         | 
| 108 | 
            +
                    if args[0].to_s =~ /\A\d{1,}\Z/
         | 
| 109 | 
            +
                      print_dry_run @preseed_scripts_interface.dry.get(args[0].to_i)
         | 
| 110 | 
            +
                    else
         | 
| 111 | 
            +
                      print_dry_run @preseed_scripts_interface.dry.list({name:args[0]})
         | 
| 112 | 
            +
                    end
         | 
| 113 | 
            +
                    return
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
                  preseed_script = find_preseed_script_by_name_or_id(args[0])
         | 
| 116 | 
            +
                  return 1 if preseed_script.nil?
         | 
| 117 | 
            +
                  json_response = {'preseedScript' => preseed_script}  # skip redundant request
         | 
| 118 | 
            +
                  # json_response = @preseed_scripts_interface.get(preseed_script['id'])
         | 
| 119 | 
            +
                  preseed_script = json_response['preseedScript']
         | 
| 120 | 
            +
                  if options[:json]
         | 
| 121 | 
            +
                    print JSON.pretty_generate(json_response)
         | 
| 122 | 
            +
                    return
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
                  print_h1 "Preseed Script Details"
         | 
| 125 | 
            +
                  print cyan
         | 
| 126 | 
            +
                  description_cols = {
         | 
| 127 | 
            +
                    "ID" => 'id',
         | 
| 128 | 
            +
                    "Name" => 'fileName',
         | 
| 129 | 
            +
                    # "Description" => 'description',
         | 
| 130 | 
            +
                    # "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
         | 
| 131 | 
            +
                    # "Visibility" => lambda {|it| it['visibility'] ? it['visibility'].capitalize() : 'Private' },
         | 
| 132 | 
            +
                  }
         | 
| 133 | 
            +
                  print_description_list(description_cols, preseed_script)
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  print_h2 "Script"
         | 
| 136 | 
            +
                  print cyan
         | 
| 137 | 
            +
                  puts preseed_script['content']
         | 
| 138 | 
            +
                  
         | 
| 139 | 
            +
                  print reset,"\n"
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                rescue RestClient::Exception => e
         | 
| 142 | 
            +
                  print_rest_exception(e, options)
         | 
| 143 | 
            +
                  return 1
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
              def add(args)
         | 
| 148 | 
            +
                options = {}
         | 
| 149 | 
            +
                optparse = OptionParser.new do|opts|
         | 
| 150 | 
            +
                  opts.banner = subcommand_usage("[fileName]")
         | 
| 151 | 
            +
                  build_option_type_options(opts, options, add_preseed_script_option_types(false))
         | 
| 152 | 
            +
                  build_common_options(opts, options, [:options, :json, :dry_run, :quiet])
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
                optparse.parse!(args)
         | 
| 155 | 
            +
                connect(options)
         | 
| 156 | 
            +
                begin
         | 
| 157 | 
            +
                  options[:options] ||= {}
         | 
| 158 | 
            +
                  # support [preseed-script] as first argument still
         | 
| 159 | 
            +
                  if args[0]
         | 
| 160 | 
            +
                    options[:options]['fileName'] = args[0]
         | 
| 161 | 
            +
                  end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  payload = {
         | 
| 164 | 
            +
                    'preseedScript' => {}
         | 
| 165 | 
            +
                  }
         | 
| 166 | 
            +
                  # prompt for Script Content unless --file is passed.
         | 
| 167 | 
            +
                  my_options = add_preseed_script_option_types()
         | 
| 168 | 
            +
                  if options[:options]['file']
         | 
| 169 | 
            +
                    my_options = my_options.reject {|it| it['fieldName'] == 'content' }
         | 
| 170 | 
            +
                  # elsif options[:options]['content']
         | 
| 171 | 
            +
                  #   my_options = my_options.reject {|it| it['fieldName'] == 'file' }
         | 
| 172 | 
            +
                  else
         | 
| 173 | 
            +
                    my_options = my_options.reject {|it| it['fieldName'] == 'file' }
         | 
| 174 | 
            +
                  end
         | 
| 175 | 
            +
                  params = Morpheus::Cli::OptionTypes.prompt(my_options, options[:options], @api_client, options[:params])
         | 
| 176 | 
            +
                  script_file = params.delete('file')
         | 
| 177 | 
            +
                  if script_file
         | 
| 178 | 
            +
                    if !File.exists?(script_file)
         | 
| 179 | 
            +
                      print_red_alert "File not found: #{script_file}"
         | 
| 180 | 
            +
                      return 1
         | 
| 181 | 
            +
                    end
         | 
| 182 | 
            +
                    payload['preseedScript']['content'] = File.read(script_file)
         | 
| 183 | 
            +
                  end
         | 
| 184 | 
            +
                  payload['preseedScript'].merge!(params)
         | 
| 185 | 
            +
                  if options[:dry_run]
         | 
| 186 | 
            +
                    print_dry_run @preseed_scripts_interface.dry.create(payload)
         | 
| 187 | 
            +
                    return
         | 
| 188 | 
            +
                  end
         | 
| 189 | 
            +
                  json_response = @preseed_scripts_interface.create(payload)
         | 
| 190 | 
            +
                  if options[:json]
         | 
| 191 | 
            +
                    print JSON.pretty_generate(json_response)
         | 
| 192 | 
            +
                    print "\n"
         | 
| 193 | 
            +
                  elsif !options[:quiet]
         | 
| 194 | 
            +
                    print_green_success "Added image build #{payload['preseedScript']['fileName']}"
         | 
| 195 | 
            +
                    # list([])
         | 
| 196 | 
            +
                    preseed_script = json_response['preseedScript']
         | 
| 197 | 
            +
                    get([preseed_script['id']])
         | 
| 198 | 
            +
                  end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                rescue RestClient::Exception => e
         | 
| 201 | 
            +
                  print_rest_exception(e, options)
         | 
| 202 | 
            +
                  exit 1
         | 
| 203 | 
            +
                end
         | 
| 204 | 
            +
              end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
              def update(args)
         | 
| 207 | 
            +
                options = {}
         | 
| 208 | 
            +
                optparse = OptionParser.new do|opts|
         | 
| 209 | 
            +
                  opts.banner = subcommand_usage("[preseed-script] [options]")
         | 
| 210 | 
            +
                  build_option_type_options(opts, options, update_preseed_script_option_types(false))
         | 
| 211 | 
            +
                  build_common_options(opts, options, [:options, :json, :dry_run])
         | 
| 212 | 
            +
                end
         | 
| 213 | 
            +
                optparse.parse!(args)
         | 
| 214 | 
            +
                if args.count < 1
         | 
| 215 | 
            +
                  puts optparse
         | 
| 216 | 
            +
                  return 1
         | 
| 217 | 
            +
                end
         | 
| 218 | 
            +
                connect(options)
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                begin
         | 
| 221 | 
            +
                  preseed_script = find_preseed_script_by_name_or_id(args[0])
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                  payload = {
         | 
| 224 | 
            +
                    'preseedScript' => {id: preseed_script["id"]}
         | 
| 225 | 
            +
                  }
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                  params = options[:options] || {}
         | 
| 228 | 
            +
                  #puts "parsed params is : #{params.inspect}"
         | 
| 229 | 
            +
                  params = params.select {|k,v| params[k].to_s != "" }
         | 
| 230 | 
            +
                  if params.empty?
         | 
| 231 | 
            +
                    print_red_alert "Specify atleast one option to update"
         | 
| 232 | 
            +
                    puts optparse
         | 
| 233 | 
            +
                    return 1
         | 
| 234 | 
            +
                  end
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                  # prompt for Script Content unless --file is passed.
         | 
| 237 | 
            +
                  # my_options = add_preseed_script_option_types()
         | 
| 238 | 
            +
                  # if options[:options]['file']
         | 
| 239 | 
            +
                  #   my_options = my_options.reject {|it| it['fieldName'] == 'content' }
         | 
| 240 | 
            +
                  # # elsif options[:options]['content']
         | 
| 241 | 
            +
                  # #   my_options = my_options.reject {|it| it['fieldName'] == 'file' }
         | 
| 242 | 
            +
                  # else
         | 
| 243 | 
            +
                  #   my_options = my_options.reject {|it| it['fieldName'] == 'file' }
         | 
| 244 | 
            +
                  # end
         | 
| 245 | 
            +
                  # params = Morpheus::Cli::OptionTypes.prompt(my_options, options[:options], @api_client, options[:params])
         | 
| 246 | 
            +
                  script_file = params.delete('file')
         | 
| 247 | 
            +
                  if script_file
         | 
| 248 | 
            +
                    if !File.exists?(script_file)
         | 
| 249 | 
            +
                      print_red_alert "File not found: #{script_file}"
         | 
| 250 | 
            +
                      return 1
         | 
| 251 | 
            +
                    end
         | 
| 252 | 
            +
                    payload['preseedScript']['content'] = File.read(script_file)
         | 
| 253 | 
            +
                  end
         | 
| 254 | 
            +
                  payload['preseedScript'].merge!(params)
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                  if options[:dry_run]
         | 
| 257 | 
            +
                    print_dry_run @preseed_scripts_interface.dry.update(preseed_script["id"], payload)
         | 
| 258 | 
            +
                    return
         | 
| 259 | 
            +
                  end
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                  json_response = @preseed_scripts_interface.update(preseed_script["id"], payload)
         | 
| 262 | 
            +
                  if options[:json]
         | 
| 263 | 
            +
                    print JSON.pretty_generate(json_response)
         | 
| 264 | 
            +
                    print "\n"
         | 
| 265 | 
            +
                  else
         | 
| 266 | 
            +
                    print_green_success "Updated preseed script #{preseed_script['fileName']}"
         | 
| 267 | 
            +
                    get([preseed_script['id']])
         | 
| 268 | 
            +
                  end
         | 
| 269 | 
            +
                  return 0
         | 
| 270 | 
            +
                rescue RestClient::Exception => e
         | 
| 271 | 
            +
                  print_rest_exception(e, options)
         | 
| 272 | 
            +
                  return 1
         | 
| 273 | 
            +
                end
         | 
| 274 | 
            +
              end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
              def remove(args)
         | 
| 277 | 
            +
                options = {}
         | 
| 278 | 
            +
                optparse = OptionParser.new do|opts|
         | 
| 279 | 
            +
                  opts.banner = subcommand_usage("[preseed-script]")
         | 
| 280 | 
            +
                  build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run])
         | 
| 281 | 
            +
                end
         | 
| 282 | 
            +
                optparse.parse!(args)
         | 
| 283 | 
            +
             | 
| 284 | 
            +
                if args.count < 1
         | 
| 285 | 
            +
                  print_error Morpheus::Terminal.angry_prompt
         | 
| 286 | 
            +
                  puts_error  "#{command_name} missing argument: [preseed-script]\n#{optparse}"
         | 
| 287 | 
            +
                  return 1
         | 
| 288 | 
            +
                end
         | 
| 289 | 
            +
             | 
| 290 | 
            +
                connect(options)
         | 
| 291 | 
            +
                begin
         | 
| 292 | 
            +
                  preseed_script = find_preseed_script_by_name_or_id(args[0])
         | 
| 293 | 
            +
                  return 1 if preseed_script.nil?
         | 
| 294 | 
            +
             | 
| 295 | 
            +
                  unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the preseed script: #{preseed_script['fileName']}?")
         | 
| 296 | 
            +
                    return 9, "aborted command"
         | 
| 297 | 
            +
                  end
         | 
| 298 | 
            +
                  if options[:dry_run]
         | 
| 299 | 
            +
                    print_dry_run @preseed_scripts_interface.dry.destroy(preseed_script['id'])
         | 
| 300 | 
            +
                    return 0
         | 
| 301 | 
            +
                  end
         | 
| 302 | 
            +
                  json_response = @preseed_scripts_interface.destroy(preseed_script['id'])
         | 
| 303 | 
            +
                  if options[:json]
         | 
| 304 | 
            +
                    print JSON.pretty_generate(json_response)
         | 
| 305 | 
            +
                    print "\n"
         | 
| 306 | 
            +
                  else
         | 
| 307 | 
            +
                    print_green_success "Removed preseed script #{preseed_script['fileName']}"
         | 
| 308 | 
            +
                    # list([])
         | 
| 309 | 
            +
                  end
         | 
| 310 | 
            +
                  return 0
         | 
| 311 | 
            +
                rescue RestClient::Exception => e
         | 
| 312 | 
            +
                  print_rest_exception(e, options)
         | 
| 313 | 
            +
                  return 1
         | 
| 314 | 
            +
                end
         | 
| 315 | 
            +
              end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
              private
         | 
| 318 | 
            +
             | 
| 319 | 
            +
              def get_available_preseed_script_types()
         | 
| 320 | 
            +
                [{'name' => 'VMware', 'value' => 'vmware'}]
         | 
| 321 | 
            +
              end
         | 
| 322 | 
            +
             | 
| 323 | 
            +
              def add_preseed_script_option_types(connected=true)
         | 
| 324 | 
            +
                [
         | 
| 325 | 
            +
                  {'fieldName' => 'fileName', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for this script.'},
         | 
| 326 | 
            +
                  # {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false},
         | 
| 327 | 
            +
                  {'fieldName' => 'file', 'fieldLabel' => 'Script File', 'type' => 'file', 'required' => false, 'description' => 'Set script contents to that of a local file.'},
         | 
| 328 | 
            +
                  {'fieldName' => 'content', 'fieldLabel' => 'Script', 'type' => 'code-editor', 'required' => true},
         | 
| 329 | 
            +
                ]
         | 
| 330 | 
            +
              end
         | 
| 331 | 
            +
             | 
| 332 | 
            +
              def update_preseed_script_option_types(connected=true)
         | 
| 333 | 
            +
                list = add_preseed_script_option_types(connected)
         | 
| 334 | 
            +
                # list = list.reject {|it| ["group"].include? it['fieldName'] }
         | 
| 335 | 
            +
                list.each {|it| it['required'] = false }
         | 
| 336 | 
            +
                list
         | 
| 337 | 
            +
              end
         | 
| 338 | 
            +
             | 
| 339 | 
            +
             def find_preseed_script_by_name_or_id(val)
         | 
| 340 | 
            +
                if val.to_s =~ /\A\d{1,}\Z/
         | 
| 341 | 
            +
                  return find_preseed_script_by_id(val)
         | 
| 342 | 
            +
                else
         | 
| 343 | 
            +
                  return find_preseed_script_by_name(val)
         | 
| 344 | 
            +
                end
         | 
| 345 | 
            +
              end
         | 
| 346 | 
            +
             | 
| 347 | 
            +
              def find_preseed_script_by_id(id)
         | 
| 348 | 
            +
                begin
         | 
| 349 | 
            +
                  json_response = @preseed_scripts_interface.get(id.to_i)
         | 
| 350 | 
            +
                  return json_response['preseedScript']
         | 
| 351 | 
            +
                rescue RestClient::Exception => e
         | 
| 352 | 
            +
                  if e.response && e.response.code == 404
         | 
| 353 | 
            +
                    print_red_alert "Preseed Script not found by id #{id}"
         | 
| 354 | 
            +
                    return nil
         | 
| 355 | 
            +
                  else
         | 
| 356 | 
            +
                    raise e
         | 
| 357 | 
            +
                  end
         | 
| 358 | 
            +
                end
         | 
| 359 | 
            +
              end
         | 
| 360 | 
            +
             | 
| 361 | 
            +
              def find_preseed_script_by_name(name)
         | 
| 362 | 
            +
                preseed_scripts = @preseed_scripts_interface.list({name: name.to_s})['preseedScripts']
         | 
| 363 | 
            +
                if preseed_scripts.empty?
         | 
| 364 | 
            +
                  print_red_alert "Preseed Script not found by name #{name}"
         | 
| 365 | 
            +
                  return nil
         | 
| 366 | 
            +
                elsif preseed_scripts.size > 1
         | 
| 367 | 
            +
                  print_red_alert "#{preseed_scripts.size} preseed scripts found by name #{name}"
         | 
| 368 | 
            +
                  # print_preseed_scripts_table(preseed_scripts, {color: red})
         | 
| 369 | 
            +
                  rows = preseed_scripts.collect do |preseed_script|
         | 
| 370 | 
            +
                    {id: it['id'], name: it['fileName']}
         | 
| 371 | 
            +
                  end
         | 
| 372 | 
            +
                  print red
         | 
| 373 | 
            +
                  tp rows, [:id, :name]
         | 
| 374 | 
            +
                  print reset,"\n"
         | 
| 375 | 
            +
                  return nil
         | 
| 376 | 
            +
                else
         | 
| 377 | 
            +
                  return preseed_scripts[0]
         | 
| 378 | 
            +
                end
         | 
| 379 | 
            +
              end
         | 
| 380 | 
            +
             | 
| 381 | 
            +
            end
         |