#outputstring below allows the initialization of how data should be outpout - it is used for both file and screen output. As for the use of a number of strings - I found the formatting easier to read but I'd be open to using one string if evidence supported that being a better way to do this
$stderr.print"You specified a seperator with format that was not \"screen\" or \"file\". You do not need to specify a seperator for the given format.\n"
exit64
end
options[:seperator]=seperator
end
#options processing for region
opts.on('-r','--region REGION',"Region for which Instance Costs Should be Provided. Accepts values such as \"us-east-1\" or \"us-west-1.\" Default value is \"all\".")do|region_selected|
opts.on('-p','--period PERIOD',"Period for Which Costs Should Be Calculated. Accepts values \"hour\", \"day\", \"week\", \"month\" or \"year\". Default value is \"hour\".")do|period|
period.downcase!
caseperiod
when"hour"
options[:multiplier]=1
when"day"
options[:multiplier]=24
when"week"
options[:multiplier]=168
when"month"
options[:multiplier]=720
when"year"
options[:multiplier]=8760
else
$stderr.print"You specified the period \"",period,".\" Valid inputs are \"hour\", \"day\", \"week\", \"month\" or \"year.\"\n"
exit64
end
end
#options processing for status
opts.on('-s','--status STATUS',"Status for which instance cost should be gotten. Default is \"running\" status. Acceptable inputs are \"pending\"\"running\"\"shutting_down\", \"terminated\", \"stopping\", \"stopped.\"")do|status_selected|
status_selected.downcase!
#if instance_valid_statuses includes the user provided status, place in the options hash
#mode - allowing either "byinstance" - in which the cost of each instance is listed or "byASG" in which the cost of each ASG is listed
opts.on("-m","--mode MODE","mode in which ",program_name," runs. Accepts values \"byinstance\" or \"byASG.\" Default value is \"byinstance\".")do|mode|
#forces option to lowercase - easier to evaluate variables when always lowercase
mode.downcase!
if(mode=="byinstance"||mode=="byasg")
options[:mode]=mode
else
$stderr.print"You must specifiy a mode such as \"byinstance\" or \"byasg\". You specified \"",mode,".\"\n"
opts.on("--awscredentialfile CREDENTIAILFILE","path to AWS credential file. This is required if the path to an AWS credential file is not provided by an environment variable.")do|awscredentialfile|
#ensures that if output is mysql that mysqluser, mysqlpass and mysqlhost are set
ifoptions[:output]=="mysql"
ifmysql_connection_info[:mysql_user].nil?
$stderr.print"If you are outputing to MySQL using \"--output mysql\" you must specify a mysql username using \"--mysqluser.\"\n"
exit64;
end
ifmysql_connection_info[:mysql_pass].nil?
$stderr.print"If you are outputing to MySQL using \"--output mysql\" you must specify a mysql password using \"--mysqlpass.\"\n"
exit64;
end
ifmysql_connection_info[:mysql_host].nil?
$stderr.print"If you are outputing to MySQL using \"--output mysql\" you must specify a mysql hostname using \"--mysqlhost.\"\n"
exit64;
end
end
#case statement determines the location where AWS credentials should be gotten. Defaults to "env" (environment) if set to "file" will read from a user provided file.
awscredentialsmissingtext="The environment variable AWS_CREDENTIAL_FILE must exist and point to a valid credential file in order for ","#{program_name}"," to run. The AWS_CREDENTIAL_FILE must contain also contain the two lines below:\n AWSAccessKeyId=<your access key>\n AWSSecretKey=<your secret key>\nPlease correct this error and run again.\n"
when"file"
credentialfile=options[:awscredentialfile]
awscredentialsmissingtext="The AWS Credential File you specified must exist for ","#{program_name}"," to run. The specified file must contain also contain the two lines below:\n AWSAccessKeyId=<your access key>\n AWSSecretKey=<your secret key>\nPlease correct this error and run again.\n"
else
$stderr.print"A problem was encountered when attempting to set AWS Credentials."
$stderr.print"The region \"",options[:user_selected_region],"\" has been selected.\n"
options[:region]=options[:user_selected_region]
else
$stderr.print"You specified the region \"",options[:user_selected_region],".\" You need to specify a valid region (example: \"us-east-1\") or region \"all\" for all regions.\n"
#AWS.memoize "causes the sdk to hold onto information until the end of the memoization block" - rather than return information for each function. Performance improvement went from slow (~1 second per instance to 5 seconds for 200 instances)
AWS.memoizedo
#First Code Block: passes in regional_resource (endpoint) - 1 call for each AWS region
#Second Code Block: for each region, list all EC2 instances
#corrects an issue where instance.platform returns nil if a "linux" based instance - see https://forums.aws.amazon.com/thread.jspa?threadID=94567&tstart=0
ifinstance.platform==nil
platform="linux"
else
platform=instance.platform
end
#creates an "Instance" object with a number of attributes
#if mode is "byasg" create a new asg cost object and then insert into the asg_cost_collection
ifoptions[:mode]=="byasg"
#handles case where "ASG" tag is not set, sets to "<nil> string"
ifec2_object.asg.nil?
ec2_object.asg="<nil>"
end
#asg_unique_id is a unique id for each Auto Scaling Group in each region. Converting all values to strings (to_s) ensures no errors when concatinating - one example of a need to convert to string is a "nil" value for ASG - which would cause errors on concatenation.