awspec 1.24.1 → 1.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +69 -0
  3. data/.github/workflows/doc.yml +29 -0
  4. data/.rubocop.yml +47 -2
  5. data/Gemfile +2 -0
  6. data/README.md +2 -4
  7. data/Rakefile +0 -1
  8. data/awspec.gemspec +3 -5
  9. data/doc/_resource_types/cloudwatch_logs.md +9 -0
  10. data/doc/_resource_types/eks_nodegroup.md +53 -0
  11. data/doc/resource_types.md +62 -9
  12. data/lib/awspec/command/generate.rb +1 -1
  13. data/lib/awspec/generator/spec/cloudwatch_logs.rb +5 -1
  14. data/lib/awspec/generator/spec/elasticache.rb +43 -0
  15. data/lib/awspec/generator.rb +1 -0
  16. data/lib/awspec/helper/finder/ec2.rb +41 -16
  17. data/lib/awspec/helper/finder/ecs.rb +1 -1
  18. data/lib/awspec/helper/finder/subnet.rb +118 -20
  19. data/lib/awspec/helper/finder.rb +6 -0
  20. data/lib/awspec/helper/states.rb +16 -0
  21. data/lib/awspec/matcher/belong_to_subnets.rb +14 -0
  22. data/lib/awspec/matcher/have_metric_filter.rb +9 -0
  23. data/lib/awspec/matcher.rb +4 -0
  24. data/lib/awspec/setup.rb +1 -1
  25. data/lib/awspec/stub/cloudwatch_logs.rb +2 -1
  26. data/lib/awspec/stub/ec2_non_existing.rb +7 -0
  27. data/lib/awspec/stub/eks_nodegroup.rb +61 -1
  28. data/lib/awspec/stub/elasticsearch.rb +0 -1
  29. data/lib/awspec/stub/rds_db_parameter_group.rb +8 -0
  30. data/lib/awspec/stub/sns_topic.rb +15 -8
  31. data/lib/awspec/stub/sns_topic_error.rb +13 -0
  32. data/lib/awspec/type/cloudwatch_logs.rb +8 -3
  33. data/lib/awspec/type/ec2.rb +21 -16
  34. data/lib/awspec/type/eks_nodegroup.rb +105 -0
  35. data/lib/awspec/type/rds_db_parameter_group.rb +54 -0
  36. data/lib/awspec/type/s3_bucket.rb +1 -1
  37. data/lib/awspec/version.rb +1 -1
  38. metadata +26 -20
  39. data/.tachikoma.yml +0 -1
  40. data/.travis.yml +0 -23
@@ -1,4 +1,3 @@
1
-
2
1
  Aws.config[:elasticsearchservice] = {
3
2
  stub_responses: {
4
3
  list_domain_names: {
@@ -13,6 +13,14 @@ Aws.config[:rds] = {
13
13
  {
14
14
  parameter_name: 'max_allowed_packet',
15
15
  parameter_value: '16777216'
16
+ },
17
+ {
18
+ parameter_name: 'rds.logical_replication',
19
+ parameter_value: '1'
20
+ },
21
+ {
22
+ parameter_name: 'rds.accepted_password_auth_method',
23
+ parameter_value: 'md5+scram'
16
24
  }
17
25
  ]
18
26
  }
@@ -1,26 +1,33 @@
1
+ OWNER = '123456789'
2
+ REGION = 'us-east-1'
3
+ TOPIC_ARN = "arn:aws:sns:#{REGION}:#{OWNER}:foobar"
4
+ DISPLAY_NAME = 'Useless'
5
+ SUBSCRIBED = "arn:aws:sns:#{REGION}:#{OWNER}:Foobar:3dbf4999-b3e2-4345-bd11-c34c9784ecca"
6
+ ENDPOINT = "arn:aws:lambda:#{REGION}:#{OWNER}:function:foobar"
7
+
1
8
  Aws.config[:sns] = {
2
9
  stub_responses: {
3
10
  get_topic_attributes: {
4
11
  attributes: {
5
12
  # rubocop:disable LineLength
6
- 'Policy' => '{\"Version\":\"2008-10-17\",\"Id\":\"__default_policy_ID\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:GetTopicAttributes\",\"SNS:SetTopicAttributes\",\"SNS:AddPermission\",\"SNS:RemovePermission\",\"SNS:DeleteTopic\",\"SNS:Subscribe\",\"SNS:ListSubscriptionsByTopic\",\"SNS:Publish\",\"SNS:Receive\"],\"Resource\":\"arn:aws:sns:us-east-1:123456789:foobar-lambda-sample\",\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"123456789\"}}}]}',
7
- 'Owner' => '123456789',
13
+ 'Policy' => "{\"Version\":\"2008-10-17\",\"Id\":\"__default_policy_ID\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:GetTopicAttributes\",\"SNS:SetTopicAttributes\",\"SNS:AddPermission\",\"SNS:RemovePermission\",\"SNS:DeleteTopic\",\"SNS:Subscribe\",\"SNS:ListSubscriptionsByTopic\",\"SNS:Publish\",\"SNS:Receive\"],\"Resource\":\"arn:aws:sns:#{REGION}:#{OWNER}:foobar-lambda-sample\",\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"#{OWNER}\"}}}]}",
14
+ 'Owner' => OWNER,
8
15
  'SubscriptionsPending' => '0',
9
- 'TopicArn' => 'arn:aws:sns:us-east-1:123456789:foobar',
16
+ 'TopicArn' => TOPIC_ARN,
10
17
  'EffectiveDeliveryPolicy' => '{\"http\":{\"defaultHealthyRetryPolicy\":{\"minDelayTarget\":20,\"maxDelayTarget\":20,\"numRetries\":3,\"numMaxDelayRetries\":0,\"numNoDelayRetries\":0,\"numMinDelayRetries\":0,\"backoffFunction\":\"linear\"},\"disableSubscriptionOverrides\":false}}',
11
18
  'SubscriptionsConfirmed' => '1',
12
- 'DisplayName' => 'Useless',
19
+ 'DisplayName' => DISPLAY_NAME,
13
20
  'SubscriptionsDeleted' => '0'
14
21
  }
15
22
  },
16
23
  list_subscriptions_by_topic: {
17
24
  subscriptions: [
18
25
  {
19
- subscription_arn: 'arn:aws:sns:us-east-1:123456789:Foobar:3dbf4999-b3e2-4345-bd11-c34c9784ecca',
20
- owner: '123456789',
26
+ subscription_arn: SUBSCRIBED,
27
+ owner: OWNER,
21
28
  protocol: 'lambda',
22
- endpoint: 'arn:aws:lambda:us-east-1:123456789:function:foobar',
23
- topic_arn: 'arn:aws:sns:us-east-1:123456789:foobar'
29
+ endpoint: ENDPOINT,
30
+ topic_arn: TOPIC_ARN
24
31
  }
25
32
  ],
26
33
  next_token: nil
@@ -0,0 +1,13 @@
1
+ OWNER = '123456789'
2
+ REGION = 'us-east-1'
3
+ TOPIC_ARN = "arn:aws:sns:#{REGION}:#{OWNER}:invalid"
4
+ TOPIC_SUBS_ARN = "arn:aws:sns:us-east-1:#{OWNER}:Foobar:3dbf4999-b3e2-4345-bd11-c34c9784ecca"
5
+
6
+ Aws.config[:sns] = {
7
+ stub_responses: {
8
+ get_topic_attributes: Aws::SNS::Errors::NotFound.new(
9
+ TOPIC_ARN, 'no such topic'),
10
+ list_subscriptions_by_topic: Aws::SNS::Errors::NotFound.new(
11
+ TOPIC_SUBS_ARN, 'no such topic')
12
+ }
13
+ }
@@ -13,9 +13,14 @@ module Awspec::Type
13
13
  return true if ret == stream_name
14
14
  end
15
15
 
16
- def has_metric_filter?(filter_name)
17
- ret = find_cloudwatch_logs_metric_fileter_by_log_group_name(@id, filter_name).filter_name
18
- return true if ret == filter_name
16
+ def has_metric_filter?(filter_name, pattern = nil)
17
+ ret = find_cloudwatch_logs_metric_fileter_by_log_group_name(@id, filter_name)
18
+ if pattern.nil?
19
+ return true if ret.filter_name == filter_name
20
+ else
21
+ return false unless ret.filter_pattern == pattern
22
+ end
23
+ return true if ret.filter_name == filter_name
19
24
  end
20
25
 
21
26
  def has_subscription_filter?(filter_name, pattern = nil)
@@ -1,3 +1,5 @@
1
+ require 'awspec/helper/states'
2
+
1
3
  module Awspec::Type
2
4
  class Ec2 < ResourceBase
3
5
  aws_resource Aws::EC2::Instance
@@ -8,6 +10,16 @@ module Awspec::Type
8
10
  @display_name = name
9
11
  end
10
12
 
13
+ # required by Awspec::Generator::Doc::Type
14
+ STATES = Awspec::Helper::States::EC2_STATES
15
+
16
+ Awspec::Helper::States.ec2_states_checks.each do |method_name, state|
17
+ define_method method_name do
18
+ check_existence
19
+ resource_via_client.state.name == state
20
+ end
21
+ end
22
+
11
23
  def resource_via_client
12
24
  @resource_via_client ||= find_ec2(@display_name)
13
25
  end
@@ -17,20 +29,10 @@ module Awspec::Type
17
29
  end
18
30
 
19
31
  def security_group_count
32
+ check_existence
20
33
  resource_via_client.security_groups.count
21
34
  end
22
35
 
23
- STATES = %w(
24
- pending running shutting-down
25
- terminated stopping stopped
26
- )
27
-
28
- STATES.each do |state|
29
- define_method state.tr('-', '_') + '?' do
30
- resource_via_client.state.name == state
31
- end
32
- end
33
-
34
36
  def disabled_api_termination?
35
37
  ret = find_ec2_attribute(id, 'disableApiTermination')
36
38
  ret.disable_api_termination.value
@@ -48,7 +50,6 @@ module Awspec::Type
48
50
 
49
51
  def has_security_groups?(sg_ids)
50
52
  return true if match_group_ids?(sg_ids) || match_group_names?(sg_ids)
51
-
52
53
  group_ids = resource_security_groups.map { |sg| sg.group_id }
53
54
  tags = select_security_group_by_group_id(group_ids).map { |sg| sg.tags }.flatten
54
55
  group_names = tags.select { |tag| tag.key == 'Name' }.map { |tag| tag.value }
@@ -56,6 +57,7 @@ module Awspec::Type
56
57
  end
57
58
 
58
59
  def has_security_group?(sg_id)
60
+ check_existence
59
61
  sgs = resource_via_client.security_groups
60
62
  ret = sgs.find do |sg|
61
63
  sg.group_id == sg_id || sg.group_name == sg_id
@@ -69,12 +71,14 @@ module Awspec::Type
69
71
  end
70
72
 
71
73
  def has_iam_instance_profile?(iam_instance_profile_name)
74
+ check_existence
72
75
  iam = resource_via_client.iam_instance_profile
73
76
  ret = iam.arn.split('/').last == iam_instance_profile_name
74
77
  return true if ret
75
78
  end
76
79
 
77
80
  def has_ebs?(volume_id)
81
+ check_existence
78
82
  blocks = resource_via_client.block_device_mappings
79
83
  ret = blocks.find do |block|
80
84
  next false unless block.ebs
@@ -89,8 +93,9 @@ module Awspec::Type
89
93
 
90
94
  def has_network_interface?(network_interface_id, device_index = nil)
91
95
  res = find_network_interface(network_interface_id)
96
+ check_existence
92
97
  interfaces = resource_via_client.network_interfaces
93
- interfaces.find do |interface|
98
+ ret = interfaces.find do |interface|
94
99
  next false if device_index && interface.attachment.device_index != device_index
95
100
  interface.network_interface_id == res.network_interface_id
96
101
  end
@@ -98,7 +103,7 @@ module Awspec::Type
98
103
 
99
104
  def has_event?(event_code)
100
105
  status = find_ec2_status(id)
101
- status.events.find do |event|
106
+ ret = status.events.find do |event|
102
107
  event.code == event_code
103
108
  end
104
109
  end
@@ -133,8 +138,7 @@ module Awspec::Type
133
138
  end
134
139
 
135
140
  def has_credit_specification?(cpu_credits)
136
- ret = find_ec2_credit_specifications(id)
137
- ret.cpu_credits == cpu_credits
141
+ find_ec2_credit_specifications(id).cpu_credits == cpu_credits
138
142
  end
139
143
 
140
144
  private
@@ -148,6 +152,7 @@ module Awspec::Type
148
152
  end
149
153
 
150
154
  def resource_security_groups
155
+ check_existence
151
156
  resource_via_client.security_groups
152
157
  end
153
158
  end
@@ -1,10 +1,47 @@
1
+ require 'set'
2
+
1
3
  module Awspec::Type
4
+ class EksNodeEC2
5
+ attr_reader :state, :subnet_id, :sec_groups
6
+
7
+ def initialize(id, state, subnet_id, sec_groups)
8
+ @id = id
9
+ @state = state
10
+ @subnet_id = subnet_id
11
+ @sec_groups = sec_groups
12
+ end
13
+
14
+ def to_s
15
+ "ID: #{@id}, State: #{@state}, Subnet ID: #{@subnet_id}, Security Groups: #{@sec_groups}"
16
+ end
17
+ end
18
+
19
+ class EksNodeSecGroup
20
+ attr_reader :name, :id
21
+
22
+ def initialize(id, name)
23
+ @id = id
24
+ @name = name
25
+ end
26
+
27
+ def to_s
28
+ "ID: #{@id}, Name: #{@name}"
29
+ end
30
+ end
31
+
2
32
  class EksNodegroup < ResourceBase
33
+ # the tags below are standard for EKS node groups instances
34
+ EKS_CLUSTER_TAG = 'tag:eks:cluster-name'
35
+ EKS_NODEGROUP_TAG = 'tag:eks:nodegroup-name'
36
+
3
37
  attr_accessor :cluster
4
38
 
5
39
  def initialize(group_name)
6
40
  super
7
41
  @group_name = group_name
42
+ @ec2_instances = []
43
+ @sec_groups = Set.new
44
+ @sec_groups_ids = Set.new
8
45
  end
9
46
 
10
47
  def resource_via_client
@@ -19,6 +56,39 @@ module Awspec::Type
19
56
  @cluster || 'default'
20
57
  end
21
58
 
59
+ def subnets
60
+ ec2_instances = find_nodes
61
+ Set.new(ec2_instances.map { |ec2| ec2.subnet_id })
62
+ end
63
+
64
+ def has_security_group?(sec_group)
65
+ if @sec_groups.empty? || @sec_groups_ids.empty?
66
+ ec2_instances = find_nodes
67
+
68
+ ec2_instances.each do |ec2|
69
+ ec2.sec_groups.each do |sg|
70
+ @sec_groups.add(sg.name)
71
+ @sec_groups_ids.add(sg.id)
72
+ end
73
+ end
74
+ end
75
+
76
+ @sec_groups.member?(sec_group) || @sec_groups_ids.member?(sec_group)
77
+ end
78
+
79
+ def ready?
80
+ min_expected = resource_via_client.scaling_config.min_size
81
+ ec2_instances = find_nodes
82
+ running_counter = 0
83
+
84
+ ec2_instances.each do |ec2|
85
+ running_counter += 1 if ec2.state.eql?('running')
86
+ break if running_counter == min_expected
87
+ end
88
+
89
+ running_counter >= min_expected
90
+ end
91
+
22
92
  STATES = %w(ACTIVE INACTIVE)
23
93
 
24
94
  STATES.each do |state|
@@ -26,5 +96,40 @@ module Awspec::Type
26
96
  resource_via_client.status == state
27
97
  end
28
98
  end
99
+
100
+ private
101
+
102
+ def find_nodes
103
+ return @ec2_instances unless @ec2_instances.empty?
104
+
105
+ result = ec2_client.describe_instances(
106
+ {
107
+ filters: [
108
+ { name: EKS_CLUSTER_TAG, values: [cluster] },
109
+ { name: EKS_NODEGROUP_TAG, values: [@group_name] }
110
+ ]
111
+ }
112
+ )
113
+ result.reservations.each do |reservation|
114
+ reservation.instances.each do |instance|
115
+ sec_groups = []
116
+
117
+ instance.security_groups.map do |sg|
118
+ sec_groups.push(EksNodeSecGroup.new(sg.group_id, sg.group_name))
119
+ end
120
+
121
+ @ec2_instances.push(
122
+ EksNodeEC2.new(
123
+ instance.instance_id,
124
+ instance.state.name,
125
+ instance.subnet_id,
126
+ sec_groups
127
+ )
128
+ )
129
+ end
130
+ end
131
+
132
+ @ec2_instances
133
+ end
29
134
  end
30
135
  end
@@ -1,4 +1,39 @@
1
1
  module Awspec::Type
2
+ class InvalidRdsDbParameter < StandardError
3
+ ##
4
+ # Overrides the superclass initialize method to include more information
5
+ # and default error message.
6
+ # Expected parameters:
7
+ # - parameter_name: the name of the parameter.
8
+
9
+ def initialize(parameter_name)
10
+ @param_name = parameter_name
11
+ message = "There is no such parameter \"rds.#{parameter_name}\""
12
+ super message
13
+ end
14
+ end
15
+
16
+ class RdsDBParameters
17
+ ##
18
+ # Thanks to AWS for creating parameters names like
19
+ # 'rds.accepted_password_auth_method', which would be caught as method 'rds'
20
+ # by method_missing in RdsDbParameterGroup class, this class was created
21
+ # See https://github.com/k1LoW/awspec/issues/527 for more details
22
+ def initialize(params)
23
+ @params = params
24
+ end
25
+
26
+ def to_s
27
+ return "RdsDBParameters = #{@params}"
28
+ end
29
+
30
+ def method_missing(name)
31
+ param_name = name.to_sym
32
+ return @params[param_name] if @params.include?(param_name)
33
+ raise InvalidRdsDbParameter, name
34
+ end
35
+ end
36
+
2
37
  class RdsDbParameterGroup < ResourceBase
3
38
  def resource_via_client
4
39
  return @resource_via_client if @resource_via_client
@@ -11,11 +46,30 @@ module Awspec::Type
11
46
 
12
47
  def method_missing(name)
13
48
  param_name = name.to_s
49
+ return create_rds_params if param_name == 'rds'
50
+
14
51
  if resource_via_client.include?(param_name)
15
52
  resource_via_client[param_name].to_s
16
53
  else
17
54
  super
18
55
  end
19
56
  end
57
+
58
+ private
59
+
60
+ def create_rds_params
61
+ return @rds_params if @rds_params
62
+
63
+ rds_params_keys = resource_via_client.keys.select { |key| key.to_s.start_with?('rds.') }
64
+ rds_params = {}
65
+
66
+ rds_params_keys.each do |key|
67
+ new_key = key.split('.')[-1]
68
+ rds_params[new_key.to_sym] = resource_via_client[key]
69
+ end
70
+
71
+ @rds_params = RdsDBParameters.new(rds_params)
72
+ @rds_params
73
+ end
20
74
  end
21
75
  end
@@ -108,8 +108,8 @@ module Awspec::Type
108
108
  if value.is_a?(Array)
109
109
  return false if r[key].map(&:to_h) != value
110
110
  end
111
- true
112
111
  end
112
+ true
113
113
  end
114
114
  end
115
115
 
@@ -1,3 +1,3 @@
1
1
  module Awspec
2
- VERSION = '1.24.1'
2
+ VERSION = '1.25.0'
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.24.1
4
+ version: 1.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - k1LoW
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-08 00:00:00.000000000 Z
11
+ date: 2021-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: addressable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: aws-sdk
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +136,6 @@ dependencies:
122
136
  - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: addressable
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: bundler
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -204,14 +204,14 @@ dependencies:
204
204
  requirements:
205
205
  - - "~>"
206
206
  - !ruby/object:Gem::Version
207
- version: 0.49.0
207
+ version: 0.57.0
208
208
  type: :development
209
209
  prerelease: false
210
210
  version_requirements: !ruby/object:Gem::Requirement
211
211
  requirements:
212
212
  - - "~>"
213
213
  - !ruby/object:Gem::Version
214
- version: 0.49.0
214
+ version: 0.57.0
215
215
  description: RSpec tests for your AWS resources.
216
216
  email:
217
217
  - k1lowxb@gmail.com
@@ -221,9 +221,9 @@ extensions: []
221
221
  extra_rdoc_files: []
222
222
  files:
223
223
  - ".editorconfig"
224
+ - ".github/workflows/ci.yml"
225
+ - ".github/workflows/doc.yml"
224
226
  - ".rubocop.yml"
225
- - ".tachikoma.yml"
226
- - ".travis.yml"
227
227
  - Gemfile
228
228
  - LICENSE.txt
229
229
  - README.md
@@ -435,6 +435,7 @@ files:
435
435
  - lib/awspec/generator/spec/ec2.rb
436
436
  - lib/awspec/generator/spec/efs.rb
437
437
  - lib/awspec/generator/spec/eip.rb
438
+ - lib/awspec/generator/spec/elasticache.rb
438
439
  - lib/awspec/generator/spec/elasticsearch.rb
439
440
  - lib/awspec/generator/spec/elb.rb
440
441
  - lib/awspec/generator/spec/iam_group.rb
@@ -518,6 +519,7 @@ files:
518
519
  - lib/awspec/helper/finder/vpc_endpoints.rb
519
520
  - lib/awspec/helper/finder/waf.rb
520
521
  - lib/awspec/helper/finder/wafregional.rb
522
+ - lib/awspec/helper/states.rb
521
523
  - lib/awspec/helper/type.rb
522
524
  - lib/awspec/matcher.rb
523
525
  - lib/awspec/matcher/be_allowed.rb
@@ -537,6 +539,7 @@ files:
537
539
  - lib/awspec/matcher/belong_to_nlb.rb
538
540
  - lib/awspec/matcher/belong_to_replication_group.rb
539
541
  - lib/awspec/matcher/belong_to_subnet.rb
542
+ - lib/awspec/matcher/belong_to_subnets.rb
540
543
  - lib/awspec/matcher/belong_to_vpc.rb
541
544
  - lib/awspec/matcher/have_attribute_definition.rb
542
545
  - lib/awspec/matcher/have_cluster_parameter_group.rb
@@ -548,6 +551,7 @@ files:
548
551
  - lib/awspec/matcher/have_inline_policy.rb
549
552
  - lib/awspec/matcher/have_key_policy.rb
550
553
  - lib/awspec/matcher/have_key_schema.rb
554
+ - lib/awspec/matcher/have_metric_filter.rb
551
555
  - lib/awspec/matcher/have_network_interface.rb
552
556
  - lib/awspec/matcher/have_option_group.rb
553
557
  - lib/awspec/matcher/have_origin.rb
@@ -593,6 +597,7 @@ files:
593
597
  - lib/awspec/stub/ebs.rb
594
598
  - lib/awspec/stub/ec2.rb
595
599
  - lib/awspec/stub/ec2_has_multi_security_groups.rb
600
+ - lib/awspec/stub/ec2_non_existing.rb
596
601
  - lib/awspec/stub/ecr_repository.rb
597
602
  - lib/awspec/stub/ecs.rb
598
603
  - lib/awspec/stub/ecs_cluster.rb
@@ -640,6 +645,7 @@ files:
640
645
  - lib/awspec/stub/security_group.rb
641
646
  - lib/awspec/stub/ses_identity.rb
642
647
  - lib/awspec/stub/sns_topic.rb
648
+ - lib/awspec/stub/sns_topic_error.rb
643
649
  - lib/awspec/stub/sqs.rb
644
650
  - lib/awspec/stub/ssm_parameter.rb
645
651
  - lib/awspec/stub/subnet.rb