staugaard-cloudmaster 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. data/VERSION.yml +4 -0
  2. data/bin/cloudmaster +45 -0
  3. data/lib/AWS/AWS.rb +3 -0
  4. data/lib/AWS/EC2.rb +14 -0
  5. data/lib/AWS/S3.rb +14 -0
  6. data/lib/AWS/SQS.rb +14 -0
  7. data/lib/AWS/SimpleDB.rb +14 -0
  8. data/lib/MockAWS/EC2.rb +119 -0
  9. data/lib/MockAWS/S3.rb +39 -0
  10. data/lib/MockAWS/SQS.rb +82 -0
  11. data/lib/MockAWS/SimpleDB.rb +46 -0
  12. data/lib/MockAWS/clock.rb +67 -0
  13. data/lib/OriginalAWS/AWS.rb +475 -0
  14. data/lib/OriginalAWS/EC2.rb +783 -0
  15. data/lib/OriginalAWS/S3.rb +559 -0
  16. data/lib/OriginalAWS/SQS.rb +159 -0
  17. data/lib/OriginalAWS/SimpleDB.rb +460 -0
  18. data/lib/RetryAWS/EC2.rb +88 -0
  19. data/lib/RetryAWS/S3.rb +77 -0
  20. data/lib/RetryAWS/SQS.rb +109 -0
  21. data/lib/RetryAWS/SimpleDB.rb +118 -0
  22. data/lib/SafeAWS/EC2.rb +63 -0
  23. data/lib/SafeAWS/S3.rb +56 -0
  24. data/lib/SafeAWS/SQS.rb +75 -0
  25. data/lib/SafeAWS/SimpleDB.rb +88 -0
  26. data/lib/aws_context.rb +165 -0
  27. data/lib/basic_configuration.rb +120 -0
  28. data/lib/clock.rb +10 -0
  29. data/lib/factory.rb +14 -0
  30. data/lib/file_logger.rb +36 -0
  31. data/lib/inifile.rb +148 -0
  32. data/lib/instance_logger.rb +25 -0
  33. data/lib/logger_factory.rb +38 -0
  34. data/lib/periodic.rb +29 -0
  35. data/lib/string_logger.rb +29 -0
  36. data/lib/sys_logger.rb +40 -0
  37. data/lib/user_data.rb +30 -0
  38. data/test/aws-config.ini +9 -0
  39. data/test/cloudmaster-tests.rb +329 -0
  40. data/test/configuration-test.rb +62 -0
  41. data/test/daytime-policy-tests.rb +47 -0
  42. data/test/enumerator-test.rb +47 -0
  43. data/test/fixed-policy-tests.rb +50 -0
  44. data/test/instance-pool-test.rb +359 -0
  45. data/test/instance-test.rb +98 -0
  46. data/test/job-policy-test.rb +95 -0
  47. data/test/manual-policy-tests.rb +63 -0
  48. data/test/named-queue-test.rb +90 -0
  49. data/test/resource-policy-tests.rb +126 -0
  50. data/test/suite +17 -0
  51. data/test/test-config.ini +47 -0
  52. metadata +111 -0
@@ -0,0 +1,165 @@
1
+
2
+ require 'AWS/SQS'
3
+ require 'AWS/EC2'
4
+ require 'AWS/S3'
5
+ require 'AWS/SimpleDB'
6
+ require 'SafeAWS/SQS'
7
+ require 'SafeAWS/EC2'
8
+ require 'SafeAWS/S3'
9
+ require 'SafeAWS/SimpleDB'
10
+ require 'RetryAWS/SQS'
11
+ require 'RetryAWS/EC2'
12
+ require 'RetryAWS/S3'
13
+ require 'RetryAWS/SimpleDB'
14
+ require 'MockAWS/EC2'
15
+ require 'MockAWS/S3'
16
+ require 'MockAWS/SQS'
17
+ require 'MockAWS/SimpleDB'
18
+ require 'logger'
19
+
20
+ # Make sure there is a Clock implementation.
21
+ # If not, supply one.
22
+ # Caller may supply a mock implementation instead of the standard one.
23
+ begin
24
+ Clock.now
25
+ rescue
26
+ require 'clock'
27
+ end
28
+
29
+ # Creates and caches EC2, SQS, and S3 interface implementations.
30
+ # Can serve up AWS, SafeAWS, RetryAWS, or MockAWS interfaces.
31
+ # Every time we create one, we reset the interfaces by forcing the
32
+ # creation of new objects.
33
+ # This is treated as a global. It is initialized by calling "AwsContext.setup"
34
+ # and then anyone can get a copy by calling "AwsContext.instance".
35
+ class AwsContext
36
+ private_class_method :new
37
+ @@instance = nil
38
+
39
+ def initialize(context, logger)
40
+ @context = context
41
+ @logger = logger
42
+ @ec2 = @sqs = @s3 = @sdb = nil
43
+ end
44
+
45
+ # Create a AwsContext.
46
+ #
47
+ # The context here can be one of
48
+ # * :aws -- use the standard AWS interface
49
+ # * :safe -- use the SafeAWS interface
50
+ # * :retry -- use the RetryAWS interface
51
+ # * :mock -- use the MockAWS interface
52
+ #
53
+ # The interface is established the first time you use it. The
54
+ # returned interface is retained, and used for subsequent requests.
55
+ # Thus only one instance of each interface is created.
56
+ def AwsContext.setup(context, logger = nil)
57
+ @@instance = new(context, logger)
58
+ end
59
+
60
+ # Return the instance that was already created.
61
+ # If none created yet, then create AWS context.
62
+ def AwsContext.instance
63
+ if @@instance.nil?
64
+ setup(:aws)
65
+ end
66
+ @@instance
67
+ end
68
+
69
+ private
70
+
71
+ # Create an EC2 interface.
72
+ def create_ec2(*params)
73
+ case @context
74
+ when :aws
75
+ @ec2 = AWS::EC2.new(*params)
76
+ when :safe
77
+ @ec2 = SafeAWS::EC2.new(*params)
78
+ when :retry
79
+ @ec2 = RetryAWS::EC2.new(*params)
80
+ when :mock
81
+ @ec2 = MockAWS::EC2.new(*params)
82
+ @ec2.reset
83
+ @ec2.logger = @logger if @logger
84
+ end
85
+ @ec2
86
+ end
87
+
88
+ # Create an sqs interface.
89
+ def create_sqs(*params)
90
+ case @context
91
+ when :aws
92
+ @sqs = AWS::SQS.new(*params)
93
+ when :safe
94
+ @sqs = SafeAWS::SQS.new(*params)
95
+ when :retry
96
+ @sqs = RetryAWS::SQS.new(*params)
97
+ when :mock
98
+ @sqs = MockAWS::SQS.new(*params)
99
+ @sqs.reset
100
+ @sqs.logger = @logger if @logger
101
+ end
102
+ @sqs
103
+ end
104
+
105
+ # Create an S3 interface.
106
+ def create_s3(*params)
107
+ case @context
108
+ when :aws
109
+ @s3 = AWS::S3.new(*params)
110
+ when :safe
111
+ @s3 = SafeAWS::S3.new(*params)
112
+ when :retry
113
+ @s3 = RetryAWS::S3.new(*params)
114
+ when :mock
115
+ @s3 = MockAWS::S3.new(*params)
116
+ @s3.logger = @logger if @logger
117
+ @s3.reset
118
+ end
119
+ @s3
120
+ end
121
+
122
+ # Create a SimpleDB interface.
123
+ def create_sdb(*params)
124
+ case @context
125
+ when :aws
126
+ @sdb = AWS::SimpleDB.new(*params)
127
+ when :safe
128
+ @sdb = SafeAWS::SimpleDB.new(*params)
129
+ when :retry
130
+ @sdb = RetryAWS::SimpleDB.new(*params)
131
+ when :mock
132
+ @sdb = MockAWS::SimpleDB.new(*params)
133
+ @sdb.logger = @logger if @logger
134
+ @sdb.reset
135
+ end
136
+ @sdb
137
+ end
138
+
139
+ public
140
+
141
+ # Return an EC2 interface. Create on if needed.
142
+ # Note that the parameters (if given) are only used if the interface is created.
143
+ def ec2(*params)
144
+ @ec2 || create_ec2(*params)
145
+ end
146
+
147
+ # Return an SQS interface. Create on if needed.
148
+ # Note that the parameters (if given) are only used if the interface is created.
149
+ def sqs(*params)
150
+ @sqs || create_sqs(*params)
151
+ end
152
+
153
+ # Return a S3 interface. Create on if needed.
154
+ # Note that the parameters (if given) are only used if the interface is created.
155
+ def s3(*params)
156
+ @s3 || create_s3(*params)
157
+ end
158
+
159
+ # Return a SimpleDB interface. Create on if needed.
160
+ # Note that the parameters (if given) are only used if the interface is created.
161
+ def sdb(*params)
162
+ @sdb || create_sdb(*params)
163
+ end
164
+
165
+ end
@@ -0,0 +1,120 @@
1
+ require 'inifile'
2
+ require 'pp'
3
+
4
+ # BasicConfiguration
5
+ # Read an ini file and create a configuration.
6
+ # The configuration contains the aws configuration only.
7
+
8
+ class BasicConfiguration
9
+ attr_reader :aws
10
+
11
+ # Default list of config files to search for
12
+ DEFAULT_CONFIG_FILES = ['aws-config.ini', 'default-config.ini', 'config.ini']
13
+ # Search for config files in these directories
14
+ DEFAULT_SEARCH_PATH = [ ".", ENV['AWS_HOME'], ENV['HOME'], File.dirname(__FILE__)]
15
+
16
+ @@config_files = DEFAULT_CONFIG_FILES
17
+ @@search_path = DEFAULT_SEARCH_PATH
18
+
19
+ # Set up the list of config files that is read when looking for configurations.
20
+ # If this is not called, a default set of files is read.
21
+ def BasicConfiguration.setup_config_files(config_files = [])
22
+ @@config_files = config_files
23
+ end
24
+
25
+ # Set up the search path.
26
+ # If this is not called, a default path is used
27
+ def BasicConfiguration.setup_search_path(search_path = [])
28
+ @@search_path = search_path
29
+ end
30
+
31
+ # Add the given array of files to the list that we read.
32
+ def BasicConfiguration.add_config_files(config_files)
33
+ @@config_files |= config_files
34
+ end
35
+
36
+ # Add the following set of search paths to the ones that we use.
37
+ def BasicConfiguration.add_search_paths(search_paths)
38
+ @@search_path |= search_paths
39
+ end
40
+
41
+ # Create a config structure by reading the given config_filenames.
42
+ # If config files or search_paths are given, they apply only to this
43
+ # instance, but are retained for use by refresh.
44
+ # Create default aws config items based on environment varbiables, in
45
+ # case we can't find a config file.
46
+ def initialize(config_files = [], search_paths = [])
47
+ @config_files = @@config_files | config_files
48
+ @search_path = @@search_path | search_paths
49
+ refresh
50
+ end
51
+
52
+ # Read the configuration from the existing config file using
53
+ # the existing filenames.
54
+ # This is useful for reinitiaizing on a SIGTERM
55
+ def refresh
56
+ @aws = get_aws_from_environment
57
+ read_config
58
+ end
59
+
60
+ def keys
61
+ [ @aws[:aws_access_key], @aws[:aws_secret_key]]
62
+ end
63
+
64
+ private
65
+
66
+ # Looks up an environment variable, and returns the value, if there is one.
67
+ # If the caller asks for some environment variable that is not
68
+ # present in the environment, then the default is returned.
69
+ def get_environment(var, default = nil)
70
+ ENV[var] || default
71
+ end
72
+
73
+
74
+ def get_aws_from_environment
75
+ # Get aws config from the environment
76
+ aws_user = get_environment('AWS_USER', 'aws')
77
+ key_file = File.join(ENV['HOME'], 'keys', "#{aws_user}-kp.pem")
78
+
79
+ # Set up our credentials from the environment
80
+ # These sere as a default to the credentials in the
81
+ # config.ini file.
82
+ { :aws_env => ENV['AWS_ENV'],
83
+ :aws_access_key => get_environment('AWS_ACCESS_KEY'),
84
+ :aws_secret_key => get_environment('AWS_SECRET_KEY'),
85
+ :aws_user => aws_user,
86
+ :aws_bucket => get_environment('AWS_BUCKET'),
87
+ :aws_key => get_environment('AWS_KEY', key_file)
88
+ }
89
+ end
90
+
91
+ # Read all the config files in order
92
+ def read_config
93
+ @config_files.each {|config_file| read(config_file)}
94
+ end
95
+
96
+ # Read the config file and store aws section.
97
+ def read(config_file)
98
+ ini = IniFile.load(find_on_search_path(config_file))
99
+ return nil unless ini
100
+ # Merge in the items from the 'aws' section, overriding the defaults.
101
+ # This needs to be first, so others can use it.
102
+ @aws.merge!(ini['aws'])
103
+ ini
104
+ end
105
+
106
+ # If filename starts with "/" then return it unchanged.
107
+ # Otherwise try various prefixes on it.
108
+ # Return the first one that is actually a file.
109
+ # Retun nil if the file does not exist at any of the places.
110
+ def find_on_search_path(filename)
111
+ return filename if filename[0..0] == File::SEPARATOR
112
+ @search_path.each do |prefix|
113
+ unless prefix.nil?
114
+ fn = File.join(prefix, filename)
115
+ return fn if File.exists?(fn)
116
+ end
117
+ end
118
+ nil
119
+ end
120
+ end
data/lib/clock.rb ADDED
@@ -0,0 +1,10 @@
1
+
2
+ # Used to wrap Time so it can be mocked
3
+
4
+ class Clock < Time
5
+
6
+ def Clock.sleep(numeric = 0)
7
+ Kernel.sleep numeric
8
+ end
9
+
10
+ end
data/lib/factory.rb ADDED
@@ -0,0 +1,14 @@
1
+ # This contains common factory methods.
2
+
3
+ module Factory
4
+ # Given a class name as a string, create an instance of that class
5
+ # and initialize it with the given arguments.
6
+ def Factory.create_object_from_string(class_name, *args)
7
+ ObjectSpace.each_object(Class) do |x|
8
+ if x.name == class_name || x.name == "Cloudmaster::#{class_name}"
9
+ return x.new(*args)
10
+ end
11
+ end
12
+ nil
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ # The default logger writes to a file descriptor.
2
+ # This could be an actual file, or a stream such as STDOUT.
3
+ class FileLogger
4
+ def initialize(file = nil, *args)
5
+ case
6
+ when file.nil?
7
+ @fd = STDOUT
8
+ @needs_close = false
9
+ when file.is_a?(String)
10
+ @fd = File.new(file, "a")
11
+ @needs_close = true
12
+ else
13
+ @fd = file
14
+ @needs_close = false
15
+ end
16
+ end
17
+
18
+ def puts(msg)
19
+ @fd.puts msg
20
+ end
21
+
22
+ def close
23
+ @fd.close if @needs_close
24
+ end
25
+
26
+ alias debug puts
27
+ alias info puts
28
+ alias notice puts
29
+ alias warning puts
30
+ alias err puts
31
+ alias error puts
32
+ alias alert puts
33
+ alias emerg puts
34
+ alias crit puts
35
+ end
36
+
data/lib/inifile.rb ADDED
@@ -0,0 +1,148 @@
1
+ #
2
+ # This class represents the INI file and can be used to parse INI files.
3
+ # Derived from IniFile gem, found on http://rubyforge.org/projects/inifile/
4
+ #
5
+ class IniFile
6
+
7
+ #
8
+ # call-seq:
9
+ # IniFile.load( filename )
10
+ # IniFile.load( filename, options )
11
+ #
12
+ # Open the given _filename_ and load the contents of the INI file.
13
+ # The following _options_ can be passed to this method:
14
+ #
15
+ # :comment => ';' The line comment character(s)
16
+ # :parameter => '=' The parameter / value separator
17
+ #
18
+ def self.load( filename, opts = {} )
19
+ if filename
20
+ new(filename, opts)
21
+ else
22
+ nil
23
+ end
24
+ end
25
+
26
+ def initialize( filename, opts = {} )
27
+ @fn = filename
28
+ @comment = opts[:comment] || '#'
29
+ @param = opts[:parameter] || '='
30
+ @ini = Hash.new {|h,k| h[k] = Hash.new}
31
+
32
+ @rgxp_comment = /^\s*$|^\s*[#{@comment}]/
33
+ @rgxp_section = /^\s*\[([^\]]+)\]/
34
+ @rgxp_param = /^([^#{@param}]+)#{@param}(.*)$/
35
+
36
+ parse
37
+ end
38
+
39
+ #
40
+ # call-seq:
41
+ # each {|section, parameter, value| block}
42
+ #
43
+ # Yield each _section_, _parameter_, _value_ in turn to the given
44
+ # _block_. The method returns immediately if no block is supplied.
45
+ #
46
+ def each
47
+ return unless block_given?
48
+ @ini.each do |section,hash|
49
+ hash.each do |param,val|
50
+ yield section, param, val
51
+ end
52
+ end
53
+ self
54
+ end
55
+
56
+ #
57
+ # call-seq:
58
+ # each_section {|section| block}
59
+ #
60
+ # Yield each _section_ in turn to the given _block_. The method returns
61
+ # immediately if no block is supplied.
62
+ #
63
+ def each_section
64
+ return unless block_given?
65
+ @ini.each_key {|section| yield section}
66
+ self
67
+ end
68
+
69
+ #
70
+ # call-seq:
71
+ # ini_file[section]
72
+ #
73
+ # Get the hash of parameter/value pairs for the given _section_.
74
+ #
75
+ def []( section )
76
+ return nil if section.nil?
77
+ @ini[section.to_s]
78
+ end
79
+
80
+ #
81
+ # call-seq:
82
+ # has_section?( section )
83
+ #
84
+ # Returns +true+ if the named _section_ exists in the INI file.
85
+ #
86
+ def has_section?( section )
87
+ @ini.has_key? section.to_s
88
+ end
89
+
90
+ #
91
+ # call-seq:
92
+ # sections
93
+ #
94
+ # Returns an array of the section names.
95
+ #
96
+ def sections
97
+ @ini.keys
98
+ end
99
+
100
+ private
101
+
102
+ def cleanup(str)
103
+ str = str.strip
104
+ first = str[0..0]; last = str[-1..-1]
105
+ str = str[1..-2] if first == last && (first == '"' || first == "'")
106
+ end
107
+ #
108
+ # call-seq
109
+ # parse
110
+ #
111
+ # Parse the ini file contents.
112
+ #
113
+ def parse
114
+ return unless ::Kernel.test ?f, @fn
115
+ section = nil
116
+
117
+ ::File.open(@fn, 'r') do |f|
118
+ while line = f.gets
119
+ line = line.chomp
120
+
121
+ case line
122
+ # ignore blank lines and comment lines
123
+ when @rgxp_comment: next
124
+
125
+ # this is a section declaration
126
+ when @rgxp_section: section = @ini[$1.strip.downcase]
127
+
128
+ # otherwise we have a parameter
129
+ when @rgxp_param
130
+ begin
131
+ val = $2.strip
132
+ val = val[1..-2] if val[0..0] == "'" || val[-1..-1] == '"'
133
+ section[$1.strip.downcase.to_sym] = val
134
+ rescue NoMethodError
135
+ raise "Bad configuration - inifile parameter encountered before first section"
136
+ end
137
+
138
+ else
139
+ raise "Bad configuration -- inifile could not parse line '#{line}"
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ end
146
+
147
+
148
+
@@ -0,0 +1,25 @@
1
+ # The instance logger writes to a file in a given directory.
2
+ # The file is determined by the instance_id in the message.
3
+ # The file is opened and closed each time something is written.
4
+ class InstanceLogger
5
+ def initialize(dir)
6
+ @directory = dir
7
+ end
8
+
9
+ def puts(instance, msg)
10
+ File.open(File.join(@directory, instance), "a") do |fd|
11
+ fd.puts msg
12
+ end
13
+ end
14
+
15
+ alias debug puts
16
+ alias info puts
17
+ alias notice puts
18
+ alias warning puts
19
+ alias err puts
20
+ alias error puts
21
+ alias alert puts
22
+ alias emerg puts
23
+ alias crit puts
24
+ end
25
+
@@ -0,0 +1,38 @@
1
+ require 'factory'
2
+ require 'sys_logger'
3
+ require 'string_logger'
4
+ require 'file_logger'
5
+
6
+ class LoggerFactory
7
+ include Factory
8
+ @@filename = 'logfile'
9
+ @@program = 'unknown'
10
+
11
+ def LoggerFactory.setup(filename, program = 'unknown')
12
+ @@filename = filename
13
+ @@program = program
14
+ end
15
+
16
+ def LoggerFactory.create(type, *params)
17
+ filename = filename || @@filename
18
+ program = program || @@program
19
+ name = type.to_s
20
+ require name.downcase + '_logger'
21
+ class_name = name.capitalize + 'Logger'
22
+ logger = Factory.create_object_from_string(class_name, filename, program)
23
+ raise "Bad configuration -- no logger #{class_name}" unless logger
24
+ logger
25
+
26
+ # case type.to_s
27
+ # when 'syslog'
28
+ # SysLogger.new(program)
29
+ # when 'string'
30
+ # StringLogger.new
31
+ # when 'stdout'
32
+ # FileLogger.new(STDOUT, false)
33
+ # when 'file'
34
+ # FileLogger.new(File.new(filename, "a"), true)
35
+ # end
36
+ end
37
+ end
38
+
data/lib/periodic.rb ADDED
@@ -0,0 +1,29 @@
1
+ # Used to execute tasks periodically.
2
+ # Execute at most once each interval (seconds).
3
+ # If interval is < 0, never execute.
4
+ # If interval is 0, execute every time.
5
+ class Periodic
6
+ # Create a periodic execution at this interval.
7
+ def initialize(interval)
8
+ @last_time = Clock.at(0)
9
+ @interval = interval
10
+ end
11
+
12
+ # Runs if it has not executed in the interval,.
13
+ # Skip otherwise.
14
+ def check #expects a block
15
+ case
16
+ when @interval < 0
17
+ return
18
+ when @interval == 0
19
+ yield
20
+ when @interval > 0
21
+ now = Clock.now
22
+ if (@last_time + @interval) < now
23
+ yield
24
+ @last_time = now
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,29 @@
1
+ # Logs to a string.
2
+ # This is useful in testing so that we can read back what
3
+ # was put into the log, to see if it was what was expected.
4
+ class StringLogger
5
+ def initialize(*params)
6
+ @log = StringIO.new("", "w")
7
+ end
8
+ def close
9
+ end
10
+
11
+ def puts(msg)
12
+ @log.puts(msg)
13
+ end
14
+
15
+ def string
16
+ @log.string
17
+ end
18
+
19
+ alias debug puts
20
+ alias info puts
21
+ alias notice puts
22
+ alias warning puts
23
+ alias err puts
24
+ alias error err
25
+ alias alert puts
26
+ alias emerg puts
27
+ alias crit puts
28
+ end
29
+
data/lib/sys_logger.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'syslog'
2
+
3
+ # Logs using the syslog facility.
4
+ class SysLogger
5
+ def initialize(dummy, program_name)
6
+ @log = Syslog.open(program_name)
7
+ end
8
+
9
+ def close
10
+ end
11
+ def puts(msg)
12
+ @log.info(msg)
13
+ end
14
+ def debug(msg)
15
+ @log.debug(msg)
16
+ end
17
+ def info(msg)
18
+ @log.info(msg)
19
+ end
20
+ def notice(msg)
21
+ @log.notice(msg)
22
+ end
23
+ def warning(msg)
24
+ @log.warning(msg)
25
+ end
26
+ def err(msg)
27
+ @log.err(msg)
28
+ end
29
+ def alert(msg)
30
+ @log.alert(msg)
31
+ end
32
+ def emerg(msg)
33
+ @log.emerg(msg)
34
+ end
35
+ def crit(msg)
36
+ @log.crit(msg)
37
+ end
38
+ alias error err
39
+ end
40
+
data/lib/user_data.rb ADDED
@@ -0,0 +1,30 @@
1
+ # This class loads user data.
2
+
3
+ require 'open-uri'
4
+ require 'yaml'
5
+
6
+ class UserData
7
+ # Load user data
8
+ def self.load
9
+ begin
10
+ iid = open('http://169.254.169.254/latest/meta-data/instance-id').read(200)
11
+ user_data = open('http://169.254.169.254/latest/user-data').read(2000)
12
+ data = YAML.load(user_data)
13
+ aws = { :aws_env => data[:aws_env],
14
+ :aws_access_key => data[:aws_access_key],
15
+ :aws_secret_key => data[:aws_secret_key]
16
+ }
17
+ rescue
18
+ # when running locally, use fake iid
19
+ iid = "unknown"
20
+ user_data = nil
21
+ aws = {}
22
+ end
23
+ @@data = {:aws => aws, :iid => iid, :user_data => user_data}
24
+ @@data
25
+ end
26
+
27
+ def self.keys
28
+ [@@data[:aws][:aws_access_key], @@data[:aws][:aws_secret_key]] if @@data
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ #
2
+ # EC2 Instance Manager Test Configuration
3
+ [AWS]
4
+ aws_env=test
5
+ aws_access_key='test'
6
+ aws_secret_key='test'
7
+ aws_user=chayden
8
+ aws_bucket=chayden
9
+ aws_keypair=test