cloudformula 1.1.2
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 +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +206 -0
- data/Rakefile +1 -0
- data/bin/cloudformula +12 -0
- data/cloudformula.gemspec +26 -0
- data/integration_tests/.ruby-gemset +1 -0
- data/integration_tests/.ruby-version +1 -0
- data/integration_tests/Gemfile +3 -0
- data/integration_tests/README.md +33 -0
- data/integration_tests/fixtures/minimal_cf_template.json +30 -0
- data/integration_tests/fixtures/minimal_cf_template_update.json +54 -0
- data/integration_tests/stack_create_update.rb +26 -0
- data/lib/cloudformula/cli.rb +113 -0
- data/lib/cloudformula/cloud_formation.rb +54 -0
- data/lib/cloudformula/help/create.txt +12 -0
- data/lib/cloudformula/help/generate.txt +10 -0
- data/lib/cloudformula/help/top.txt +20 -0
- data/lib/cloudformula/help/update.txt +12 -0
- data/lib/cloudformula/json_erb.rb +42 -0
- data/lib/cloudformula/string.rb +11 -0
- data/lib/cloudformula/template.rb +99 -0
- data/lib/cloudformula/validator.rb +172 -0
- data/lib/cloudformula/version.rb +3 -0
- data/lib/cloudformula.rb +23 -0
- data/spec/cloud_formula_spec.rb +18 -0
- data/spec/cloudformula/cloud_formation_spec.rb +55 -0
- data/spec/cloudformula/template_spec.rb +303 -0
- data/spec/fixtures/_partial.json.erb +1 -0
- data/spec/fixtures/with_custom_erb_validations.erb +4 -0
- data/spec/fixtures/with_erb_parameters.erb +3 -0
- data/spec/fixtures/with_erb_parameters.json.erb +4 -0
- data/spec/fixtures/with_erb_parameters_and_stack_options.json.erb +5 -0
- data/spec/fixtures/with_erb_parameters_answer.json +4 -0
- data/spec/fixtures/with_erb_parameters_answer.txt +3 -0
- data/spec/fixtures/with_erb_parameters_escaped_answer.json +4 -0
- data/spec/fixtures/with_erb_validations.json.erb +53 -0
- data/spec/fixtures/with_partial.json.erb +5 -0
- data/spec/fixtures/with_partial_answer.json +5 -0
- data/spec/fixtures/with_raw.json.erb +3 -0
- data/spec/fixtures/with_raw_answer.json +3 -0
- data/spec/fixtures/with_stack_options.json.erb +4 -0
- data/spec/fixtures/without_erb_parameters.erb +1 -0
- data/spec/fixtures/without_erb_parameters.json.erb +3 -0
- data/spec/spec_helper.rb +11 -0
- metadata +185 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
NAME
|
2
|
+
cloudformula
|
3
|
+
https://github.com/Kabam/cloudformula
|
4
|
+
|
5
|
+
DESCRIPTION
|
6
|
+
Dynamically generates AWS CloudFormation templates, creates, and updates
|
7
|
+
CloudFormation stacks.
|
8
|
+
|
9
|
+
USAGE
|
10
|
+
cloudformula <command> <options>
|
11
|
+
|
12
|
+
AVAILABLE COMMANDS
|
13
|
+
'cloudformula <command> --help' provides more detailed information for each
|
14
|
+
command.
|
15
|
+
|
16
|
+
generate :: Generate a template
|
17
|
+
create :: Generate a template and create a new CloudFormation stack
|
18
|
+
update :: Generate a template and update an existing CloudFormation stack
|
19
|
+
|
20
|
+
OPTIONS
|
@@ -0,0 +1,12 @@
|
|
1
|
+
NAME
|
2
|
+
cloudformula update
|
3
|
+
|
4
|
+
DESCRIPTION
|
5
|
+
Dynamically generates an AWS CloudFormation template and uses it to update an
|
6
|
+
existing CloudFormation stack.
|
7
|
+
|
8
|
+
USAGE
|
9
|
+
cloudformula update --stack-name '<stackname>' --template '<template>' \\
|
10
|
+
--parameters '<params>' [--region '<region>']
|
11
|
+
|
12
|
+
OPTIONS
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module CloudFormula
|
4
|
+
# Custom ERB compiler which causes variable interpolation inside <%= %> to be json encoded.
|
5
|
+
# Inside regular <% %>, the variables are used without json encoding.
|
6
|
+
#
|
7
|
+
# CloudFormation stack options defaults can be set directly within a template by setting @stack_options.
|
8
|
+
# See README.md "CloudFormation stack options" for details.
|
9
|
+
#
|
10
|
+
# Basic validation functionality is possible by setting @validations.
|
11
|
+
# See README.md "Validations" for details
|
12
|
+
#
|
13
|
+
class JsonErb < ::ERB
|
14
|
+
class CompilerWithBlock < ::ERB::Compiler
|
15
|
+
def add_insert_cmd(out, content)
|
16
|
+
out.push "#{@insert_cmd}((#{content}).to_s.try_to_json)"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def make_compiler(*args)
|
21
|
+
CompilerWithBlock.new *args
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the @stack_options value set within the template.
|
25
|
+
#
|
26
|
+
# @param [Binding] b accepts a Binding or Proc object which is used to set the context of code evaluation.
|
27
|
+
# @return [Hash] The stack options set by the template or an empty Hash if none are set.
|
28
|
+
def stack_options(b = new_toplevel)
|
29
|
+
result(b)
|
30
|
+
b.eval('@stack_options') || {}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the @validations value set within the template.
|
34
|
+
#
|
35
|
+
# @param [Binding] b accepts a Binding or Proc object which is used to set the context of code evaluation.
|
36
|
+
# @return [Hash] The stack options set by the template or an empty Hash if none are set.
|
37
|
+
def validations(b = new_toplevel)
|
38
|
+
result(b)
|
39
|
+
b.eval('@validations') || {}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class String
|
4
|
+
# Returns the string JSON-escaped.
|
5
|
+
# If the cloudformula_raw flag is set, returns the string as-is.
|
6
|
+
# @return [String]
|
7
|
+
def try_to_json
|
8
|
+
return self if instance_variable_get :@cloudformula_raw
|
9
|
+
self.to_json
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module CloudFormula
|
4
|
+
# Defines a CloudFormula/CloudFormation template
|
5
|
+
class Template
|
6
|
+
attr :parameters, :source
|
7
|
+
|
8
|
+
# @param [String] source Path to source template
|
9
|
+
# @param [Hash] parameters Parameter names and values to use in the template
|
10
|
+
def initialize(source = '', parameters = {})
|
11
|
+
@source = source
|
12
|
+
@parameters = parameters
|
13
|
+
end
|
14
|
+
|
15
|
+
# Evaluates and returns the @source template populated with values from @parameters
|
16
|
+
# @return [String]
|
17
|
+
def generate
|
18
|
+
init_parameters @parameters
|
19
|
+
raise "Parameter validation failed.\n\nErrors:\n #{errors.join("\n")}" if invalid?
|
20
|
+
JsonErb.new(File.read(@source)).result(binding)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Evalutes and returns the @source template populated with values from @parameters
|
24
|
+
# @return [Hash]
|
25
|
+
def generate_hash
|
26
|
+
JSON.parse(generate)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Causes the given string value to be output without escape characters
|
30
|
+
# @param [String] value
|
31
|
+
# @return [String]
|
32
|
+
def raw(value)
|
33
|
+
value.instance_variable_set :@cloudformula_raw, true
|
34
|
+
value
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [String] source Path to source template
|
38
|
+
# @param [Hash] parameters Parameter names and values to use in the template
|
39
|
+
# @return [String] The result of generating the template
|
40
|
+
def render(source, parameters = {})
|
41
|
+
raw CloudFormula::Template.new(source, parameters).generate
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the CloudFormation stack options defined by the template.
|
45
|
+
def stack_options
|
46
|
+
init_parameters @parameters
|
47
|
+
JsonErb.new(File.read(@source), 0).stack_options(binding) rescue {}
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the validations defined by the template.
|
51
|
+
def validations
|
52
|
+
init_parameters @parameters
|
53
|
+
JsonErb.new(File.read(@source), 0).validations(binding) rescue {}
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the merged options Hash for use by AWS::CloudFormation::StackCollection#create and
|
57
|
+
# AWS::CloudFormation::Stack#update
|
58
|
+
#
|
59
|
+
# @param [Hash] override_options Optional. Stack options to override. See README.md "CloudFormation stack options" for details
|
60
|
+
# @param [Hash] parameters Parameters to supply to the template. Required if the template contains any required parameters without a default value
|
61
|
+
def aws_options(override_options = {}, parameters = {})
|
62
|
+
stack_options.merge(override_options.merge({ :parameters => parameters }))
|
63
|
+
end
|
64
|
+
|
65
|
+
# Similar to Active Record Validations errors[] object
|
66
|
+
# @see http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#validations_overview-errors
|
67
|
+
def errors
|
68
|
+
validate
|
69
|
+
end
|
70
|
+
|
71
|
+
def valid?
|
72
|
+
errors.length == 0
|
73
|
+
end
|
74
|
+
|
75
|
+
def invalid?
|
76
|
+
!valid?
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# Sets the given Hash as instance variables for use in the ERB template
|
82
|
+
# @param [Hash] values
|
83
|
+
def init_parameters(values = {})
|
84
|
+
values.each { |key, value| instance_variable_set("@#{key}", value) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def validate
|
88
|
+
errors = []
|
89
|
+
validations.each do |parameter_name, parameter_validations|
|
90
|
+
validator = CloudFormula::Validator.new(parameter_name, parameter_validations)
|
91
|
+
validate_result = validator.validate(@parameters[parameter_name.to_sym])
|
92
|
+
errors += validate_result
|
93
|
+
end
|
94
|
+
#puts errors.inspect
|
95
|
+
errors
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module CloudFormula
|
4
|
+
# Contains logic to perform basic validation of parameters defined in a JsonErb template.
|
5
|
+
#
|
6
|
+
# Available validations:
|
7
|
+
# :exclusion => ['val1'] Ensures a value is not in the exclusion list
|
8
|
+
# :inclusion => ['val1', 'val2'] Ensures a value is in the inclusion list
|
9
|
+
# :length => { Ensures value length
|
10
|
+
# :minimum => n,
|
11
|
+
# :maximum => n,
|
12
|
+
# :in|:within => x..y,
|
13
|
+
# :is => n
|
14
|
+
# }
|
15
|
+
# :format => /regex/ Ensures a value matches the regex
|
16
|
+
# :presence => true|false Ensures a value exists and has a length greater than 0
|
17
|
+
#
|
18
|
+
class Validator
|
19
|
+
class Rule
|
20
|
+
attr_accessor :name, :value
|
21
|
+
def initialize(name, value)
|
22
|
+
@name = name
|
23
|
+
@value = value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_accessor :parameter_name, :validations
|
28
|
+
|
29
|
+
# @param [Hash] validations The rules defined for the given parameter_name
|
30
|
+
def initialize(parameter_name, validations)
|
31
|
+
@parameter_name = parameter_name
|
32
|
+
@validations = validations
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param [Object] value The value to check against
|
36
|
+
# @return [Array] An Array of Strings describing the failure(s) if any checks fail, or an empty Array otherwise
|
37
|
+
def validate(value)
|
38
|
+
errors = []
|
39
|
+
@validations.each do |rule_name, rule_value|
|
40
|
+
rule_result = check_rule Rule.new(rule_name, rule_value), value
|
41
|
+
errors += rule_result
|
42
|
+
end
|
43
|
+
errors
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# @param [Rule] rule The rule to check
|
49
|
+
# @param [Object] parameter_value The value to check against
|
50
|
+
# @return [Array] A string describing the failure will be returned if the check fails, or an empty Array otherwise
|
51
|
+
def check_rule(rule, parameter_value)
|
52
|
+
case rule.name
|
53
|
+
when :exclusion, :inclusion, :length, :numericality, :format, :presence
|
54
|
+
self.send("check_#{rule.name}", rule.value, @parameter_name, parameter_value)
|
55
|
+
else
|
56
|
+
raise "Unknown rule name #{rule.name} found in ERB template."
|
57
|
+
end || []
|
58
|
+
end
|
59
|
+
|
60
|
+
def check_exclusion(constraint, parameter_name, value)
|
61
|
+
unless value.nil?
|
62
|
+
if constraint.include? value
|
63
|
+
["Value '#{value}' for parameter '#{parameter_name}' must not be one of [#{constraint.join(', ')}]"]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def check_inclusion(constraint, parameter_name, value)
|
69
|
+
unless value.nil?
|
70
|
+
unless constraint.include? value
|
71
|
+
["Value '#{value}' for parameter '#{parameter_name}' must be one of [#{constraint.join(', ')}]"]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def check_length(constraint, parameter_name, value)
|
77
|
+
errors = []
|
78
|
+
unless value.nil?
|
79
|
+
constraint.each do |length_rule, length_value|
|
80
|
+
case length_rule
|
81
|
+
when :maximum
|
82
|
+
if value.length > length_value
|
83
|
+
errors << "Parameter '#{parameter_name}' must have length less than or equal to #{length_value}"
|
84
|
+
end
|
85
|
+
when :minimum
|
86
|
+
if value.length < length_value
|
87
|
+
errors << "Parameter '#{parameter_name}' must have length greater than or equal to #{length_value}"
|
88
|
+
end
|
89
|
+
when :in, :within
|
90
|
+
unless length_value.cover? value.length
|
91
|
+
errors << "Parameter '#{parameter_name}' must have length in the range of #{length_value}"
|
92
|
+
end
|
93
|
+
when :is
|
94
|
+
if value.length != length_value
|
95
|
+
errors << "Parameter '#{parameter_name}' must have length #{length_value}"
|
96
|
+
end
|
97
|
+
else
|
98
|
+
raise "Unknown length rule attribute #{length_rule} found in ERB template."
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
errors
|
103
|
+
end
|
104
|
+
|
105
|
+
def check_numericality(constraint, parameter_name, value)
|
106
|
+
errors = []
|
107
|
+
unless value.nil?
|
108
|
+
constraint.each do |numericality_rule, numericality_constraint|
|
109
|
+
numeric_value = (/\./ =~ value.to_s ? value.to_f : value.to_i)
|
110
|
+
case numericality_rule
|
111
|
+
when :only_integer
|
112
|
+
if numericality_constraint
|
113
|
+
unless value.to_s =~ /\A[+-]?\d+\Z/
|
114
|
+
errors << "Parameter '#{parameter_name}' must be an integer"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
when :equal_to
|
118
|
+
unless numeric_value == numericality_constraint
|
119
|
+
errors << "Parameter '#{parameter_name}' must be equal to #{numericality_constraint}"
|
120
|
+
end
|
121
|
+
when :greater_than
|
122
|
+
unless numeric_value > numericality_constraint
|
123
|
+
errors << "Parameter '#{parameter_name}' must be greater than #{numericality_constraint}"
|
124
|
+
end
|
125
|
+
when :less_than
|
126
|
+
unless numeric_value < numericality_constraint
|
127
|
+
errors << "Parameter '#{parameter_name}' must be less than #{numericality_constraint}"
|
128
|
+
end
|
129
|
+
when :greater_than_or_equal_to
|
130
|
+
unless numeric_value >= numericality_constraint
|
131
|
+
errors << "Parameter '#{parameter_name}' must be greater than or equal to #{numericality_constraint}"
|
132
|
+
end
|
133
|
+
when :less_than_or_equal_to
|
134
|
+
unless numeric_value <= numericality_constraint
|
135
|
+
errors << "Parameter '#{parameter_name}' must be less than or equal to #{numericality_constraint}"
|
136
|
+
end
|
137
|
+
when :even
|
138
|
+
if numericality_constraint
|
139
|
+
unless numeric_value.respond_to?('even?') && numeric_value.even?
|
140
|
+
errors << "Parameter '#{parameter_name}' must be even"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
when :odd
|
144
|
+
if numericality_constraint
|
145
|
+
unless numeric_value.respond_to?('odd?') && numeric_value.odd?
|
146
|
+
errors << "Parameter '#{parameter_name}' must be odd"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
else
|
150
|
+
raise "Unknown numericality rule attribute #{numericality_rule} found in ERB template."
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
errors
|
155
|
+
end
|
156
|
+
|
157
|
+
def check_format(constraint, parameter_name, value)
|
158
|
+
unless value.nil?
|
159
|
+
unless constraint =~ value
|
160
|
+
["Value '#{value}' for parameter '#{parameter_name}' must match regexp #{constraint.source}"]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def check_presence(constraint, parameter_name, value)
|
166
|
+
if constraint && (value.nil? || value.to_s == '')
|
167
|
+
["Parameter '#{parameter_name}' must exist and have a length of at least 1"]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|
data/lib/cloudformula.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Dir.glob("#{File.dirname(__FILE__)}/cloudformula/*.rb") { |file| require file }
|
2
|
+
|
3
|
+
module CloudFormula
|
4
|
+
class << self # class methods
|
5
|
+
# Creates a new CloudFormula::Template object.
|
6
|
+
# @see CloudFormula::Template.initialize
|
7
|
+
def template(source = '', parameters = {})
|
8
|
+
Template.new(source, parameters)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Creates a new AWS CloudFormation stack
|
12
|
+
# @see CloudFormula::CloudFormation.create_stack
|
13
|
+
def create_stack(region, stack_name, template, override_options = {}, parameters = {}, aws_access_key_id = nil, aws_secret_key = nil)
|
14
|
+
CloudFormation.create_stack(region, stack_name, template, override_options, parameters, aws_access_key_id, aws_secret_key)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Updates an AWS CloudFormation stack
|
18
|
+
# @see CloudFormula::CloudFormation.update_stack
|
19
|
+
def update_stack(region, stack_name, template, parameters = {}, aws_access_key_id = nil, aws_secret_key = nil)
|
20
|
+
CloudFormation.update_stack(region, stack_name, template, parameters, aws_access_key_id, aws_secret_key)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
describe CloudFormula do
|
2
|
+
it 'should have a version' do
|
3
|
+
expect(CloudFormula::VERSION).to_not be_nil
|
4
|
+
expect(CloudFormula::VERSION).to_not be_empty
|
5
|
+
end
|
6
|
+
|
7
|
+
it 'template method should return a new Template object' do
|
8
|
+
expect(CloudFormula.template).to be_an_instance_of(CloudFormula::Template)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'create_stack method' do
|
12
|
+
expect(CloudFormula).to respond_to(:create_stack)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'update_stack method' do
|
16
|
+
expect(CloudFormula).to respond_to(:update_stack)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module CloudFormula
|
4
|
+
describe CloudFormation do
|
5
|
+
describe 'create_stack method' do
|
6
|
+
it 'should exist' do
|
7
|
+
expect(CloudFormula::CloudFormation).to respond_to(:create_stack)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'update_stack method' do
|
12
|
+
it 'should exist' do
|
13
|
+
expect(CloudFormula::CloudFormation).to respond_to(:update_stack)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'private get_cloud_formation method' do
|
18
|
+
it 'should raise an error with invalid credentials explicitly passed to it' do
|
19
|
+
stub_aws_env
|
20
|
+
CloudFormula::CloudFormation.instance_eval do
|
21
|
+
def test_cf
|
22
|
+
get_cloud_formation('us-east-1', 'foo', 'bar')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
expect(CloudFormula::CloudFormation.test_cf).to be_a(AWS::CloudFormation)
|
26
|
+
expect { CloudFormula::CloudFormation.test_cf.stacks.each }.to raise_error
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should work with credentials from ENV' do
|
30
|
+
# This test requires AWS credentials in ENV. Unfortunately it cannot be faked.
|
31
|
+
CloudFormula::CloudFormation.instance_eval do
|
32
|
+
def test_cf
|
33
|
+
get_cloud_formation('us-east-1')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
expect(CloudFormula::CloudFormation.test_cf).to be_a(AWS::CloudFormation)
|
37
|
+
expect { CloudFormula::CloudFormation.test_cf.stacks.each }.to_not raise_error
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def stub_aws_env
|
45
|
+
ENV.stub(:[]).with('AWS_ACCESS_KEY_ID').and_return(nil)
|
46
|
+
ENV.stub(:[]).with('AWS_SECRET_ACCESS_KEY').and_return(nil)
|
47
|
+
ENV.stub(:[]).with('AWS_SESSION_TOKEN').and_return(nil)
|
48
|
+
ENV.stub(:[]).with('AWS_CREDENTIAL_FILE').and_return(nil)
|
49
|
+
ENV.stub(:[]).with('http_proxy').and_return(nil)
|
50
|
+
ENV.stub(:[]).with('HTTP_PROXY').and_return(nil)
|
51
|
+
ENV.stub(:[]).with('AMAZON_ACCESS_KEY_ID').and_return(nil)
|
52
|
+
ENV.stub(:[]).with('AMAZON_SECRET_ACCESS_KEY').and_return(nil)
|
53
|
+
ENV.stub(:[]).with('AMAZON_SESSION_TOKEN').and_return(nil)
|
54
|
+
ENV.stub(:[]).with('AMAZON_CREDENTIAL_FILE').and_return(nil)
|
55
|
+
end
|