awspec 1.11.1 → 1.12.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 5fc6f65927df3c5bce28f2194e28e2295faaa76dcda4178e6a45c3ed0bb5d734
4
- data.tar.gz: fd91c29eaa74f61f74be806370564496c462d4ce8850a8e2fa5072273edb7db7
2
+ SHA1:
3
+ metadata.gz: 5be81c89f451b385efcbd7d18de2324d4484045b
4
+ data.tar.gz: 68e0de83941e97259ec93fa70d67056b4ce4474d
5
5
  SHA512:
6
- metadata.gz: a55c537349f48a6d97106cbd3b7da029ee148bc39f7a1360ed40977a2b1fc71c3bf85d980babe943fbd9042d1450a7a86f5136ba76ea04072b52e31b5c39903a
7
- data.tar.gz: 8e405e7f0a87cdbff849a78b6f3f7d020a28d241ab36c656d6e5297f098344a9bacfd9c32dc6a90afa0bca7f49678a2ebbb3136c52db2e3c7facaa927b220895
6
+ metadata.gz: 73b78a236ae3f1822544afccb7a808ede0f41d4aeb245dbf55feb0c837e4aaac6e337e6eebb3325ffda5ddc2fb46bbfa0f80ce3a6bf885e1dc6ad45ce6c589ab
7
+ data.tar.gz: 101db4cfdbaba74ea7a125a5154cf231b118b81bf4875d2733359afbe777855eb32e54601e8812892a0cd3e38d11ea785181b726597fd0e10235da377fd93b63
@@ -39,6 +39,16 @@ describe ec2('my-ec2-classic') do
39
39
  end
40
40
  ```
41
41
 
42
+ ### have_credit_specification
43
+
44
+ The credit option for CPU usage of T2 or T3 instance.
45
+
46
+ ```ruby
47
+ describe ec2('my-ec2') do
48
+ it { should have_credit_specification('unlimited') }
49
+ end
50
+ ```
51
+
42
52
  ### have_ebs
43
53
 
44
54
  ```ruby
@@ -151,3 +161,43 @@ describe ec2('my-ec2') do
151
161
  its('resource.vpc.id') { should eq 'vpc-ab123cde' }
152
162
  end
153
163
  ```
164
+
165
+ #### Awspec::DuplicatedResourceTypeError exception
166
+
167
+ EC2 resources might have the same tag value and if you try to search for a
168
+ specific instance using that tag/tag value you might found multiples results
169
+ and receive a `Awspec::DuplicatedResourceTypeError` exception as result.
170
+
171
+ To avoid such situations, you will want to use EC2 instances ID's and then use
172
+ those ID's to test whatever you need.
173
+
174
+ There are several different ways to provide such ID's, like using [Terraform output](https://www.terraform.io/docs/configuration/outputs.html) or even the
175
+ AWS SDK directly:
176
+
177
+ ```ruby
178
+ require 'awspec'
179
+ require 'aws-sdk-ec2'
180
+
181
+ tag_name = 'tag:Name'
182
+ tag_value = 'foobar'
183
+ servers = {}
184
+ ec2 = Aws::EC2::Resource.new
185
+ ec2.instances({filters: [{name: "#{tag_name}",
186
+ values: ["#{tag_value}"]}]}).each do |i|
187
+ servers.store(i.id, i.subnet_id)
188
+ end
189
+
190
+ if servers.size == 0
191
+ raise "Could not find any EC2 instance with #{tag_name} = #{tag_value}!"
192
+ end
193
+
194
+ servers.each_pair do |instance_id, subnet_id|
195
+ describe ec2(instance_id) do
196
+ it { should exist }
197
+ it { should be_running }
198
+ its(:image_id) { should eq 'ami-12345foobar' }
199
+ its(:instance_type) { should eq 't2.micro' }
200
+ it { should belong_to_subnet(subnet_id) }
201
+ end
202
+ end
203
+ ```
@@ -0,0 +1,21 @@
1
+ ### exist
2
+
3
+ ```ruby
4
+ describe emr('my-emr') do
5
+ it { should exist }
6
+ end
7
+ ```
8
+ ### be_healthy
9
+
10
+ ```ruby
11
+ describe emr('my-emr') do
12
+ it { should be_healthy }
13
+ end
14
+ ```
15
+ ### be_running, be_waiting, be_starting, be_bootstrapping
16
+
17
+ ```ruby
18
+ describe emr('my-emr') do
19
+ it { should be_running }
20
+ end
21
+ ```
@@ -0,0 +1,102 @@
1
+ ### Common arguments
2
+
3
+ `topic_arn` is a string of the ARN of the SNS Topic.
4
+
5
+ `subscribed` is a string of the SNS Topic subscription ARN.
6
+
7
+ ### exist
8
+
9
+ ```ruby
10
+ describe sns_topic(topic_arn) do
11
+ it { should exist }
12
+ end
13
+ ```
14
+
15
+ ### name
16
+
17
+ ```ruby
18
+ describe sns_topic(topic_arn) do
19
+ its(:name) { should eq 'foobar' }
20
+ end
21
+ ```
22
+
23
+ ### confirmed_subscriptions
24
+
25
+ ```ruby
26
+ describe sns_topic(topic_arn) do
27
+ its(:confirmed_subscriptions) { should eq 1 }
28
+ end
29
+ ```
30
+
31
+ ### pending_subscriptions
32
+
33
+ ```ruby
34
+ describe sns_topic(topic_arn) do
35
+ its(:pending_subscriptions) { should eq 0 }
36
+ end
37
+ ```
38
+
39
+ ### topic_arn
40
+
41
+ ```ruby
42
+ describe sns_topic(topic_arn) do
43
+ its(:topic_arn) { should eq topic_arn }
44
+ end
45
+ ```
46
+
47
+ ### display_name
48
+
49
+ ```ruby
50
+ describe sns_topic(topic_arn) do
51
+ its(:display_name) { should eq 'ShortName' }
52
+ end
53
+ ```
54
+
55
+ ### deleted_subscriptions
56
+
57
+ ```ruby
58
+ describe sns_topic(topic_arn) do
59
+ its(:deleted_subscriptions) { should eq 0 }
60
+ end
61
+ ```
62
+
63
+ ### include_subscribed
64
+
65
+ ```ruby
66
+ describe sns_topic(topic_arn) do
67
+ it { should include_subscribed(subscribed) }
68
+ end
69
+ ```
70
+
71
+ ### have_subscription_attributes
72
+
73
+ ```ruby
74
+ describe sns_topic(topic_arn) do
75
+ let(:expected_attribs) do
76
+ { protocol: 'lambda',
77
+ owner: '123456789',
78
+ subscription_arn: subscribed, # this is required
79
+ endpoint: 'arn:aws:lambda:us-east-1:123456789:function:foobar' }
80
+ end
81
+
82
+ describe '#subscribed' do
83
+ it do
84
+ should have_subscription_attributes(expected_attribs)
85
+ end
86
+ end
87
+ end
88
+ ```
89
+
90
+ Where `:expected_attribs` is a hash with keys as properties that are part of a SNS Topic subscription:
91
+
92
+ * subscription_arn
93
+ * owner
94
+ * protocol
95
+ * endpoint
96
+ * topic_arn
97
+
98
+ You can use any combinations of key/values that will be used by `have_subscription_attributes`, but the `subscription_arn` is required and if it is missing, an exception will be generated.
99
+
100
+ ### advanced
101
+
102
+ You may want to validate the subscriptions too. For that, you probably will want to use the methods `subscriptions` (that will return a list of the subscriptions ARN as symbols) and `has_subscription?` (that expects a SNS Topic subscription as parameter and will return `true` of `false` if it exists as a subscription) of the class `Awspec::Type::SnsTopic` to build the fixture in order to use the matcher `have_subscription_attributes`.
@@ -5,10 +5,19 @@
5
5
  1. Create your feature branch (`git checkout -b add-type-redshift`)
6
6
  2. Generate template files (`bundle exec bin/toolbox template redshift`)
7
7
  3. Fill files with code.
8
- 4. Generate [doc/resource_types.md](doc/resource_types.md) (`bundle exec bin/toolbox docgen > doc/resource_types.md`)
9
- 5. Run test (`bundle exec rake spec`)
10
- 6. Push to the branch (`git push origin add-type-redshift`)
11
- 7. Create a new Pull Request
8
+ 4. `bundle update` to update gems.
9
+ 5. Generate [doc/resource_types.md](doc/resource_types.md) (`bundle exec bin/toolbox docgen > doc/resource_types.md`)
10
+ 6. Run test (`bundle exec rake spec`)
11
+ 7. Push to the branch (`git push origin add-type-redshift`)
12
+ 8. Create a new Pull Request
13
+
14
+ ### Troubleshooting
15
+
16
+ #### CI Failed 'Awspec::Generator::Doc::Type generate_doc output should be the same as doc/resource_types.md'
17
+
18
+ Maybe, your `aws-sdk-ruby` is not latest. Please exec `bundle update` and `bundle exec bin/toolbox docgen > doc/resource_types.md`.
19
+
20
+ ( `aws-sdk-ruby` is often updated. )
12
21
 
13
22
  ## Add new account attribute type (ex. CloudFormation::Client#describe_account_attributes )
14
23
 
@@ -35,6 +35,7 @@
35
35
  | [elasticsearch](#elasticsearch)
36
36
  | [elastictranscoder_pipeline](#elastictranscoder_pipeline)
37
37
  | [elb](#elb)
38
+ | [emr](#emr)
38
39
  | [firehose](#firehose)
39
40
  | [iam_group](#iam_group)
40
41
  | [iam_policy](#iam_policy)
@@ -59,6 +60,7 @@
59
60
  | [s3_bucket](#s3_bucket)
60
61
  | [security_group](#security_group)
61
62
  | [ses_identity](#ses_identity)
63
+ | [sns_topic](#sns_topic)
62
64
  | [sqs](#sqs)
63
65
  | [ssm_parameter](#ssm_parameter)
64
66
  | [subnet](#subnet)
@@ -884,6 +886,17 @@ end
884
886
  ```
885
887
 
886
888
 
889
+ ### have_credit_specification
890
+
891
+ The credit option for CPU usage of T2 or T3 instance.
892
+
893
+ ```ruby
894
+ describe ec2('my-ec2') do
895
+ it { should have_credit_specification('unlimited') }
896
+ end
897
+ ```
898
+
899
+
887
900
  ### have_ebs
888
901
 
889
902
  ```ruby
@@ -1009,6 +1022,46 @@ describe ec2('my-ec2') do
1009
1022
  end
1010
1023
  ```
1011
1024
 
1025
+ #### Awspec::DuplicatedResourceTypeError exception
1026
+
1027
+ EC2 resources might have the same tag value and if you try to search for a
1028
+ specific instance using that tag/tag value you might found multiples results
1029
+ and receive a `Awspec::DuplicatedResourceTypeError` exception as result.
1030
+
1031
+ To avoid such situations, you will want to use EC2 instances ID's and then use
1032
+ those ID's to test whatever you need.
1033
+
1034
+ There are several different ways to provide such ID's, like using [Terraform output](https://www.terraform.io/docs/configuration/outputs.html) or even the
1035
+ AWS SDK directly:
1036
+
1037
+ ```ruby
1038
+ require 'awspec'
1039
+ require 'aws-sdk-ec2'
1040
+
1041
+ tag_name = 'tag:Name'
1042
+ tag_value = 'foobar'
1043
+ servers = {}
1044
+ ec2 = Aws::EC2::Resource.new
1045
+ ec2.instances({filters: [{name: "#{tag_name}",
1046
+ values: ["#{tag_value}"]}]}).each do |i|
1047
+ servers.store(i.id, i.subnet_id)
1048
+ end
1049
+
1050
+ if servers.size == 0
1051
+ raise "Could not find any EC2 instance with #{tag_name} = #{tag_value}!"
1052
+ end
1053
+
1054
+ servers.each_pair do |instance_id, subnet_id|
1055
+ describe ec2(instance_id) do
1056
+ it { should exist }
1057
+ it { should be_running }
1058
+ its(:image_id) { should eq 'ami-12345foobar' }
1059
+ its(:instance_type) { should eq 't2.micro' }
1060
+ it { should belong_to_subnet(subnet_id) }
1061
+ end
1062
+ end
1063
+ ```
1064
+
1012
1065
  ## <a name="ecr_repository">ecr_repository</a>
1013
1066
 
1014
1067
  EcrRepository resource type.
@@ -1423,6 +1476,39 @@ end
1423
1476
 
1424
1477
 
1425
1478
  ### its(:health_check_target), its(:health_check_interval), its(:health_check_timeout), its(:health_check_unhealthy_threshold), its(:health_check_healthy_threshold), its(:load_balancer_name), its(:dns_name), its(:canonical_hosted_zone_name), its(:canonical_hosted_zone_name_id), its(:backend_server_descriptions), its(:availability_zones), its(:subnets), its(:vpc_id), its(:security_groups), its(:created_time), its(:scheme)
1479
+ ## <a name="emr">emr</a>
1480
+
1481
+ Emr resource type.
1482
+
1483
+ ### exist
1484
+
1485
+ ```ruby
1486
+ describe emr('my-emr') do
1487
+ it { should exist }
1488
+ end
1489
+ ```
1490
+
1491
+ ### be_healthy
1492
+
1493
+ ```ruby
1494
+ describe emr('my-emr') do
1495
+ it { should be_healthy }
1496
+ end
1497
+ ```
1498
+
1499
+ ### be_ok
1500
+
1501
+ ### be_ready
1502
+
1503
+ ### be_running, be_waiting, be_starting, be_bootstrapping
1504
+
1505
+ ```ruby
1506
+ describe emr('my-emr') do
1507
+ it { should be_running }
1508
+ end
1509
+ ```
1510
+
1511
+ ### its(:id), its(:name), its(:instance_collection_type), its(:log_uri), its(:requested_ami_version), its(:running_ami_version), its(:release_label), its(:auto_terminate), its(:termination_protected), its(:visible_to_all_users), its(:service_role), its(:normalized_instance_hours), its(:master_public_dns_name), its(:configurations), its(:security_configuration), its(:auto_scaling_role), its(:scale_down_behavior), its(:custom_ami_id), its(:ebs_root_volume_size), its(:repo_upgrade_on_boot)
1426
1512
  ## <a name="firehose">firehose</a>
1427
1513
 
1428
1514
  Firehose resource type.
@@ -2337,7 +2423,7 @@ end
2337
2423
  ```
2338
2424
 
2339
2425
 
2340
- ### its(:vpc_id), its(:db_instance_identifier), its(:db_instance_class), its(:engine), its(:db_instance_status), its(:master_username), its(:db_name), its(:endpoint), its(:allocated_storage), its(:instance_create_time), its(:preferred_backup_window), its(:backup_retention_period), its(:db_security_groups), its(:availability_zone), its(:preferred_maintenance_window), its(:pending_modified_values), its(:latest_restorable_time), its(:multi_az), its(:engine_version), its(:auto_minor_version_upgrade), its(:read_replica_source_db_instance_identifier), its(:read_replica_db_instance_identifiers), its(:read_replica_db_cluster_identifiers), its(:license_model), its(:iops), its(:character_set_name), its(:secondary_availability_zone), its(:publicly_accessible), its(:status_infos), its(:storage_type), its(:tde_credential_arn), its(:db_instance_port), its(:db_cluster_identifier), its(:storage_encrypted), its(:kms_key_id), its(:dbi_resource_id), its(:ca_certificate_identifier), its(:domain_memberships), its(:copy_tags_to_snapshot), its(:monitoring_interval), its(:enhanced_monitoring_resource_arn), its(:monitoring_role_arn), its(:promotion_tier), its(:db_instance_arn), its(:timezone), its(:iam_database_authentication_enabled), its(:performance_insights_enabled), its(:performance_insights_kms_key_id), its(:performance_insights_retention_period), its(:enabled_cloudwatch_logs_exports), its(:processor_features), its(:deletion_protection)
2426
+ ### its(:vpc_id), its(:db_instance_identifier), its(:db_instance_class), its(:engine), its(:db_instance_status), its(:master_username), its(:db_name), its(:endpoint), its(:allocated_storage), its(:instance_create_time), its(:preferred_backup_window), its(:backup_retention_period), its(:db_security_groups), its(:availability_zone), its(:preferred_maintenance_window), its(:pending_modified_values), its(:latest_restorable_time), its(:multi_az), its(:engine_version), its(:auto_minor_version_upgrade), its(:read_replica_source_db_instance_identifier), its(:read_replica_db_instance_identifiers), its(:read_replica_db_cluster_identifiers), its(:license_model), its(:iops), its(:character_set_name), its(:secondary_availability_zone), its(:publicly_accessible), its(:status_infos), its(:storage_type), its(:tde_credential_arn), its(:db_instance_port), its(:db_cluster_identifier), its(:storage_encrypted), its(:kms_key_id), its(:dbi_resource_id), its(:ca_certificate_identifier), its(:domain_memberships), its(:copy_tags_to_snapshot), its(:monitoring_interval), its(:enhanced_monitoring_resource_arn), its(:monitoring_role_arn), its(:promotion_tier), its(:db_instance_arn), its(:timezone), its(:iam_database_authentication_enabled), its(:performance_insights_enabled), its(:performance_insights_kms_key_id), its(:performance_insights_retention_period), its(:enabled_cloudwatch_logs_exports), its(:processor_features), its(:deletion_protection), its(:listener_endpoint)
2341
2427
  ### :unlock: Advanced use
2342
2428
 
2343
2429
  `rds` can use `Aws::RDS::DBInstance` resource (see http://docs.aws.amazon.com/sdkforruby/api/Aws/RDS/DBInstance.html).
@@ -2741,6 +2827,65 @@ end
2741
2827
  ```
2742
2828
 
2743
2829
  ### its(:dkim_enabled), its(:dkim_verification_status), its(:bounce_topic), its(:complaint_topic), its(:delivery_topic), its(:forwarding_enabled), its(:verification_status), its(:verification_token)
2830
+ ## <a name="sns_topic">sns_topic</a>
2831
+
2832
+ SnsTopic resource type.
2833
+
2834
+ ### exist
2835
+
2836
+ ```ruby
2837
+ describe sns_topic(topic_arn) do
2838
+ it { should exist }
2839
+ end
2840
+ ```
2841
+
2842
+
2843
+ ### have_subscription
2844
+
2845
+ ### have_subscription_attributes
2846
+
2847
+ ```ruby
2848
+ describe sns_topic(topic_arn) do
2849
+ let(:expected_attribs) do
2850
+ { protocol: 'lambda',
2851
+ owner: '123456789',
2852
+ subscription_arn: subscribed, # this is required
2853
+ endpoint: 'arn:aws:lambda:us-east-1:123456789:function:foobar' }
2854
+ end
2855
+
2856
+ describe '#subscribed' do
2857
+ it do
2858
+ should have_subscription_attributes(expected_attribs)
2859
+ end
2860
+ end
2861
+ end
2862
+ ```
2863
+
2864
+ Where `:expected_attribs` is a hash with keys as properties that are part of a SNS Topic subscription:
2865
+
2866
+ * subscription_arn
2867
+ * owner
2868
+ * protocol
2869
+ * endpoint
2870
+ * topic_arn
2871
+
2872
+ You can use any combinations of key/values that will be used by `have_subscription_attributes`, but the `subscription_arn` is required and if it is missing, an exception will be generated.
2873
+
2874
+
2875
+ ### include_subscribed
2876
+
2877
+ ```ruby
2878
+ describe sns_topic(topic_arn) do
2879
+ it { should include_subscribed(subscribed) }
2880
+ end
2881
+ ```
2882
+
2883
+
2884
+ ### its(:policy), its(:owner), its(:pending_subscriptions), its(:topic_arn), its(:effective_delivery_policy), its(:display_name), its(:confirmed_subscriptions), its(:deleted_subscriptions), its(:name)
2885
+ ### :unlock: Advanced use
2886
+
2887
+ You may want to validate the subscriptions too. For that, you probably will want to use the methods `subscriptions` (that will return a list of the subscriptions ARN as symbols) and `has_subscription?` (that expects a SNS Topic subscription as parameter and will return `true` of `false` if it exists as a subscription) of the class `Awspec::Type::SnsTopic` to build the fixture in order to use the matcher `have_subscription_attributes`.
2888
+
2744
2889
  ## <a name="sqs">sqs</a>
2745
2890
 
2746
2891
  SQS resource type.
@@ -0,0 +1,19 @@
1
+ module Awspec::Generator
2
+ module Doc
3
+ module Type
4
+ class Emr < Base
5
+ def initialize
6
+ super
7
+ @type_name = 'Emr'
8
+ @type = Awspec::Type::Emr.new('my-emr')
9
+ @ret = @type.resource_via_client
10
+ @matchers = [
11
+ Awspec::Type::Emr::STATES.map { |state| 'be_' + state.downcase }.join(', ')
12
+ ]
13
+ @ignore_matchers = Awspec::Type::Emr::STATES.map { |state| 'be_' + state.downcase }
14
+ @describes = []
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module Awspec::Generator
2
+ module Doc
3
+ module Type
4
+ class SnsTopic < Base
5
+ def initialize
6
+ super
7
+ @type_name = 'SnsTopic'
8
+ @type = Awspec::Type::SnsTopic.new('my-sns')
9
+ @ret = @type.resource_via_client
10
+ @matchers = %w(include_subscribed have_subscription_attributes)
11
+ @ignore_matchers = []
12
+ @describes = %w(policy owner pending_subscriptions topic_arn effective_delivery_policy display_name
13
+ confirmed_subscriptions deleted_subscriptions name)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -15,7 +15,7 @@ module Awspec::Generator
15
15
  end
16
16
 
17
17
  def generate_log_stream_spec(log_group)
18
- log_stream = find_cloudwatch_logs_stream_by_log_group_name(log_group)
18
+ log_stream = last_cloudwatch_logs_stream_by_log_group_name(log_group)
19
19
  "it { should have_log_stream('#{log_stream.log_stream_name}') }" unless log_stream.nil?
20
20
  end
21
21
 
@@ -19,6 +19,7 @@ module Awspec::Generator
19
19
  eips = select_eip_by_instance_id(instance_id)
20
20
  volumes = select_ebs_by_instance_id(instance_id)
21
21
  network_interfaces = select_network_interface_by_instance_id(instance_id)
22
+ credit_specification = find_ec2_credit_specifications(instance_id)
22
23
  content = ERB.new(ec2_spec_template, nil, '-').result(binding).gsub(/^\n/, '')
23
24
  end
24
25
  specs.join("\n")
@@ -69,6 +70,9 @@ describe ec2('<%= instance_id %>') do
69
70
  <% network_interfaces.each do |interface| %>
70
71
  it { should have_network_interface('<%= interface.network_interface_id %>') }
71
72
  <% end %>
73
+ <%- if credit_specification.cpu_credits -%>
74
+ it { should have_credit_specification('<%= credit_specification.cpu_credits %>') }
75
+ <%- end -%>
72
76
  end
73
77
  EOF
74
78
  template
@@ -40,6 +40,8 @@ require 'awspec/helper/finder/apigateway'
40
40
  require 'awspec/helper/finder/kinesis'
41
41
  require 'awspec/helper/finder/batch'
42
42
  require 'awspec/helper/finder/eks'
43
+ require 'awspec/helper/finder/sns_topic'
44
+ require 'awspec/helper/finder/emr'
43
45
 
44
46
  require 'awspec/helper/finder/account_attributes'
45
47
 
@@ -89,6 +91,8 @@ module Awspec::Helper
89
91
  include Awspec::Helper::Finder::Kinesis
90
92
  include Awspec::Helper::Finder::Batch
91
93
  include Awspec::Helper::Finder::Eks
94
+ include Awspec::Helper::Finder::SNSTopic
95
+ include Awspec::Helper::Finder::Emr
92
96
 
93
97
  CLIENTS = {
94
98
  ec2_client: Aws::EC2::Client,
@@ -126,7 +130,9 @@ module Awspec::Helper
126
130
  apigateway_client: Aws::APIGateway::Client,
127
131
  kinesis_client: Aws::Kinesis::Client,
128
132
  batch_client: Aws::Batch::Client,
129
- eks_client: Aws::EKS::Client
133
+ eks_client: Aws::EKS::Client,
134
+ sns_client: Aws::SNS::Client,
135
+ emr_client: Aws::EMR::Client
130
136
  }
131
137
 
132
138
  CLIENT_OPTIONS = {
@@ -9,6 +9,10 @@ module Awspec::Helper
9
9
  end
10
10
  end
11
11
 
12
+ def last_cloudwatch_logs_stream_by_log_group_name(id)
13
+ cloudwatch_logs_client.describe_log_streams({ log_group_name: id }).log_streams.last
14
+ end
15
+
12
16
  def find_cloudwatch_logs_stream_by_log_group_name(id, stream_name)
13
17
  req = {
14
18
  log_group_name: id,
@@ -28,6 +28,13 @@ module Awspec::Helper
28
28
  })
29
29
  end
30
30
 
31
+ def find_ec2_credit_specifications(id)
32
+ res = ec2_client.describe_instance_credit_specifications({
33
+ instance_ids: [id]
34
+ })
35
+ res.instance_credit_specifications.first if res.instance_credit_specifications.count == 1
36
+ end
37
+
31
38
  def find_ec2_status(id)
32
39
  res = ec2_client.describe_instance_status({
33
40
  instance_ids: [id]
@@ -0,0 +1,9 @@
1
+ module Awspec::Helper
2
+ module Finder
3
+ module Emr
4
+ def find_emr_cluster(cluster_id)
5
+ emr_client.describe_cluster({ cluster_id: cluster_id }).cluster
6
+ end
7
+ end
8
+ end
9
+ end
@@ -89,20 +89,20 @@ module Awspec::Helper
89
89
  end
90
90
 
91
91
  def select_all_iam_users
92
- iam_client.list_users.map do |responce|
93
- responce.users
92
+ iam_client.list_users.map do |response|
93
+ response.users
94
94
  end.flatten
95
95
  end
96
96
 
97
97
  def select_all_iam_groups
98
- iam_client.list_groups.map do |responce|
99
- responce.groups
98
+ iam_client.list_groups.map do |response|
99
+ response.groups
100
100
  end.flatten
101
101
  end
102
102
 
103
103
  def select_all_iam_roles
104
- iam_client.list_roles.map do |responce|
105
- responce.roles
104
+ iam_client.list_roles.map do |response|
105
+ response.roles
106
106
  end.flatten
107
107
  end
108
108
  end
@@ -23,8 +23,8 @@ module Awspec::Helper
23
23
  end
24
24
 
25
25
  def select_all_lambda_functions
26
- res = lambda_client.list_functions.map do |responce|
27
- responce.functions
26
+ res = lambda_client.list_functions.map do |response|
27
+ response.functions
28
28
  end.flatten
29
29
  end
30
30
  end
@@ -0,0 +1,47 @@
1
+ module Awspec::Helper
2
+ module Finder
3
+ module SNSTopic
4
+ class SnsTopic
5
+ # to make testing results easier to the eyes instead of using Rspec
6
+ # include matcher for hashes
7
+ attr_reader :policy, :owner, :pending_subscriptions, :topic_arn, :effective_delivery_policy,
8
+ :display_name, :confirmed_subscriptions, :deleted_subscriptions, :name
9
+
10
+ def initialize(attribs)
11
+ @policy = attribs['Policy']
12
+ @owner = attribs['Owner']
13
+ @pending_subscriptions = attribs['SubscriptionsPending'].to_i
14
+ @topic_arn = attribs['TopicArn']
15
+ @effective_delivery_policy = attribs['EffectiveDeliveryPolicy']
16
+ @display_name = attribs['DisplayName']
17
+ @confirmed_subscriptions = attribs['SubscriptionsConfirmed'].to_i
18
+ @deleted_subscriptions = attribs['SubscriptionsDeleted'].to_i
19
+ @name = attribs['TopicArn'].split(':')[-1]
20
+ end
21
+
22
+ def to_s
23
+ output = ["SnsTopic: #{self.name}"]
24
+ self.instance_variables.each do |attrib|
25
+ tmp = attrib.to_s.sub('@', '')
26
+ output << " #{tmp} = #{self.send(tmp)}"
27
+ end
28
+ output.join("\n")
29
+ end
30
+ end
31
+
32
+ def find_sns_topic(topic_arn)
33
+ response = sns_client.get_topic_attributes({ topic_arn: topic_arn })
34
+ SnsTopic.new(response.attributes)
35
+ end
36
+
37
+ def find_sns_topic_subs(topic_arn)
38
+ response = sns_client.list_subscriptions_by_topic({ topic_arn: topic_arn })
39
+ subscriptions = {}
40
+ response.subscriptions.each do |subscribed|
41
+ subscriptions[subscribed['subscription_arn'].to_sym] = subscribed
42
+ end
43
+ subscriptions
44
+ end
45
+ end
46
+ end
47
+ end
@@ -12,13 +12,13 @@ module Awspec
12
12
  batch_compute_environment batch_job_definition batch_job_queue cloudtrail
13
13
  cloudwatch_alarm cloudwatch_event directconnect_virtual_interface
14
14
  ebs ec2 ecr_repository ecs_cluster ecs_container_instance ecs_service ecs_task_definition
15
- efs eks elasticache elasticache_cache_parameter_group elasticsearch elb firehose iam_group
15
+ efs eks elasticache elasticache_cache_parameter_group elasticsearch elb emr firehose iam_group
16
16
  iam_policy iam_role iam_user kinesis kms lambda launch_configuration nat_gateway
17
17
  network_acl network_interface nlb nlb_listener nlb_target_group
18
18
  rds rds_db_cluster_parameter_group rds_db_parameter_group route53_hosted_zone
19
19
  route_table s3_bucket security_group ses_identity subnet vpc cloudfront_distribution
20
20
  elastictranscoder_pipeline waf_web_acl customer_gateway vpn_gateway vpn_connection internet_gateway acm
21
- cloudwatch_logs dynamodb_table eip sqs ssm_parameter cloudformation_stack codebuild
21
+ cloudwatch_logs dynamodb_table eip sqs ssm_parameter cloudformation_stack codebuild sns_topic
22
22
  )
23
23
 
24
24
  ACCOUNT_ATTRIBUTES = %w(
@@ -70,3 +70,7 @@ require 'awspec/matcher/belong_to_nlb'
70
70
  # VPC
71
71
  require 'awspec/matcher/be_connected_to_vpc'
72
72
  require 'awspec/matcher/have_vpc_peering_connection'
73
+
74
+ # SNSTopic
75
+ require 'awspec/matcher/include_subscribed'
76
+ require 'awspec/matcher/have_subscription_attributes'
@@ -0,0 +1,16 @@
1
+ RSpec::Matchers.define :have_subscription_attributes do |expected_attribs|
2
+ match do |sns_topic|
3
+ unless expected_attribs.key?(:subscription_arn)
4
+ raise '"subscription_arn" is the only required attribute to validate'
5
+ end
6
+ subscribed = sns_topic.subscribed(expected_attribs[:subscription_arn])
7
+ temp = subscribed.to_h
8
+ to_remove = temp.keys - expected_attribs.keys
9
+ to_remove.each { |key| temp.delete(key) }
10
+ temp == expected_attribs
11
+ end
12
+
13
+ failure_message do |sns_topic|
14
+ "expected SNS topic #{sns_topic.name} to have a subscription with the following attributes: #{expected_attribs}"
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define :include_subscribed do |subscribed_arn|
2
+ match do |sns_topic|
3
+ sns_topic.has_subscription?(subscribed_arn)
4
+ end
5
+ end
@@ -10,11 +10,11 @@ Aws.config[:dynamodb] = {
10
10
  },
11
11
  attribute_definitions: [
12
12
  {
13
- attribute_name: 'my-dynamodb-table-attaribute1',
13
+ attribute_name: 'my-dynamodb-table-attribute1',
14
14
  attribute_type: 'S'
15
15
  },
16
16
  {
17
- attribute_name: 'my-dynamodb-table-attaribute2',
17
+ attribute_name: 'my-dynamodb-table-attribute2',
18
18
  attribute_type: 'N'
19
19
  }
20
20
  ],
@@ -222,6 +222,14 @@ Aws.config[:ec2] = {
222
222
  interface_type: nil
223
223
  }
224
224
  ]
225
+ },
226
+ describe_instance_credit_specifications: {
227
+ instance_credit_specifications: [
228
+ {
229
+ instance_id: 'i-ec12345a',
230
+ cpu_credits: 'unlimited'
231
+ }
232
+ ]
225
233
  }
226
234
  }
227
235
  }
@@ -0,0 +1,65 @@
1
+ Aws.config[:emr] = {
2
+ stub_responses: {
3
+ describe_cluster: {
4
+ cluster: {
5
+ name: 'my cluster',
6
+ log_uri: 's3n://aws-logs-232939870606-us-east-1/elasticmapreduce/',
7
+ applications: [
8
+ {
9
+ name: 'Spark',
10
+ version: '2.3.1',
11
+ args: [],
12
+ additional_info: {}
13
+ },
14
+ {
15
+ name: 'Hadoop',
16
+ version: '10.0.1',
17
+ args: [],
18
+ additional_info: {}
19
+ }
20
+ ],
21
+ tags: [{ key: 'Name', value: 'My Cluster' }],
22
+ status: {
23
+ state: 'RUNNING',
24
+ state_change_reason: {
25
+ code: '',
26
+ message: ''
27
+ },
28
+ timeline: {
29
+ creation_date_time: Time.parse('2018-10-29 22:41:38 -0400'),
30
+ ready_date_time: Time.parse('2018-10-29 22:41:38 -0400'),
31
+ end_date_time: nil
32
+ }
33
+ },
34
+ auto_scaling_role: 'EMR_AutoScaling_DefaultRole',
35
+ scale_down_behavior: 'TERMINATE_AT_TASK_COMPLETION',
36
+ ebs_root_volume_size: 30,
37
+ instance_collection_type: 'INSTANCE_FLEET',
38
+ security_configuration: 'sg-1828281-madeup',
39
+ master_public_dns_name: 'ec2-54-167-31-38.compute-1.amazonaws.com',
40
+ service_role: 'EMR_EC2_DefaultRole',
41
+ visible_to_all_users: false,
42
+ kerberos_attributes: {
43
+ realm: 'EXAMPLE.COM',
44
+ kdc_admin_password: 'password',
45
+ cross_realm_trust_principal_password: 'emr-password',
46
+ ad_domain_join_user: 'johny',
47
+ ad_domain_join_password: 'begood'
48
+ },
49
+ ec2_instance_attributes: {
50
+ ec2_key_name: 'my-key',
51
+ ec2_subnet_id: 'sb-0bfc9360',
52
+ requested_ec2_subnet_ids: [],
53
+ ec2_availability_zone: 'us-east-1a',
54
+ requested_ec2_availability_zones: [],
55
+ emr_managed_master_security_group: 'sg-0bfc9360',
56
+ emr_managed_slave_security_group: 'sg-0bfc9360',
57
+ service_access_security_group: 'sg-0bfc9360',
58
+ iam_instance_profile: 'EMR_EC2_DefaultRole',
59
+ additional_master_security_groups: [],
60
+ additional_slave_security_groups: []
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,29 @@
1
+ Aws.config[:sns] = {
2
+ stub_responses: {
3
+ get_topic_attributes: {
4
+ attributes: {
5
+ # 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',
8
+ 'SubscriptionsPending' => '0',
9
+ 'TopicArn' => 'arn:aws:sns:us-east-1:123456789:foobar',
10
+ 'EffectiveDeliveryPolicy' => '{\"http\":{\"defaultHealthyRetryPolicy\":{\"minDelayTarget\":20,\"maxDelayTarget\":20,\"numRetries\":3,\"numMaxDelayRetries\":0,\"numNoDelayRetries\":0,\"numMinDelayRetries\":0,\"backoffFunction\":\"linear\"},\"disableSubscriptionOverrides\":false}}',
11
+ 'SubscriptionsConfirmed' => '1',
12
+ 'DisplayName' => 'Useless',
13
+ 'SubscriptionsDeleted' => '0'
14
+ }
15
+ },
16
+ list_subscriptions_by_topic: {
17
+ subscriptions: [
18
+ {
19
+ subscription_arn: 'arn:aws:sns:us-east-1:123456789:Foobar:3dbf4999-b3e2-4345-bd11-c34c9784ecca',
20
+ owner: '123456789',
21
+ protocol: 'lambda',
22
+ endpoint: 'arn:aws:lambda:us-east-1:123456789:function:foobar',
23
+ topic_arn: 'arn:aws:sns:us-east-1:123456789:foobar'
24
+ }
25
+ ],
26
+ next_token: nil
27
+ }
28
+ }
29
+ }
@@ -132,6 +132,11 @@ module Awspec::Type
132
132
  return true if ret
133
133
  end
134
134
 
135
+ def has_credit_specification?(cpu_credits)
136
+ ret = find_ec2_credit_specifications(id)
137
+ ret.cpu_credits == cpu_credits
138
+ end
139
+
135
140
  private
136
141
 
137
142
  def match_group_ids?(sg_ids)
@@ -0,0 +1,40 @@
1
+ module Awspec::Type
2
+ class Emr < ResourceBase
3
+ attr_reader :id
4
+
5
+ def initialize(id)
6
+ super
7
+ @id = id
8
+ end
9
+
10
+ def resource_via_client
11
+ @resource_via_client ||= find_emr_cluster(@id)
12
+ end
13
+
14
+ STARTING_STATES = %w(STARTING BOOTSTRAPPING)
15
+ READY_STATES = %w(RUNNING WAITING)
16
+ STATES = (READY_STATES + STARTING_STATES)
17
+
18
+ STATES.each do |state|
19
+ define_method state.downcase + '?' do
20
+ resource_via_client.status.state == state
21
+ end
22
+ end
23
+
24
+ def applications
25
+ resource_via_client.applications.map { |a| { name: a.name, version: a.version } }
26
+ end
27
+
28
+ def tags
29
+ resource_via_client.tags.map { |t| { t.key.to_sym => t.value } }
30
+ end
31
+
32
+ def ok?
33
+ READY_STATES.include?(resource_via_client.status.state)
34
+ end
35
+
36
+ alias_method :healthy?, :ok?
37
+ alias_method :ready?, :ok?
38
+ alias_method :bootstrapping?, :starting?
39
+ end
40
+ end
@@ -0,0 +1,47 @@
1
+ module Awspec::Type
2
+ class SnsTopic < ResourceBase
3
+ def initialize(topic_arn)
4
+ super
5
+ @topic_arn = topic_arn
6
+ # lazy instantiation
7
+ @subscriptions = nil
8
+ end
9
+
10
+ def subscriptions
11
+ @subscriptions.keys
12
+ end
13
+
14
+ def resource_via_client
15
+ @resource_via_client ||= find_sns_topic(@topic_arn)
16
+ end
17
+
18
+ def id
19
+ # A SNS Topic doesn't have an ID...
20
+ @id ||= resource_via_client.topic_arn if resource_via_client
21
+ end
22
+
23
+ def has_subscription?(subscribed_arn)
24
+ fetch_subscriptions
25
+ @subscriptions.key?(subscribed_arn.to_sym)
26
+ end
27
+
28
+ def subscribed(subscribed_arn)
29
+ subs_key = subscribed_arn.to_sym
30
+ fetch_subscriptions
31
+ raise "'#{subscribed_arn}' is not a valid subscription ARN" unless @subscriptions.key?(subs_key)
32
+ @subscriptions[subs_key]
33
+ end
34
+
35
+ def method_missing(method_name)
36
+ # delegates the method invocation to Awspec::Helper::Finder::SnsTopic::SnsTopic class
37
+ @resource_via_client.send method_name
38
+ end
39
+
40
+ private
41
+
42
+ def fetch_subscriptions
43
+ @subscriptions = find_sns_topic_subs(@topic_arn) if @subscriptions.nil?
44
+ @subscriptions
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module Awspec
2
- VERSION = '1.11.1'
2
+ VERSION = '1.12.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.1
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - k1LoW
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-29 00:00:00.000000000 Z
11
+ date: 2018-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -248,6 +248,7 @@ files:
248
248
  - doc/_resource_types/elasticsearch.md
249
249
  - doc/_resource_types/elastictranscoder_pipeline.md
250
250
  - doc/_resource_types/elb.md
251
+ - doc/_resource_types/emr.md
251
252
  - doc/_resource_types/firehose.md
252
253
  - doc/_resource_types/iam_group.md
253
254
  - doc/_resource_types/iam_policy.md
@@ -275,6 +276,7 @@ files:
275
276
  - doc/_resource_types/security_group.md
276
277
  - doc/_resource_types/ses_identity.md
277
278
  - doc/_resource_types/ses_send_quota.md
279
+ - doc/_resource_types/sns_topic.md
278
280
  - doc/_resource_types/sqs.md
279
281
  - doc/_resource_types/ssm_parameter.md
280
282
  - doc/_resource_types/subnet.md
@@ -336,6 +338,7 @@ files:
336
338
  - lib/awspec/generator/doc/type/elasticsearch.rb
337
339
  - lib/awspec/generator/doc/type/elastictranscoder_pipeline.rb
338
340
  - lib/awspec/generator/doc/type/elb.rb
341
+ - lib/awspec/generator/doc/type/emr.rb
339
342
  - lib/awspec/generator/doc/type/firehose.rb
340
343
  - lib/awspec/generator/doc/type/iam_group.rb
341
344
  - lib/awspec/generator/doc/type/iam_policy.rb
@@ -363,6 +366,7 @@ files:
363
366
  - lib/awspec/generator/doc/type/security_group.rb
364
367
  - lib/awspec/generator/doc/type/ses_identity.rb
365
368
  - lib/awspec/generator/doc/type/ses_send_quota.rb
369
+ - lib/awspec/generator/doc/type/sns_topic.rb
366
370
  - lib/awspec/generator/doc/type/sqs.rb
367
371
  - lib/awspec/generator/doc/type/ssm_parameter.rb
368
372
  - lib/awspec/generator/doc/type/subnet.rb
@@ -434,6 +438,7 @@ files:
434
438
  - lib/awspec/helper/finder/elasticsearch.rb
435
439
  - lib/awspec/helper/finder/elastictranscoder.rb
436
440
  - lib/awspec/helper/finder/elb.rb
441
+ - lib/awspec/helper/finder/emr.rb
437
442
  - lib/awspec/helper/finder/firehose.rb
438
443
  - lib/awspec/helper/finder/iam.rb
439
444
  - lib/awspec/helper/finder/kinesis.rb
@@ -445,6 +450,7 @@ files:
445
450
  - lib/awspec/helper/finder/s3.rb
446
451
  - lib/awspec/helper/finder/security_group.rb
447
452
  - lib/awspec/helper/finder/ses.rb
453
+ - lib/awspec/helper/finder/sns_topic.rb
448
454
  - lib/awspec/helper/finder/sqs.rb
449
455
  - lib/awspec/helper/finder/ssm_parameter.rb
450
456
  - lib/awspec/helper/finder/subnet.rb
@@ -482,9 +488,11 @@ files:
482
488
  - lib/awspec/matcher/have_record_set.rb
483
489
  - lib/awspec/matcher/have_route.rb
484
490
  - lib/awspec/matcher/have_rule.rb
491
+ - lib/awspec/matcher/have_subscription_attributes.rb
485
492
  - lib/awspec/matcher/have_subscription_filter.rb
486
493
  - lib/awspec/matcher/have_tag.rb
487
494
  - lib/awspec/matcher/have_vpc_peering_connection.rb
495
+ - lib/awspec/matcher/include_subscribed.rb
488
496
  - lib/awspec/resource_reader.rb
489
497
  - lib/awspec/setup.rb
490
498
  - lib/awspec/shared_context.rb
@@ -528,6 +536,7 @@ files:
528
536
  - lib/awspec/stub/elasticsearch.rb
529
537
  - lib/awspec/stub/elastictranscoder_pipeline.rb
530
538
  - lib/awspec/stub/elb.rb
539
+ - lib/awspec/stub/emr.rb
531
540
  - lib/awspec/stub/firehose.rb
532
541
  - lib/awspec/stub/iam_group.rb
533
542
  - lib/awspec/stub/iam_policy.rb
@@ -552,6 +561,7 @@ files:
552
561
  - lib/awspec/stub/s3_bucket.rb
553
562
  - lib/awspec/stub/security_group.rb
554
563
  - lib/awspec/stub/ses_identity.rb
564
+ - lib/awspec/stub/sns_topic.rb
555
565
  - lib/awspec/stub/sqs.rb
556
566
  - lib/awspec/stub/ssm_parameter.rb
557
567
  - lib/awspec/stub/subnet.rb
@@ -600,6 +610,7 @@ files:
600
610
  - lib/awspec/type/elasticsearch.rb
601
611
  - lib/awspec/type/elastictranscoder_pipeline.rb
602
612
  - lib/awspec/type/elb.rb
613
+ - lib/awspec/type/emr.rb
603
614
  - lib/awspec/type/firehose.rb
604
615
  - lib/awspec/type/iam_group.rb
605
616
  - lib/awspec/type/iam_policy.rb
@@ -628,6 +639,7 @@ files:
628
639
  - lib/awspec/type/security_group.rb
629
640
  - lib/awspec/type/ses_identity.rb
630
641
  - lib/awspec/type/ses_send_quota.rb
642
+ - lib/awspec/type/sns_topic.rb
631
643
  - lib/awspec/type/sqs.rb
632
644
  - lib/awspec/type/ssm_parameter.rb
633
645
  - lib/awspec/type/subnet.rb
@@ -656,7 +668,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
656
668
  version: '0'
657
669
  requirements: []
658
670
  rubyforge_project:
659
- rubygems_version: 2.7.6
671
+ rubygems_version: 2.6.14
660
672
  signing_key:
661
673
  specification_version: 4
662
674
  summary: RSpec tests for your AWS resources.