aws-must-templates 0.1.6 → 0.2.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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +97 -44
  3. data/lib/tasks/cross-ref.rb +6 -0
  4. data/lib/tasks/suite.rake +150 -48
  5. data/lib/test-suites/test_suites.rb +13 -13
  6. data/mustache/commonDependsOn.mustache +24 -2
  7. data/mustache/commonRef.mustache +22 -0
  8. data/mustache/commonValue.mustache +1 -1
  9. data/mustache/commonXGressRule.mustache +31 -0
  10. data/mustache/mapping.mustache +3 -1
  11. data/mustache/mappingAmazonVpcNat.mustache +38 -0
  12. data/mustache/resource.mustache +4 -0
  13. data/mustache/resourceInstance.mustache +26 -7
  14. data/mustache/resourceInternetGateway.mustache +30 -16
  15. data/mustache/resourceRoute.mustache +50 -0
  16. data/mustache/resourceRouteTable.mustache +67 -0
  17. data/mustache/resourceSecurityGroup.mustache +13 -12
  18. data/mustache/resourceSubnet.mustache +20 -8
  19. data/mustache/root.mustache +26 -11
  20. data/spec/aws-must-templates/AllwaysOk/AllwaysOk_spec.rb +35 -0
  21. data/spec/aws-must-templates/AwsCommandLineInterfaceInstalled/AwsCommandLineInterfaceInstalled_spec.rb +19 -1
  22. data/spec/aws-must-templates/AwsMustTestRunnerProperties/AwsMustTestRunnerProperties_spec.rb +16 -1
  23. data/spec/aws-must-templates/CloudFormationHelperScriptsInstalled/CloudFormationHelperScriptsInstalled_spec.rb +17 -0
  24. data/spec/aws-must-templates/Ec2InstanceType/Ec2InstanceType_spec.rb +47 -0
  25. data/spec/aws-must-templates/Ec2PrivateIp/Ec2PrivateIp_spec.rb +49 -0
  26. data/spec/aws-must-templates/Ec2PublicIp/Ec2PublicIp_spec.rb +68 -0
  27. data/spec/aws-must-templates/Ec2Routes/Ec2Routes_spec.rb +69 -0
  28. data/spec/aws-must-templates/Ec2SecurityGroups/Ec2SecurityGroups_spec.rb +151 -0
  29. data/spec/aws-must-templates/Ec2StatusNormal/Ec2StatusNormal_spec.rb +55 -0
  30. data/spec/aws-must-templates/NetworkCanPing/NetworkCanPing_spec.rb +36 -0
  31. data/spec/aws-must-templates/ParameterTest/ParameterTest_spec.rb +17 -1
  32. data/spec/aws-must-templates/RespondsToPing/RespondsToPing_spec.rb +46 -0
  33. data/spec/aws-must-templates/S3NoAccess/S3NoAccess_spec.rb +17 -3
  34. data/spec/aws-must-templates/S3ReadAccessAllowed/S3ReadAccessAllowed_spec.rb +18 -1
  35. data/spec/aws-must-templates/Stack/Stack_spec.rb +28 -1
  36. data/spec/aws-must-templates/ValidOSVersion/ValidOSVersion_spec.rb +16 -1
  37. data/spec/aws-must-templates/Vpc/vpc_spec.rb +51 -0
  38. data/spec/aws-must-templates/table_of_content.mustache +67 -0
  39. data/spec/lib/test_suites_spec.rb +101 -28
  40. data/spec/mustache/commonDependsOn_spec.rb +57 -2
  41. data/spec/mustache/commonInstanceType_spec.rb +1 -1
  42. data/spec/mustache/mappingAmazonVpcNat_spec.rb +56 -0
  43. data/spec/mustache/mapping_spec.rb +48 -7
  44. data/spec/mustache/resourceInstance_spec.rb +102 -1
  45. data/spec/mustache/resourceInternetGateway_spec.rb +14 -9
  46. data/spec/mustache/resourcePolicy_spec.rb +1 -1
  47. data/spec/mustache/resourceS3Bucket_spec.rb +1 -1
  48. data/spec/mustache/resourceSecurityGroup_spec.rb +3 -3
  49. data/spec/mustache/resourceSubnet_spec.rb +50 -3
  50. data/spec/support/lib/aws/aws.rb +6 -0
  51. data/spec/support/lib/aws/ec2_resource.rb +177 -0
  52. data/spec/support/lib/aws/mixin_cidr.rb +18 -0
  53. data/spec/support/lib/aws/mixin_ec2.rb +53 -0
  54. data/spec/support/lib/aws/mixin_security_group.rb +15 -0
  55. data/spec/support/lib/aws/mixin_subnet.rb +77 -0
  56. data/spec/support/lib/aws/mixin_vpc.rb +10 -0
  57. data/spec/support/lib/aws/route_resource.rb +86 -0
  58. data/spec/support/lib/aws/security_group_resource.rb +120 -0
  59. data/spec/support/lib/aws/vpc_resource.rb +69 -0
  60. data/spec/support/lib/suite_value.rb +38 -0
  61. data/spec/support/lib/test_parameter.rb +12 -8
  62. data/spec/support/lib/valid_property.rb +29 -9
  63. data/spec/support/spec_helper.rb +75 -44
  64. data/spec/support/utils.rb +4 -0
  65. metadata +34 -24
@@ -0,0 +1,86 @@
1
+ require 'aws-sdk'
2
+ require 'serverspec'
3
+
4
+
5
+
6
+ module Serverspec
7
+ module Type
8
+ class AwsRoute < Base
9
+
10
+ # ------------------------------------------------------------------
11
+ # attrbutes
12
+
13
+ attr_accessor :instanceName # tagged
14
+
15
+
16
+ # ------------------------------------------------------------------
17
+ # constrcutore
18
+
19
+ def self.new_for_ec2( instanceName )
20
+ raise "must set a 'instanceName' " unless instanceName
21
+
22
+ awsRoute = AwsRoute.new
23
+ awsRoute.instanceName = instanceName
24
+ return awsRoute
25
+ end
26
+
27
+ def initialize
28
+ end
29
+
30
+ # ------------------------------------------------------------------
31
+ # public interface
32
+
33
+ def to_s
34
+ "awsRoute: " +
35
+ ( @instanceName ? " instanceName=#{@instanceName}" : "" )
36
+ end
37
+
38
+
39
+ def subnet_routes
40
+ subnetId = describe_instance.subnet_id
41
+ subnet_routes_as_array_of_hashes( subnetId )
42
+ end
43
+
44
+
45
+ private
46
+
47
+ # ------------------------------------------------------------------
48
+ # mixin interface
49
+
50
+ def client
51
+ @ec2Client = Aws::EC2::Client.new
52
+ return @ec2Client
53
+ end
54
+
55
+ def get_instanceId
56
+ return @instanceId if @instanceId
57
+ options = {
58
+ dry_run: false,
59
+ filters: [
60
+ { name: "tag:Name", values: [ instanceName ]},
61
+ { name: "instance-state-name", values: [ "running" ]},
62
+ ],
63
+ }
64
+
65
+ @instanceId = describe_instances(options).reservations.first.instances.first.instance_id
66
+ return @instanceId
67
+ end
68
+
69
+ # ------------------------------------------------------------------
70
+ # mixin services included
71
+
72
+ include AwsMustTemplates::Mixin::EC2
73
+ include AwsMustTemplates::Mixin::Subnet
74
+
75
+ end # class Vpc < Base
76
+
77
+ def route_resource_for_ec2( instanceName )
78
+ AwsRoute.new_for_ec2( instanceName.kind_of?(Serverspec::Type::ValidProperty) ? instanceName.value : instanceName )
79
+ end
80
+
81
+
82
+ end # module Type
83
+ end
84
+
85
+ include Serverspec::Type
86
+
@@ -0,0 +1,120 @@
1
+ require 'aws-sdk'
2
+ require 'serverspec'
3
+
4
+ require_relative "./mixin_security_group"
5
+
6
+ module Serverspec
7
+ module Type
8
+ class SecurityGroup < Base
9
+
10
+ # ------------------------------------------------------------------
11
+ # attrbutes
12
+
13
+ attr_accessor :instanceName # ec2 tagged with 'Name' = @instanceName
14
+
15
+
16
+ # ------------------------------------------------------------------
17
+ # constrcutore
18
+
19
+ def self.new_for_ec2( instanceName )
20
+ raise "must set a 'instanceName' " unless instanceName
21
+
22
+ sg = SecurityGroup.new
23
+ sg.instanceName = instanceName
24
+ return sg
25
+ end
26
+
27
+ def initialize
28
+ end
29
+
30
+ # ------------------------------------------------------------------
31
+ # public interface
32
+
33
+ def to_s
34
+ "Security group: " +
35
+ ( @instanceName ? " instanceName=#{@instanceName}" : "" )
36
+ end
37
+
38
+ # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html#security-group-rules
39
+ # Security group rules are always permissive; you can't create
40
+ # rules that deny access.
41
+ def instance_ingress_rules
42
+ instance_security_group_ip_permissions
43
+ end
44
+
45
+ def instance_egress_rules
46
+ instance_security_group_ip_permissions_egress
47
+ end
48
+
49
+ private
50
+
51
+ # collect all ingress permissions to an array
52
+ def instance_security_group_ip_permissions
53
+ ret = [];
54
+ describe_security_groups(instance_security_group_ids).
55
+ inject( ret ){ |ret,group|
56
+ group.ip_permissions.each{ |ip_permission| ret << ip_permission.to_h }}
57
+ return ret
58
+ end
59
+
60
+ # collect all egress permissions to an array
61
+ def instance_security_group_ip_permissions_egress
62
+ ret = [];
63
+ describe_security_groups(instance_security_group_ids).
64
+ inject( ret ){ |ret,group|
65
+ group.ip_permissions_egress.each{ |ip_permission_egress| ret << ip_permission_egress.to_h }}
66
+ return ret
67
+ end
68
+
69
+
70
+ # security group ids for an instance
71
+ def instance_security_group_ids
72
+ instance_security_groups.map{ |group| group.group_id }
73
+ end
74
+
75
+
76
+ # for an instance
77
+ def instance_security_groups
78
+ describe_instance.security_groups
79
+ end
80
+
81
+
82
+ # ------------------------------------------------------------------
83
+ # mixin interface
84
+
85
+ def client
86
+ @ec2Client = Aws::EC2::Client.new
87
+ return @ec2Client
88
+ end
89
+
90
+ def get_instanceId
91
+ return @instanceId if @instanceId
92
+ options = {
93
+ dry_run: false,
94
+ filters: [
95
+ { name: "tag:Name", values: [ instanceName ]},
96
+ { name: "instance-state-name", values: [ "running" ]},
97
+ ],
98
+ }
99
+
100
+ @instanceId = describe_instances(options).reservations.first.instances.first.instance_id
101
+ return @instanceId
102
+ end
103
+
104
+ # ------------------------------------------------------------------
105
+ # mixin services included
106
+
107
+ include AwsMustTemplates::Mixin::EC2
108
+ include AwsMustTemplates::Mixin::SecurityGroup
109
+
110
+ end # class Vpc < Base
111
+
112
+ def security_group_resource_for_ec2( instanceName )
113
+ SecurityGroup.new_for_ec2( instanceName.kind_of?(Serverspec::Type::ValidProperty) ? instanceName.value : instanceName )
114
+ end
115
+
116
+ end # module Type
117
+ end
118
+
119
+ include Serverspec::Type
120
+
@@ -0,0 +1,69 @@
1
+ require 'aws-sdk'
2
+ require 'serverspec'
3
+
4
+
5
+
6
+ module Serverspec
7
+ module Type
8
+
9
+ class VpcResource < Base
10
+
11
+ def initialize( vpcName )
12
+ raise "must set a 'vpcName' " unless vpcName
13
+ @vpcName = vpcName
14
+ end
15
+
16
+ def to_s
17
+ "vpc: '#{@vpcName}'"
18
+ end
19
+
20
+ def is_default?
21
+ return describe_vpc.is_default
22
+ end
23
+
24
+ # convinience routine to check value of state
25
+ def is_available?
26
+ return state == "available"
27
+ end
28
+
29
+ # String, one of "pending", "available"
30
+ def state
31
+ return describe_vpc.state
32
+ end
33
+
34
+ private
35
+
36
+ def client
37
+ @ec2Client = Aws::EC2::Client.new
38
+ return @ec2Client
39
+ end
40
+
41
+ def describe_vpc
42
+ vpcs = describe_vpcs
43
+ # vpc tagged `Name`== @vpcName
44
+ vpc = vpcs.vpcs.select {|vpc| vpc.tags.select{ |tag| tag['key'] == 'Name' && tag['value'] == @vpcName }.any? }.first
45
+ raise "No vpc tagged 'Name'='#{@vpcName}'" if vpc.nil?
46
+ return vpc
47
+ end
48
+
49
+ # read all vpc
50
+ def describe_vpcs
51
+ options = {
52
+ dry_run: false,
53
+ }
54
+ client.describe_vpcs( options )
55
+ end
56
+
57
+
58
+ end # class Vpc < Base
59
+
60
+ def vpc_resource_by_name( vpcName )
61
+ VpcResource.new( vpcName )
62
+ end
63
+
64
+
65
+ end # module Type
66
+ end
67
+
68
+ include Serverspec::Type
69
+
@@ -0,0 +1,38 @@
1
+ module Serverspec
2
+ module Type
3
+
4
+ class SuiteValue < ValidProperty
5
+
6
+ VALID_VALUES = [ :host,
7
+ :instance_name,
8
+ :stack_id,
9
+ :suite_id
10
+ ]
11
+
12
+ def initialize(key)
13
+ raise <<-EOS unless VALID_VALUES.include?(key)
14
+ Invalid suite value #{key}
15
+
16
+ Valid values #{VALID_VALUES.join( ', ')}
17
+ EOS
18
+ keys = []
19
+ keys << key
20
+ @key = key
21
+ super( keys )
22
+ end
23
+
24
+ def to_s
25
+ "Suite value '#{@key}'"
26
+ end
27
+
28
+ end # class
29
+
30
+ def suite_value( key )
31
+ SuiteValue.new( key )
32
+ end
33
+
34
+ end
35
+ end
36
+
37
+ include Serverspec::Type
38
+
@@ -3,7 +3,7 @@ module Serverspec
3
3
 
4
4
  class TestParameter < ValidProperty
5
5
 
6
- def initialize( role_id, test_parameter_name )
6
+ def initialize( role_id, test_parameter_name, mandatory )
7
7
 
8
8
  keys = ["Roles"]
9
9
  keys << role_id
@@ -12,9 +12,10 @@ module Serverspec
12
12
  @role_id = role_id
13
13
  @test_parameter_name = test_parameter_name
14
14
 
15
- super( keys )
15
+ super( keys )
16
+
17
+ validate if mandatory
16
18
 
17
- validate
18
19
  end
19
20
 
20
21
  # rpsec description text
@@ -24,18 +25,18 @@ module Serverspec
24
25
 
25
26
  # error string
26
27
  def to_error_s
27
- "Test paramater '#{@test_parameter_name}' configuration error in suite '#{ @runner.property[:suite_id]}' test '#{@role_id}'"
28
+ "Test paramater '#{@test_parameter_name}' configuration error in suite '#{ @runner.property[:suite_id]}' #{ @runner.property[:instance_name] ? 'instance \'' + @runner.property[:instance_name] + '\'' : ' common ' } test '#{@role_id}' "
28
29
  end
29
30
 
30
31
  # definition in test_suite.yaml (nil if not defined)
31
32
  def definition_in_test_suite
32
- self.class.superclass.instance_method(:value).bind(self).call
33
+ self.class.superclass.instance_method(:defined?).bind(self).call
33
34
  # method( :value ).super_method.call
34
35
  end
35
36
 
36
37
  # exception unless definition ok
37
38
  def validate
38
- raise to_error_s unless definition_in_test_suite
39
+ raise to_error_s unless definition_in_test_suite
39
40
  end
40
41
 
41
42
  # evaluated value
@@ -45,16 +46,19 @@ module Serverspec
45
46
  end
46
47
 
47
48
  private
49
+
50
+ # value starts with '@' --> lookup in 'properties'
48
51
  def param_evaluate( val )
49
52
  return val if val.nil?
53
+ return val if !!val == val
50
54
  return val unless val[0] == "@"
51
55
  return resolve_value_for_keys( val[1..-1].split( '.' ) )
52
56
  end
53
57
 
54
58
  end # class
55
59
 
56
- def test_parameter( role_id, test_parameter_name )
57
- TestParameter.new( role_id, test_parameter_name )
60
+ def test_parameter( role_id, test_parameter_name, mandatory=true )
61
+ TestParameter.new( role_id, test_parameter_name, mandatory )
58
62
  end
59
63
 
60
64
  end
@@ -17,37 +17,57 @@ module Serverspec
17
17
  @value
18
18
  end
19
19
 
20
+ # key exist (may be nil)
20
21
  # RSpec document output
21
22
  def to_s
22
23
  "property with keys #{@keys}" # + " in @runner.property= #{@runner.property}"
23
24
  end
24
25
 
25
- # return value for '@runner.property'
26
- def resolve_value_for_keys( keys )
27
-
28
- props = @runner.property
26
+ # yield block for final value iterating 'keys' in 'props'
27
+ def iterate_keys(keys, props )
29
28
 
30
29
  # iterate keys
31
- keys.each do |k|
30
+ keys.each_with_index do |k,index|
32
31
  # puts "Prrops=#{props}, k=#{k}"
33
32
  if props.nil? then
34
33
  # fixed point reached
35
34
  props = nil
36
35
  elsif props.is_a?( Hash ) then
37
36
  # recurse down a hash
38
- props = props[k]
37
+ # props = props[k]
38
+ if index == (keys.size() -1 ) then
39
+ props = yield props, k
40
+ else
41
+ props = props[k]
42
+ end
39
43
  elsif props.is_a?( Array ) then
40
44
  # choose hash with a matching key from an array
41
- props = props.select{ |e| e.is_a?(Hash) && e.keys.first == k }.first
42
- props = props[k] if props
45
+ # props = props.select{ |e| e.is_a?(Hash) && e.keys.first == k }.first
46
+ props = props.select{ |e| e.is_a?(Hash) && e.keys.include?(k) }.first
47
+ if props then
48
+ if index == (keys.size() -1) then
49
+ props = yield props, k
50
+ else
51
+ props = props[k]
52
+ end
53
+ # props = props[k]
54
+ end
43
55
  else
44
56
  # unknown case
45
57
  props = nil
46
58
  end
47
59
  end
48
-
49
60
  return props
61
+ end
50
62
 
63
+ # is last key defined (value maybe whatever)
64
+ def defined?
65
+ iterate_keys( @keys, @runner.property) { |hash,key| hash.has_key?(key) }
66
+ end
67
+
68
+ # return value for 'keys' in '@runner.property'
69
+ def resolve_value_for_keys( keys )
70
+ iterate_keys( keys, @runner.property) { |hash,key| hash[key] }
51
71
  end
52
72
 
53
73
  end
@@ -8,7 +8,68 @@ require_relative "./utils.rb"
8
8
  # test-suites interface
9
9
  require_relative "../../lib/test-suites/test_suites.rb"
10
10
 
11
- # load test-suites.yaml
11
+
12
+ # ------------------------------------------------------------------
13
+ # Constants
14
+
15
+ describe_stacks_command =
16
+ "aws cloudformation describe-stacks" # read json using aws cli
17
+
18
+ # SSH client configuration to use
19
+ ssh_config_file = "ssh/config.aws"
20
+ # file to use
21
+ # stack states
22
+
23
+ SUCESS_STATES = ["CREATE_COMPLETE", "UPDATE_COMPLETE"]
24
+ FAILURE_STATES = ["CREATE_FAILED", "DELETE_FAILED", "UPDATE_ROLLBACK_FAILED", "ROLLBACK_FAILED", "ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"]
25
+ END_STATES = SUCESS_STATES + FAILURE_STATES
26
+
27
+
28
+ # return ssh options for 'hostname_for_instance'
29
+ def read_ssh_options( instance_name, ssh_config_file, options_init )
30
+
31
+
32
+ raise <<-EOS unless File.exist?( ssh_config_file )
33
+
34
+ Could not find ssh configuration file in '#{ssh_config_file}'.
35
+
36
+ Serverspec uses ssh to connect to #{instance_name}, but no configuration found!
37
+
38
+ EOS
39
+
40
+
41
+ # start search for an instance id
42
+ # puts "read_ssh_options: instance_name:#{instance_name}"
43
+ host = instance_name
44
+
45
+ options = Net::SSH::Config.for( host, [ ssh_config_file ] )
46
+ # puts "read_ssh_options: host:#{host} --> options#{options}"
47
+ # options[:verbose] = :info # :debug, :info, :warn, :error, :fatal
48
+
49
+ # mapped to another name?
50
+ if options[:host_name] then
51
+ host = options[:host_name]
52
+ options2 = Net::SSH::Config.for( host, [ ssh_config_file ] )
53
+ # puts "read_ssh_options: host:#{host} --> options2#{options2}"
54
+ if options2[:proxy] then
55
+ # use proxy - if defined
56
+ options = options2
57
+ # keep original host_name where to connect
58
+ options[:host_name] = host
59
+ end
60
+ end
61
+
62
+ # puts "read_ssh_options: result host:#{host} --> options#{options}"
63
+ return options
64
+
65
+ end
66
+
67
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
68
+ # Main
69
+
70
+ # ------------------------------------------------------------------
71
+ # load test-suites.yaml to an object
72
+
12
73
  test_suites = AwsMustTemplates::TestSuites::TestSuites.new
13
74
 
14
75
  # ------------------------------------------------------------------
@@ -31,31 +92,14 @@ end
31
92
  # suite.rake sets target ENV for suite and instance id
32
93
 
33
94
  suite_id = ENV['TARGET_SUITE_ID'] # test suite being processed
34
- instance_id = ENV['TARGET_INSTANCE_ID'] # instance being tested (if any)
95
+ instance_name = ENV['TARGET_INSTANCE_NAME'] # instance being tested (if any)
35
96
 
36
97
  # map suite_id to stack_id
37
98
  stack_id = test_suites.get_suite_stack_id( suite_id )
38
99
 
39
100
  puts "------------------------------------------------------------------"
40
- puts "instance_id #{instance_id}" if instance_id
41
-
42
- # ------------------------------------------------------------------
43
- # Constants used in stack
44
-
45
- output_key_for_hostname = instance_id # Stack Output variable for
46
- # ip/hostname for the instance
47
-
48
- describe_stacks_command =
49
- "aws cloudformation describe-stacks" # read json using aws cli
101
+ puts "instance_name #{instance_name}" if instance_name
50
102
 
51
- # SSH client configuration must be in CWD (=user directory)
52
- ssh_config_file = "ssh/config"
53
- # file to use
54
- # stack states
55
-
56
- SUCESS_STATES = ["CREATE_COMPLETE", "UPDATE_COMPLETE"]
57
- FAILURE_STATES = ["CREATE_FAILED", "DELETE_FAILED", "UPDATE_ROLLBACK_FAILED", "ROLLBACK_FAILED", "ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"]
58
- END_STATES = SUCESS_STATES + FAILURE_STATES
59
103
 
60
104
  # ------------------------------------------------------------------
61
105
  # access cloudformation stacks using aws cli
@@ -78,19 +122,16 @@ EOS
78
122
 
79
123
  raise "Stack '#{stack_id}' status='#{stack_json["StackStatus"]} is not ready (=#{SUCESS_STATES}) '" unless SUCESS_STATES.include?( stack_json["StackStatus"] )
80
124
 
81
- if instance_id then
82
- # find output parameter defining hostname (or ip address)
83
- hostname_in_stack=stack_json["Outputs"].select {|a| a["OutputKey"] == output_key_for_hostname }.first["OutputValue"]
84
- raise "Could not find OutputKey '#{output_key_for_hostname}' in stack '#{stack}' for instance_id '#{instance_id}'" unless hostname_in_stack
85
- end
125
+ # ------------------------------------------------------------------
126
+ # hash in accessible in spec tests with name 'property'
86
127
 
87
- # create a hash, which is accessible in spec tests are 'property'
88
128
  properties = {
89
129
  "Outputs" => stack_json["Outputs"] ? stack_json["Outputs"].inject( {} ) { |r,e| r[e["OutputKey"]] = e["OutputValue"] ; r } : {},
90
130
  "Parameters" => stack_json["Parameters"] ? stack_json["Parameters"].inject( {} ) { |r,e| r[e["ParameterKey"]] = e["ParameterValue"] ; r }: {},
91
131
  # Roles for test (from instance or from common suites)
92
- "Roles" => ( instance_id ? test_suites.suite_instance_roles( suite_id, instance_id ) : test_suites.suite_roles( suite_id ) ),
93
- :host => instance_id,
132
+ "Roles" => ( instance_name ? test_suites.suite_instance_roles( suite_id, instance_name ) : test_suites.suite_roles( suite_id ) ),
133
+ :host => instance_name,
134
+ :instance_name => instance_name,
94
135
  :stack_id => stack_id,
95
136
  :suite_id=> suite_id,
96
137
  }
@@ -104,25 +145,13 @@ set_property properties
104
145
 
105
146
  # CloudFormatio instance resources are defined in 'ssh_config_file'
106
147
 
107
- raise <<-EOS unless File.exist?( ssh_config_file )
108
-
109
- Could not find ssh configuration file in '#{ssh_config_file}'.
110
-
111
- Serverspec uses ssh to connect to #{instance_id}, but no configuration found!
112
-
113
- EOS
114
-
115
- options = Net::SSH::Config.for(instance_id, [ ssh_config_file ] )
116
- # puts "instance_id #{instance_id}, options=#{options}"
117
-
118
- # use ip host_name to access stack resource `instance_id`
119
- options[:host_name] = hostname_in_stack
148
+ options = read_ssh_options( instance_name, ssh_config_file, {} )
149
+ # puts "instance_name #{instance_name}--> options=#{options}"
120
150
 
121
- options[:user] ||= Etc.getlogin
122
-
123
- set :host, options[:host_name] || instance_id
151
+ set :host, options[:host_name]# || instance_name
124
152
  set :ssh_options, options
125
153
 
154
+ set :request_pty, true
126
155
  # Disable sudo
127
156
  # set :disable_sudo, true
128
157
 
@@ -132,3 +161,5 @@ set :ssh_options, options
132
161
 
133
162
  # Set PATH
134
163
  # set :path, '/sbin:/usr/local/sbin:$PATH'
164
+
165
+
@@ -3,4 +3,8 @@ require_relative "lib/valid_property.rb"
3
3
  require_relative "lib/stack_output.rb"
4
4
  require_relative "lib/stack_parameter.rb"
5
5
  require_relative "lib/test_parameter.rb"
6
+ require_relative "lib/suite_value.rb"
7
+
8
+ # AWS
9
+ require_relative 'lib/aws/aws'
6
10