From: Martyn Taylor <mtaylor(a)redhat.com>
---
lib/aeolus_cli/command/config_parser.rb | 338 ++++++++++++++++--------------
spec/command/config_parser_spec.rb | 32 ++--
2 files changed, 193 insertions(+), 177 deletions(-)
diff --git a/lib/aeolus_cli/command/config_parser.rb b/lib/aeolus_cli/command/config_parser.rb
index 6f66fba..ff1172d 100644
--- a/lib/aeolus_cli/command/config_parser.rb
+++ b/lib/aeolus_cli/command/config_parser.rb
@@ -19,6 +19,7 @@ module Aeolus
module CLI
class ConfigParser
COMMANDS = %w(list build push import delete status)
+
attr_accessor :options, :command, :args
def initialize(argv)
@@ -34,124 +35,152 @@ module Aeolus
# Eventually get the config file from user dir if it exists.
# File.expand_path("~")
if COMMANDS.include?(@command)
- parse(@command)
- self.send((a)command.to_sym) unless @args.include?('-h')
+ opts = self.send((@command + "Options").to_sym)
+ if @args.include?('-h')
+ puts opts
+ else
+ parse(opts)
+ self.send((a)command.to_sym)
+ end
else
- @args << "-h"
- puts "Valid command required: \n\n"
- parse
+ puts generalOptions
+ exit(1)
end
end
- private
- def parse(subcommand = nil)
- subcommand = subcommand.to_sym if subcommand
+ def parse(opts)
+ begin
+ opts.parse(@args)
+ rescue OptionParser::InvalidOption => io
+ puts "Warning, " + io.message + "\n\tSee `aeolus-image " + @command + " -h` for usage information."
+ exit(1)
+ rescue OptionParser::MissingArgument => e
+ puts "Warning, #{e.message}" + "\n\tSee `aeolus-image " + @command + " -h` for usage information."
+ exit(1)
+ end
+ end
- @optparse ||= OptionParser.new do|opts|
- opts.banner = "Usage: aeolus-image [#{COMMANDS.join('|')}] [general options] [command options]"
+ def generalOptions
+ subtext = "Aeolus Image Commands:"
+ subtext += "\n list : Lists Aeolus Image Resources"
+ subtext += "\n build : Builds a new Image"
+ subtext += "\n push : Pushes an Image to a particular Provider Account"
+ subtext += "\n import : Imports an existing image"
+ subtext += "\n delete : Delete an Aeolus Image Resource"
+ subtext += "\n status : Check the status of a push or build"
+ subtext += "\nSee `aeolus-image <command> -h` for more information on each command"
- opts.separator ""
- opts.separator "General options:"
- opts.on('-d', '--id ID', 'id for a given object') do |id|
+ general = OptionParser.new do |opts|
+ opts.banner = "Usage: aeolus-image [#{COMMANDS.join('|')}] [command options]"
+ opts.on( '-h', '--help', 'Get usage information for this tool') do
+ puts opts
+ exit(0)
+ end
+ opts.separator(subtext)
+ end
+ general
+ end
+
+ def listOptions
+ OptionParser.new do |opts|
+ opts.banner = "Usage: aeolus-image list [command options]"
+ opts.on('-i', '--images', 'Retrieve a list of images') do
+ @options[:subcommand] = :images
+ end
+ opts.on('-b', '--builds ID', 'Retrieve the builds of an image') do |id|
+ @options[:subcommand] = :builds
@options[:id] = id
end
- opts.on('-r', '--description NAME', 'description (e.g. "<image><name>MyImage</name></image>" or "/home/user/myImage.xml")') do |description|
- @options[:description] = description
+ opts.on('-t', '--targetimages ID', 'Retrieve the target images from a build') do |id|
+ @options[:subcommand] = :targetimages
+ @options[:id] = id
end
- opts.on('-r', '--provider NAME1,NAME2', Array,'name of specific provider (ie ec2-us-east1)') do |name|
- @options[:provider] = name
+ opts.on('-P', '--providerimages ID', 'Retrieve the provider images from a target image') do |id|
+ @options[:subcommand] = :providerimages
+ @options[:id] = id
end
- opts.on('-a', '--provider_account NAME1,NAME2', Array,'name of specific provider account (ie my-ec2') do |name|
- @options[:provider_account] = name
+ opts.on('-g', '--targets', 'Retrieve the values available for the --target parameter') do
+ @options[:subcommand] = :targets
end
- opts.on('-I', '--image ID', 'ID of the base image, can be used in build and push commands, see examples') do |id|
- @options[:image] = id
+ opts.on('-p', '--providers', 'Retrieve the values available for the --provider parameter') do
+ @options[:subcommand] = :providers
+ end
+ opts.on('-a', '--accounts', 'Retrieve the values available for the --account parameter') do
+ @options[:subcommand] = :accounts
+ end
+ opts.on( '-h', '--help', 'Get usage information for this command')
+
+ opts.separator ""
+ opts.separator "Examples:"
+ opts.separator "aeolus-image list --images # list available images"
+ opts.separator "aeolus-image list --builds $image_id # list the builds of an image"
+ opts.separator "aeolus-image list --targetimages $build_id # list the target images from a build"
+ opts.separator "aeolus-image list --providerimages $target_id # list the provider images from a target image"
+ opts.separator "aeolus-image list --targets # list the values available for the --target parameter"
+ opts.separator "aeolus-image list --providers # list the values available for the --provider parameter"
+ opts.separator "aeolus-image list --accounts # list the values available for the --account parameter"
+ end
+ end
+
+ def buildOptions
+ OptionParser.new do |opts|
+ opts.banner = "Usage: aeolus-image build [command options]"
+ opts.separator ""
+ opts.separator "Options:"
+ opts.on('-e', '--template FILE', 'path to file that contains template xml') do |file|
+ @options[:template] = file
+ end
+ opts.on('-z', '--no-validation', 'Do not validation the template against the TDL XML Schema') do |description|
+ @options[:validation] = false
end
opts.on('-T', '--target TARGET1,TARGET2', Array, 'provider type (ec2, rackspace, rhevm, etc)') do |name|
@options[:target] = name
end
- opts.on( '-h', '--help', 'Get usage information for this tool') do
- puts opts
- exit(0)
- end
+ opts.on( '-h', '--help', 'Get usage information for this command')
- if !subcommand || subcommand == :list
- opts.separator ""
- opts.separator "List options:"
- opts.on('-i', '--images', 'Retrieve a list of images') do
- @options[:subcommand] = :images
- end
- opts.on('-b', '--builds ID', 'Retrieve the builds of an image') do |id|
- @options[:subcommand] = :builds
- @options[:id] = id
- end
- opts.on('-t', '--targetimages ID', 'Retrieve the target images from a build') do |id|
- @options[:subcommand] = :targetimages
- @options[:id] = id
- end
- opts.on('-P', '--providerimages ID', 'Retrieve the provider images from a target image') do |id|
- @options[:subcommand] = :providerimages
- @options[:id] = id
- end
- opts.on('-g', '--targets', 'Retrieve the values available for the --target parameter') do
- @options[:subcommand] = :targets
- end
- opts.on('-p', '--providers', 'Retrieve the values available for the --provider parameter') do
- @options[:subcommand] = :providers
- end
- opts.on('-a', '--accounts', 'Retrieve the values available for the --account parameter') do
- @options[:subcommand] = :accounts
- end
- end
+ opts.separator ""
+ opts.separator "Examples:"
+ opts.separator "aeolus-image build --target ec2 --template my.tmpl # build a new image for ec2 from based on the given template"
+ opts.separator "aeolus-image build --target ec2,rhevm --template my.tmpl # build a new image for ec2 and for rhevm based on the given template"
+ #opts.separator "aeolus-image build --image $image_id # (NOT IMPLEMENTED) rebuild the image template and targets from latest build"
+ #opts.separator %q{aeolus-image build --target ec2,rackspace \ # rebuild the image with a new template and set of targets
+ # --image $image_i \
+ # --template my.tmpl}
+ end
+ end
- if !subcommand || subcommand == :build
- opts.separator ""
- opts.separator "Build options:"
- opts.on('-e', '--template FILE', 'path to file that contains template xml') do |file|
- @options[:template] = file
- end
- opts.on('-z', '--no-validation', 'Do not validation the template against the TDL XML Schema') do |description|
- @options[:validation] = false
- end
+ def pushOptions
+ OptionParser.new do |opts|
+ opts.banner = "Usage: aeolus-image push [command options]"
+ opts.separator ""
+ opts.separator "Options:"
+ opts.on('-I', '--image ID', 'ID of the base image, can be used in build and push commands, see examples') do |id|
+ @options[:image] = id
end
-
- if !subcommand || subcommand == :push
- opts.separator ""
- opts.separator "Push options:"
- opts.on('-B', '--build ID', 'push all target images for a build, to same providers as previously') do |id|
- @options[:build] = id
- end
- opts.on('-t', '--targetimages ID', 'Retrieve the target images from a build') do |id|
- @options[:targetimage] = id
- end
- opts.on('-A', '--account NAME', 'name of specific provider account to use for push') do |name|
- @options[:account] = name
- end
+ opts.on('-B', '--build ID', 'push all target images for a build, to same providers as previously') do |id|
+ @options[:build] = id
end
-
- if !subcommand || subcommand == :delete
- opts.separator ""
- opts.separator "Delete options:"
- opts.on('-I', '--image ID', 'delete build image and associated objects') do |id|
- @options[:subcommand] = :image
- @options[:image] = id
- end
- opts.on('-B', '--build ID', 'delete build and associated objects') do |id|
- @options[:subcommand] = :build
- @options[:build] = id
- end
- opts.on('-m', '--targetimage ID', 'delete target image and its provider images') do |id|
- @options[:subcommand] = :target_image
- @options[:targetimage] = id
- end
- opts.on('-D', '--providerimage ID', 'delete provider image') do |id|
- @options[:subcommand] = :provider_image
- @options[:providerimage] = id
- end
+ opts.on('-t', '--targetimages ID', 'Retrieve the target images from a build') do |id|
+ @options[:targetimage] = id
end
+ opts.on('-A', '--account NAME,NAME', Array, 'name of specific provider account to use for push') do |name|
+ @options[:account] = name
+ end
+ opts.on( '-h', '--help', 'Get usage information for this command')
+
+ opts.separator ""
+ opts.separator "Examples:"
+ opts.separator "aeolus-image push --account ec2-account,ec2-account2 --targetimage $target_image_id # Push target images to each of the specified account"
+ opts.separator "aeolus-image push --account ec2-account,rhevm-account --build $build_id # Push target images attached to a particular build to each of the specified accounts"
+ opts.separator "aeolus-image push --account ec2-account,rhevm-account --image $image_id # Push target images attached to a particular image to each of the specified accounts"
+ end
+ end
+ def statusOptions
+ OptionParser.new do |opts|
+ opts.banner = "Usage: aeolus-image status [command options]"
opts.separator ""
- opts.separator "Status options:"
+ opts.separator "Options:"
opts.on('-t', '--targetimage ID', 'target image status') do |id|
@options[:subcommand] = :target_image
@options[:targetimage] = id
@@ -160,79 +189,71 @@ module Aeolus
@options[:subcommand] = :provider_image
@options[:providerimage] = id
end
+ opts.on( '-h', '--help', 'Get usage information for this command')
- opts.separator ""
- opts.separator "URL with credentials to Conductor are set in ~/.aeolus-cli"
- opts.separator "Conductor URL should point to https://<host_where_conductor_runs>/conductor/api"
+ opts.separator "Examples:"
+ opts.separator "aeolus-image status --targetimage $target_image # status of target image build"
+ opts.separator "aeolus-image status --providerimage $provider_image # status of provider image push"
+ end
+ end
- if !subcommand || subcommand == :list
- opts.separator ""
- opts.separator "List Examples:"
- opts.separator "aeolus-image list --images # list available images"
- opts.separator "aeolus-image list --builds $image_id # list the builds of an image"
- opts.separator "aeolus-image list --targetimages $build_id # list the target images from a build"
- opts.separator "aeolus-image list --providerimages $target_id # list the provider images from a target image"
- opts.separator "aeolus-image list --targets # list the values available for the --target parameter"
- opts.separator "aeolus-image list --providers # list the values available for the --provider parameter"
- opts.separator "aeolus-image list --accounts # list the values available for the --account parameter"
+ def importOptions
+ OptionParser.new do |opts|
+ opts.banner = "Usage: aeolus-image import [command options]"
+ opts.separator ""
+ opts.separator "Options:"
+ opts.on('-d', '--id ID', 'id for a given object') do |id|
+ @options[:id] = id
end
-
- if !subcommand || subcommand == :build
- opts.separator ""
- opts.separator "Build examples:"
- opts.separator "aeolus-image build --target ec2 --template my.tmpl # build a new image for ec2 from based on the given template"
- opts.separator "aeolus-image build --target ec2,rhevm --template my.tmpl # build a new image for ec2 and for rhevm based on the given template"
- #opts.separator "aeolus-image build --image $image_id # (NOT IMPLEMENTED) rebuild the image template and targets from latest build"
- #opts.separator %q{aeolus-image build --target ec2,rackspace \ # rebuild the image with a new template and set of targets
- # --image $image_i \
- # --template my.tmpl}
+ opts.on('-r', '--description NAME', 'description (e.g. "<image><name>MyImage</name></image>" or "/home/user/myImage.xml")') do |description|
+ @options[:description] = description
end
-
- if !subcommand || subcommand == :push
- opts.separator ""
- opts.separator "Push examples:"
- opts.separator "aeolus-image push --account ec2-account,ec2-account2 --targetimage $target_image_id # Push target images to each of the specified account"
- opts.separator "aeolus-image push --account ec2-account,rhevm-account --build $build_id # Push target images attached to a particular build to each of the specified accounts"
- opts.separator "aeolus-image push --account ec2-account,rhevm-account --image $image_id # Push target images attached to a particular image to each of the specified accounts"
+ opts.on('-A', '--account NAME,NAME', Array, 'name of specific account to import to') do |name|
+ @options[:provider_account] = name
end
+ opts.on( '-h', '--help', 'Get usage information for this command')
- if !subcommand || subcommand == :import
- opts.separator ""
- opts.separator "Import examples:"
- opts.separator "aeolus-image import --provider_account my-ec2 --id $ami_id # import an AMI from the specified provider"
- opts.separator "aeolus-image import --provider_account my-ec2 --id $ami_id --description '<image><name>My Image</name></image>' # import an AMI from the specified provider"
- opts.separator "aeolus-image import --provider_account my-ec2 --id $ami_id --description <path_to_xml_file> # import an AMI from the specified provider"
- end
+ opts.separator ""
+ opts.separator "Examples:"
+ opts.separator "aeolus-image import --account my-ec2 --id $ami_id # import an AMI from the specified provider"
+ opts.separator "aeolus-image import --account my-ec2 --id $ami_id --description '<image><name>My Image</name></image>' # import an AMI from the specified provider"
+ opts.separator "aeolus-image import --account my-ec2 --id $ami_id --description <path_to_xml_file> # import an AMI from the specified provider"
+ end
+ end
- if !subcommand || subcommand == :status
- opts.separator "Status examples:"
- opts.separator "aeolus-image status --targetimage $target_image # status of target image build"
- opts.separator "aeolus-image status --providerimage $provider_image # status of provider image push"
- end
+ def deleteOptions
+ OptionParser.new do |opts|
+ opts.banner = "Usage: aeolus-image delete [command options]"
+ opts.separator ""
- if !subcommand || subcommand == :delete
- opts.separator ""
- opts.separator "Delete examples: (DELETE CURRENTLY NOT IMPLEMENTED) "
- opts.separator "aeolus-image delete --image $image_id # deletes a image and all associated builds"
- opts.separator "aeolus-image delete --build $build_id # deletes a build and all associated targetimages"
- opts.separator "aeolus-image delete --targetimage $target_image # deletes a target image and all associated provider images"
- opts.separator "aeolus-image delete --providerimage $provider_image # deletes a provider image"
+ opts.separator "Delete options:"
+ opts.on('-I', '--image ID', 'delete build image and associated objects') do |id|
+ @options[:subcommand] = :image
+ @options[:image] = id
end
- end
+ opts.on('-B', '--build ID', 'delete build and associated objects') do |id|
+ @options[:subcommand] = :build
+ @options[:build] = id
+ end
+ opts.on('-m', '--targetimage ID', 'delete target image and its provider images') do |id|
+ @options[:subcommand] = :target_image
+ @options[:targetimage] = id
+ end
+ opts.on('-D', '--providerimage ID', 'delete provider image') do |id|
+ @options[:subcommand] = :provider_image
+ @options[:providerimage] = id
+ end
+ opts.on( '-h', '--help', 'Get usage information for this command')
- begin
- @optparse.parse(@args)
- rescue OptionParser::InvalidOption
- puts "Warning: Invalid option"
- exit(1)
- rescue OptionParser::MissingArgument => e
- puts "Warning, #{e.message}"
- exit(1)
+ opts.separator ""
+ opts.separator "Delete examples:"
+ opts.separator "aeolus-image delete --image $image_id # deletes a image and all associated builds"
+ opts.separator "aeolus-image delete --build $build_id # deletes a build and all associated targetimages"
+ opts.separator "aeolus-image delete --targetimage $target_image # deletes a target image and all associated provider images"
+ opts.separator "aeolus-image delete --providerimage $provider_image # deletes a provider image"
end
end
- # TODO: Remove all this boilerplate and replace with some metaprogramming,
- # perhaps method_missing
def list
# TODO: Instantiate and call object matching command type, for example:
# l = ListCommand.new(@options)
@@ -242,7 +263,7 @@ module Aeolus
# self.send(@options[:subcommand])
if @options[:subcommand].nil?
# TODO: Pull out Print Usage into seporate method, and print
- puts "Could not find subcommand for list, run `./aeolus-image --help` for usage instructions"
+ puts "Could not find options for list, run `./aeolus-image list --help` for usage instructions"
exit(1)
else
list_command = ListCommand.new(@options)
@@ -280,6 +301,7 @@ module Aeolus
status_command = StatusCommand.new(@options)
status_command.run
end
+
end
end
-end
+end
\ No newline at end of file
diff --git a/spec/command/config_parser_spec.rb b/spec/command/config_parser_spec.rb
index f3ab88c..5c9c46a 100644
--- a/spec/command/config_parser_spec.rb
+++ b/spec/command/config_parser_spec.rb
@@ -43,7 +43,7 @@ module Aeolus
it "should notify the user of an invalid command" do
config_parser = ConfigParser.new(%w(sparkle))
- config_parser.should_receive(:exit).with(0)
+ config_parser.should_receive(:exit).with(1)
silence_stream(STDOUT) do
config_parser.process
end
@@ -146,8 +146,8 @@ module Aeolus
context "for import command" do
context "without other options" do
- let ( :parameters ) { %w(import --provider ec2-us-east-1a --description /path/to/file --id ami-123456 --target ec2) }
- let ( :options_hash ) { { :provider => ['ec2-us-east-1a'], :target => ['ec2'], :description => '/path/to/file', :id => 'ami-123456' } }
+ let ( :parameters ) { %w(import --account ec2-us-east-1a --description /path/to/file --id ami-123456) }
+ let ( :options_hash ) { { :provider_account => ['ec2-us-east-1a'], :description => '/path/to/file', :id => 'ami-123456' } }
its ( :options ) { should include( options_hash ) }
end
@@ -155,14 +155,14 @@ module Aeolus
context "for build command" do
context "with --template FILE" do
- let ( :parameters ) { %w(build --target ec2,rackspace --image 12345 --template my.tmpl) }
- let ( :options_hash ) { { :target => ['ec2','rackspace'], :image => '12345', :template => 'my.tmpl' } }
+ let ( :parameters ) { %w(build --target ec2,rackspace --template my.tmpl) }
+ let ( :options_hash ) { { :target => ['ec2','rackspace'], :template => 'my.tmpl' } }
its ( :options ) { should include( options_hash ) }
end
context "with --no-validation" do
- let ( :parameters ) { %w(build --target ec2,rackspace --image 12345 --no-validation) }
- let ( :options_hash ) { { :target => ['ec2','rackspace'], :image => '12345', :validation => false } }
+ let ( :parameters ) { %w(build --target ec2,rackspace --no-validation) }
+ let ( :options_hash ) { { :target => ['ec2','rackspace'], :validation => false } }
its ( :options ) { should include( options_hash ) }
end
@@ -170,26 +170,20 @@ module Aeolus
context "for push command" do
context "without other options" do
- let ( :parameters ) { %w(push --provider ec2-us-east1 --id 12345) }
- let ( :options_hash ) { { :provider => ['ec2-us-east1'], :id => '12345' } }
+ let ( :parameters ) { %w(push --account ec2-us-east1 --image 12345) }
+ let ( :options_hash ) { { :account => ['ec2-us-east1'], :image => '12345' } }
its ( :options ) { should include( options_hash ) }
end
context "with --build ID" do
- let ( :parameters ) { %w(push --provider ec2-us-east1 --build 12345) }
- let ( :options_hash ) { { :provider => ['ec2-us-east1'], :build => '12345' } }
+ let ( :parameters ) { %w(push --account ec2-us-east1 --build 12345) }
+ let ( :options_hash ) { { :account => ['ec2-us-east1'], :build => '12345' } }
its ( :options ) { should include( options_hash ) }
end
context "with --targetimage ID" do
- let ( :parameters ) { %w(push --provider ec2-us-east1 --targetimage 12345) }
- let ( :options_hash ) { { :provider => ['ec2-us-east1'], :targetimage => '12345' } }
-
- its ( :options ) { should include( options_hash ) }
- end
- context "with --account NAME" do
- let ( :parameters ) { %w(push --provider ec2-us-east1 --account 12345) }
- let ( :options_hash ) { { :provider => ['ec2-us-east1'], :account => '12345' } }
+ let ( :parameters ) { %w(push --account ec2-us-east1 --targetimage 12345) }
+ let ( :options_hash ) { { :account => ['ec2-us-east1'], :targetimage => '12345' } }
its ( :options ) { should include( options_hash ) }
end
--
1.7.6.4