aws-must-templates 0.1.6 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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