awspec 1.24.3 → 1.24.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +69 -0
- data/.github/workflows/doc.yml +29 -0
- data/.rubocop.yml +47 -2
- data/Gemfile +2 -0
- data/README.md +1 -3
- data/Rakefile +0 -1
- data/awspec.gemspec +3 -5
- data/doc/_resource_types/cloudwatch_logs.md +9 -0
- data/doc/_resource_types/eks_nodegroup.md +53 -0
- data/doc/resource_types.md +48 -4
- data/lib/awspec/generator/spec/cloudwatch_logs.rb +5 -1
- data/lib/awspec/helper/finder/ec2.rb +41 -17
- data/lib/awspec/helper/finder/ecs.rb +1 -1
- data/lib/awspec/matcher.rb +4 -0
- data/lib/awspec/matcher/belong_to_subnets.rb +14 -0
- data/lib/awspec/matcher/have_metric_filter.rb +9 -0
- data/lib/awspec/setup.rb +1 -1
- data/lib/awspec/stub/cloudwatch_logs.rb +2 -1
- data/lib/awspec/stub/eks_nodegroup.rb +61 -1
- data/lib/awspec/stub/elasticsearch.rb +0 -1
- data/lib/awspec/type/cloudwatch_logs.rb +8 -3
- data/lib/awspec/type/eks_nodegroup.rb +105 -0
- data/lib/awspec/type/s3_bucket.rb +1 -1
- data/lib/awspec/version.rb +1 -1
- metadata +26 -24
- data/.tachikoma.yml +0 -1
- data/.travis.yml +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03a271717bc3471b5109a4831bbb0941a1d2975b90ed04427fa304fb727c251b
|
4
|
+
data.tar.gz: 3eff98cd7e63f51067739eebf9d8c94476b66469ea98b2148d96c9afec502c3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82d89949fa055cbcfda478ff3efa28259a70cf9dc37fba9ea2c9e861c6393e225c5d268b701acdd4c567b0878d4d06f3c2db692b554d41a9737cecac87cc6dab
|
7
|
+
data.tar.gz: 9d5a864c8065cf512aabcb2c2dd8851510253d8486dc0d6653e5c53d4c50376ca9c53a4a7ad45db5c8841e38d6c210a6e14c90970fabb75e03a454f4730cdaf3
|
@@ -0,0 +1,69 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
lint:
|
10
|
+
name: Lint
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- name: Checkout
|
15
|
+
uses: actions/checkout@v2
|
16
|
+
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 2.7
|
21
|
+
bundler-cache: true
|
22
|
+
|
23
|
+
- name: Run rubocop
|
24
|
+
uses: reviewdog/action-rubocop@v1
|
25
|
+
with:
|
26
|
+
rubocop_version: 0.57.2
|
27
|
+
rubocop_extensions: rubocop:0.57.2
|
28
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
29
|
+
reporter: github-pr-review
|
30
|
+
fail_on_error: true
|
31
|
+
|
32
|
+
test:
|
33
|
+
name: Test
|
34
|
+
needs: [ lint ]
|
35
|
+
strategy:
|
36
|
+
fail-fast: false
|
37
|
+
matrix:
|
38
|
+
ruby-version:
|
39
|
+
- '2.1'
|
40
|
+
- '2.2'
|
41
|
+
- '2.3'
|
42
|
+
- '2.4'
|
43
|
+
- '2.5'
|
44
|
+
- '2.6'
|
45
|
+
- '2.7'
|
46
|
+
# - '3.0'
|
47
|
+
runs-on: ubuntu-latest
|
48
|
+
env:
|
49
|
+
DISABLE_AWS_CLIENT_CHECK: true
|
50
|
+
|
51
|
+
steps:
|
52
|
+
- name: Checkout
|
53
|
+
uses: actions/checkout@v2
|
54
|
+
|
55
|
+
- name: Set up Ruby
|
56
|
+
uses: ruby/setup-ruby@v1
|
57
|
+
with:
|
58
|
+
ruby-version: ${{ matrix.ruby-version }}
|
59
|
+
bundler-cache: true
|
60
|
+
|
61
|
+
- name: Install xml lib
|
62
|
+
run: gem install ox
|
63
|
+
if: matrix.ruby-version == '3.0'
|
64
|
+
|
65
|
+
- name: Generate document
|
66
|
+
run: bundle exec bin/toolbox docgen > doc/resource_types.md
|
67
|
+
|
68
|
+
- name: Run tests
|
69
|
+
run: bundle exec rake spec
|
@@ -0,0 +1,29 @@
|
|
1
|
+
name: Doc
|
2
|
+
|
3
|
+
on:
|
4
|
+
schedule:
|
5
|
+
- cron: '0 0 * * 0'
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
doc:
|
9
|
+
name: Document
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
env:
|
12
|
+
DISABLE_AWS_CLIENT_CHECK: true
|
13
|
+
steps:
|
14
|
+
- name: Checkout
|
15
|
+
uses: actions/checkout@v2
|
16
|
+
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: '2.7'
|
21
|
+
bundler-cache: true
|
22
|
+
|
23
|
+
- name: Generate document
|
24
|
+
run: bundle exec bin/toolbox docgen > doc/resource_types.md
|
25
|
+
|
26
|
+
- uses: EndBug/add-and-commit@v7
|
27
|
+
with:
|
28
|
+
default_author: github_actions
|
29
|
+
add: 'doc/resource_types.md'
|
data/.rubocop.yml
CHANGED
@@ -10,12 +10,24 @@ Layout/MultilineOperationIndentation:
|
|
10
10
|
Layout/MultilineMethodCallBraceLayout:
|
11
11
|
Enabled: false
|
12
12
|
|
13
|
+
Layout/ClosingHeredocIndentation:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Layout/SpaceInsideArrayLiteralBrackets:
|
17
|
+
Enabled: false
|
18
|
+
|
13
19
|
Lint/HandleExceptions:
|
14
20
|
Enabled: false
|
15
21
|
|
16
22
|
Lint/UselessAssignment:
|
17
23
|
Enabled: false
|
18
24
|
|
25
|
+
Lint/DuplicateMethods:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Lint/MissingCopEnableDirective:
|
29
|
+
Enabled: false
|
30
|
+
|
19
31
|
Metrics/AbcSize:
|
20
32
|
Max: 50
|
21
33
|
|
@@ -41,7 +53,13 @@ Metrics/ModuleLength:
|
|
41
53
|
Metrics/PerceivedComplexity:
|
42
54
|
Max: 15
|
43
55
|
|
44
|
-
|
56
|
+
Naming/UncommunicativeMethodParamName:
|
57
|
+
Enabled: false
|
58
|
+
|
59
|
+
Naming/PredicateName:
|
60
|
+
Enabled: false
|
61
|
+
|
62
|
+
Naming/HeredocDelimiterNaming:
|
45
63
|
Enabled: false
|
46
64
|
|
47
65
|
Performance/StringReplacement:
|
@@ -65,7 +83,10 @@ Style/ClassAndModuleChildren:
|
|
65
83
|
Style/Documentation:
|
66
84
|
Enabled: false
|
67
85
|
|
68
|
-
Style/
|
86
|
+
Style/MethodMissingSuper:
|
87
|
+
Enabled: false
|
88
|
+
|
89
|
+
Style/MissingRespondToMissing:
|
69
90
|
Enabled: false
|
70
91
|
|
71
92
|
Style/MutableConstant:
|
@@ -91,3 +112,27 @@ Style/SymbolProc:
|
|
91
112
|
|
92
113
|
Style/YodaCondition:
|
93
114
|
Enabled: false
|
115
|
+
|
116
|
+
Style/RescueStandardError:
|
117
|
+
Enabled: false
|
118
|
+
|
119
|
+
Style/RedundantReturn:
|
120
|
+
Enabled: false
|
121
|
+
|
122
|
+
Style/ConditionalAssignment:
|
123
|
+
Enabled: false
|
124
|
+
|
125
|
+
Style/EvalWithLocation:
|
126
|
+
Enabled: false
|
127
|
+
|
128
|
+
Style/MixinUsage:
|
129
|
+
Exclude:
|
130
|
+
- 'lib/awspec/helper.rb'
|
131
|
+
|
132
|
+
Style/StderrPuts:
|
133
|
+
Exclude:
|
134
|
+
- 'lib/awspec/generator/template.rb'
|
135
|
+
- 'lib/awspec/setup.rb'
|
136
|
+
|
137
|
+
Style/IfUnlessModifier:
|
138
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
# awspec [![Gem](https://img.shields.io/gem/v/awspec.svg)](https://rubygems.org/gems/awspec) [![
|
1
|
+
# awspec [![Gem](https://img.shields.io/gem/v/awspec.svg)](https://rubygems.org/gems/awspec) [![CI](https://github.com/k1LoW/awspec/actions/workflows/ci.yml/badge.svg)](https://github.com/k1LoW/awspec/actions)
|
2
2
|
|
3
3
|
![Logo](./awspec-logo.png)
|
4
4
|
|
5
5
|
RSpec tests for your AWS resources.
|
6
6
|
|
7
|
-
[![Join the chat at https://gitter.im/k1LoW/awspec](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/k1LoW/awspec?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
8
|
-
|
9
7
|
[Resource Types](doc/resource_types.md) | [Contributing](doc/contributing.md)
|
10
8
|
|
11
9
|
## Installation
|
data/Rakefile
CHANGED
data/awspec.gemspec
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
4
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
3
|
require 'awspec/version'
|
6
4
|
|
@@ -21,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
21
19
|
spec.require_paths = ['lib']
|
22
20
|
|
23
21
|
spec.required_ruby_version = '>= 2.1'
|
22
|
+
spec.add_runtime_dependency 'addressable'
|
24
23
|
spec.add_runtime_dependency 'aws-sdk', '~> 3'
|
25
24
|
spec.add_runtime_dependency 'awsecrets', '~> 1'
|
26
25
|
spec.add_runtime_dependency 'dry-inflector'
|
@@ -29,10 +28,9 @@ Gem::Specification.new do |spec|
|
|
29
28
|
spec.add_runtime_dependency 'rspec-its'
|
30
29
|
spec.add_runtime_dependency 'term-ansicolor'
|
31
30
|
spec.add_runtime_dependency 'thor'
|
32
|
-
spec.add_runtime_dependency 'addressable'
|
33
31
|
spec.add_development_dependency 'bundler', '>= 1.9', '< 3.0'
|
34
32
|
spec.add_development_dependency 'octorelease'
|
35
33
|
spec.add_development_dependency 'pry'
|
36
34
|
spec.add_development_dependency 'rake', '~> 12.0'
|
37
|
-
spec.add_development_dependency 'rubocop', '~> 0.
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 0.57.0'
|
38
36
|
end
|
@@ -21,6 +21,15 @@ describe cloudwatch_logs('my-cloudwatch-logs-group') do
|
|
21
21
|
it { should have_metric_filter('my-cloudwatch-logs-metric-filter') }
|
22
22
|
end
|
23
23
|
```
|
24
|
+
or
|
25
|
+
```ruby
|
26
|
+
describe cloudwatch_logs('my-cloudwatch-logs-group') do
|
27
|
+
it do
|
28
|
+
should have_metric_filter('my-cloudwatch-logs-metric-filter')
|
29
|
+
.filter_pattern('[date, error]')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
24
33
|
|
25
34
|
### have_subscription_filter
|
26
35
|
|
@@ -5,6 +5,25 @@ describe eks_nodegroup('my-eks-nodegroup'), cluster: 'my-cluster' do
|
|
5
5
|
it { should exist }
|
6
6
|
end
|
7
7
|
```
|
8
|
+
|
9
|
+
### have_security_group
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
describe eks_nodegroup('my-eks-nodegroup'), cluster: 'my-cluster' do
|
13
|
+
it { should have_security_group('sg-1a2b3cd4') }
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
### scaling_config
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
describe eks_nodegroup('my-eks-nodegroup'), cluster: 'my-cluster' do
|
21
|
+
its('scaling_config.min_size') { should eq 1 }
|
22
|
+
its('scaling_config.desired_size') { should eq 2 }
|
23
|
+
its('scaling_config.max_size') { should eq 3 }
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
8
27
|
### be_active, be_creating
|
9
28
|
|
10
29
|
```ruby
|
@@ -12,3 +31,37 @@ describe eks('my-eks-nodegroup'), cluster: 'my-cluster' do
|
|
12
31
|
it { should be_active }
|
13
32
|
end
|
14
33
|
```
|
34
|
+
|
35
|
+
### be_ready
|
36
|
+
|
37
|
+
This matcher *might* not be exactly you are expecting: it is different from what
|
38
|
+
you can see when looking at the AWS console at the Node Groups configuration
|
39
|
+
and check if the nodes Status is "Ready".
|
40
|
+
|
41
|
+
What you seeing over there is
|
42
|
+
[actually the same thing](https://aws.amazon.com/premiumsupport/knowledge-center/eks-node-status-ready/)
|
43
|
+
you would if using `kubectl`.
|
44
|
+
|
45
|
+
This matcher cannot do the same because it would involve using the Kubernetes
|
46
|
+
API: the AWS Ruby SDK currently doesn't expose this information.
|
47
|
+
|
48
|
+
What you can get from `be_ready` matcher is asserting that you have **at least**
|
49
|
+
the number of EC2 instances (the nodes in your EKS Node Group) are actually
|
50
|
+
in running state. It doesn't mean everything is fine, the node (EC2 instance)
|
51
|
+
can be running but without communication with the cluster or any order issue
|
52
|
+
regarding the Kubernetes configuration.
|
53
|
+
|
54
|
+
Although it might look an incomplete assertion, definitely the Node Group
|
55
|
+
"Status" won't be "Active" if the EC2 instances associated with it are not
|
56
|
+
running.
|
57
|
+
|
58
|
+
So, using this assertion like the sample below:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
describe eks('my-eks-nodegroup'), cluster: 'my-cluster' do
|
62
|
+
it { should be_ready }
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
Will pass if at least the minimum expected (see `scaling_config`) number of EC2
|
67
|
+
instances are running.
|
data/doc/resource_types.md
CHANGED
@@ -836,7 +836,7 @@ describe directconnect_virtual_interface('my-directconnect-virtual-interface') d
|
|
836
836
|
end
|
837
837
|
```
|
838
838
|
|
839
|
-
### its(:owner_account), its(:virtual_interface_id), its(:location), its(:connection_id), its(:virtual_interface_type), its(:virtual_interface_name), its(:vlan), its(:asn), its(:amazon_side_asn), its(:auth_key), its(:amazon_address), its(:customer_address), its(:address_family), its(:virtual_interface_state), its(:customer_router_config), its(:mtu), its(:jumbo_frame_capable), its(:virtual_gateway_id), its(:direct_connect_gateway_id), its(:route_filter_prefixes), its(:bgp_peers), its(:region), its(:aws_device_v2), its(:tags)
|
839
|
+
### its(:owner_account), its(:virtual_interface_id), its(:location), its(:connection_id), its(:virtual_interface_type), its(:virtual_interface_name), its(:vlan), its(:asn), its(:amazon_side_asn), its(:auth_key), its(:amazon_address), its(:customer_address), its(:address_family), its(:virtual_interface_state), its(:customer_router_config), its(:mtu), its(:jumbo_frame_capable), its(:virtual_gateway_id), its(:direct_connect_gateway_id), its(:route_filter_prefixes), its(:bgp_peers), its(:region), its(:aws_device_v2), its(:aws_logical_device_id), its(:tags)
|
840
840
|
## <a name="dynamodb_table">dynamodb_table</a>
|
841
841
|
|
842
842
|
DynamodbTable resource type.
|
@@ -1370,9 +1370,53 @@ describe eks_nodegroup('my-eks-nodegroup'), cluster: 'my-cluster' do
|
|
1370
1370
|
end
|
1371
1371
|
```
|
1372
1372
|
|
1373
|
+
|
1373
1374
|
### be_active, be_inactive
|
1374
1375
|
|
1375
|
-
###
|
1376
|
+
### be_ready
|
1377
|
+
|
1378
|
+
This matcher *might* not be exactly you are expecting: it is different from what
|
1379
|
+
you can see when looking at the AWS console at the Node Groups configuration
|
1380
|
+
and check if the nodes Status is "Ready".
|
1381
|
+
|
1382
|
+
What you seeing over there is
|
1383
|
+
[actually the same thing](https://aws.amazon.com/premiumsupport/knowledge-center/eks-node-status-ready/)
|
1384
|
+
you would if using `kubectl`.
|
1385
|
+
|
1386
|
+
This matcher cannot do the same because it would involve using the Kubernetes
|
1387
|
+
API: the AWS Ruby SDK currently doesn't expose this information.
|
1388
|
+
|
1389
|
+
What you can get from `be_ready` matcher is asserting that you have **at least**
|
1390
|
+
the number of EC2 instances (the nodes in your EKS Node Group) are actually
|
1391
|
+
in running state. It doesn't mean everything is fine, the node (EC2 instance)
|
1392
|
+
can be running but without communication with the cluster or any order issue
|
1393
|
+
regarding the Kubernetes configuration.
|
1394
|
+
|
1395
|
+
Although it might look an incomplete assertion, definitely the Node Group
|
1396
|
+
"Status" won't be "Active" if the EC2 instances associated with it are not
|
1397
|
+
running.
|
1398
|
+
|
1399
|
+
So, using this assertion like the sample below:
|
1400
|
+
|
1401
|
+
```ruby
|
1402
|
+
describe eks('my-eks-nodegroup'), cluster: 'my-cluster' do
|
1403
|
+
it { should be_ready }
|
1404
|
+
end
|
1405
|
+
```
|
1406
|
+
|
1407
|
+
Will pass if at least the minimum expected (see `scaling_config`) number of EC2
|
1408
|
+
instances are running.
|
1409
|
+
|
1410
|
+
### have_security_group
|
1411
|
+
|
1412
|
+
```ruby
|
1413
|
+
describe eks_nodegroup('my-eks-nodegroup'), cluster: 'my-cluster' do
|
1414
|
+
it { should have_security_group('sg-1a2b3cd4') }
|
1415
|
+
end
|
1416
|
+
```
|
1417
|
+
|
1418
|
+
|
1419
|
+
### its(:nodegroup_name), its(:nodegroup_arn), its(:cluster_name), its(:version), its(:release_version), its(:created_at), its(:modified_at), its(:status), its(:capacity_type), its(:instance_types), its(:subnets), its(:remote_access), its(:ami_type), its(:node_role), its(:labels), its(:taints), its(:resources), its(:disk_size), its(:health), its(:update_config), its(:launch_template), its(:tags)
|
1376
1420
|
## <a name="elasticache">elasticache</a>
|
1377
1421
|
|
1378
1422
|
Elasticache resource type.
|
@@ -2573,7 +2617,7 @@ describe network_interface('eni-12ab3cde') do
|
|
2573
2617
|
end
|
2574
2618
|
```
|
2575
2619
|
|
2576
|
-
### its(:association), its(:availability_zone), its(:description), its(:interface_type), its(:ipv_6_addresses), its(:mac_address), its(:network_interface_id), its(:outpost_arn), its(:owner_id), its(:private_dns_name), its(:private_ip_address), its(:requester_id), its(:requester_managed), its(:source_dest_check), its(:status), its(:subnet_id), its(:vpc_id)
|
2620
|
+
### its(:association), its(:availability_zone), its(:description), its(:interface_type), its(:ipv_6_addresses), its(:mac_address), its(:network_interface_id), its(:outpost_arn), its(:owner_id), its(:private_dns_name), its(:private_ip_address), its(:ipv_4_prefixes), its(:ipv_6_prefixes), its(:requester_id), its(:requester_managed), its(:source_dest_check), its(:status), its(:subnet_id), its(:vpc_id)
|
2577
2621
|
## <a name="nlb">nlb</a>
|
2578
2622
|
|
2579
2623
|
NLB resource type.
|
@@ -2801,7 +2845,7 @@ end
|
|
2801
2845
|
```
|
2802
2846
|
|
2803
2847
|
|
2804
|
-
### 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(:replica_mode), its(:license_model), its(:iops), its(:character_set_name), its(:nchar_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(:associated_roles), its(:listener_endpoint), its(:max_allocated_storage), its(:tag_list), its(:db_instance_automated_backups_replications), its(:customer_owned_ip_enabled), its(:aws_backup_recovery_point_arn), its(:activity_stream_status), its(:activity_stream_kms_key_id), its(:activity_stream_kinesis_stream_name), its(:activity_stream_mode), its(:activity_stream_engine_native_audit_fields_included)
|
2848
|
+
### its(:vpc_id), its(:db_instance_identifier), its(:db_instance_class), its(:engine), its(:db_instance_status), its(:automatic_restart_time), 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(:replica_mode), its(:license_model), its(:iops), its(:character_set_name), its(:nchar_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(:associated_roles), its(:listener_endpoint), its(:max_allocated_storage), its(:tag_list), its(:db_instance_automated_backups_replications), its(:customer_owned_ip_enabled), its(:aws_backup_recovery_point_arn), its(:activity_stream_status), its(:activity_stream_kms_key_id), its(:activity_stream_kinesis_stream_name), its(:activity_stream_mode), its(:activity_stream_engine_native_audit_fields_included)
|
2805
2849
|
### :unlock: Advanced use
|
2806
2850
|
|
2807
2851
|
`rds` can use `Aws::RDS::DBInstance` resource (see http://docs.aws.amazon.com/sdkforruby/api/Aws/RDS/DBInstance.html).
|
@@ -23,7 +23,11 @@ module Awspec::Generator
|
|
23
23
|
metric_filters = select_all_cloudwatch_logs_metric_filter(log_group)
|
24
24
|
metric_filter_lines = []
|
25
25
|
metric_filters.each do |metric_filter|
|
26
|
-
line = "it { should have_metric_filter('#{metric_filter.filter_name}')
|
26
|
+
line = "it { should have_metric_filter('#{metric_filter.filter_name}')"
|
27
|
+
unless metric_filter.filter_pattern.empty?
|
28
|
+
line += ".filter_pattern('#{metric_filter.filter_pattern}')"
|
29
|
+
end
|
30
|
+
line += ' }'
|
27
31
|
metric_filter_lines.push(line)
|
28
32
|
end
|
29
33
|
metric_filter_lines
|
@@ -3,24 +3,48 @@ module Awspec::Helper
|
|
3
3
|
module Ec2
|
4
4
|
def find_ec2(id)
|
5
5
|
# instance_id or tag:Name
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
6
|
+
|
7
|
+
# First tries to search by using an educated guess, based on the
|
8
|
+
# references below:
|
9
|
+
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/resource-ids.html
|
10
|
+
# https://docs.chef.io/inspec/resources/aws_ec2_instance/
|
11
|
+
# This should be faster then just first trying ID when the parameter is
|
12
|
+
# clearly not one
|
13
|
+
|
14
|
+
# https://medium.com/@Bakku1505/ruby-start-with-end-with-vs-regular-expressions-59728be0859e
|
15
|
+
if id.start_with?('i-') && id.length == 19 && id =~ /^i-[0-9a-f]/
|
16
|
+
begin
|
17
|
+
res = ec2_client.describe_instances({
|
18
|
+
instance_ids: [id]
|
19
|
+
})
|
20
|
+
rescue Aws::EC2::Errors::InvalidInstanceIDNotFound, Aws::EC2::Errors::InvalidInstanceIDMalformed => e
|
21
|
+
res = ec2_client.describe_instances({
|
22
|
+
filters: [{ name: 'tag:Name', values: [id] }]
|
23
|
+
})
|
24
|
+
end
|
25
|
+
else
|
26
|
+
begin
|
27
|
+
res = ec2_client.describe_instances({
|
28
|
+
filters: [{ name: 'tag:Name', values: [id] }]
|
29
|
+
})
|
30
|
+
rescue Aws::EC2::Errors::InvalidInstanceIDNotFound, Aws::EC2::Errors::InvalidInstanceIDMalformed => e
|
31
|
+
res = ec2_client.describe_instances({
|
32
|
+
instance_ids: [id]
|
33
|
+
})
|
34
|
+
if res.reservations.count > 1
|
35
|
+
STDERR.puts "Warning: '#{id}' unexpectedly identified as a valid instance ID during fallback search"
|
36
|
+
end
|
37
|
+
end
|
23
38
|
end
|
39
|
+
|
40
|
+
return nil if res.reservations.count == 0
|
41
|
+
return res.reservations.first.instances.single_resource(id) if res.reservations.count == 1
|
42
|
+
raise Awspec::DuplicatedResourceTypeError, dup_ec2_instance(id) if res.reservations.count > 1
|
43
|
+
raise "Unexpected condition of having reservations = #{res.reservations.count}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def dup_ec2_instance(id)
|
47
|
+
"Duplicate instances matching id or tag #{id}"
|
24
48
|
end
|
25
49
|
|
26
50
|
def find_ec2_attribute(id, attribute)
|
@@ -36,7 +36,7 @@ module Awspec::Helper
|
|
36
36
|
# deprecated method
|
37
37
|
def find_ecs_container_instances(cluster, container_instances)
|
38
38
|
res = ecs_client.describe_container_instances(cluster: cluster, container_instances: container_instances)
|
39
|
-
res.container_instances if res.container_instances
|
39
|
+
res.container_instances if res.container_instances # rubocop:disable Style/UnneededCondition
|
40
40
|
end
|
41
41
|
|
42
42
|
alias_method :list_ecs_container_instances, :select_ecs_container_instance_arn_by_cluster_name # deprecated method
|
data/lib/awspec/matcher.rb
CHANGED
@@ -4,6 +4,9 @@ require 'awspec/matcher/belong_to_subnet'
|
|
4
4
|
require 'awspec/matcher/have_tag'
|
5
5
|
require 'awspec/matcher/have_network_interface'
|
6
6
|
|
7
|
+
# EKS
|
8
|
+
require 'awspec/matcher/belong_to_subnets'
|
9
|
+
|
7
10
|
# RDS
|
8
11
|
require 'awspec/matcher/belong_to_db_subnet_group'
|
9
12
|
require 'awspec/matcher/have_db_parameter_group'
|
@@ -53,6 +56,7 @@ require 'awspec/matcher/have_rule'
|
|
53
56
|
|
54
57
|
# CloudWatch Logs
|
55
58
|
require 'awspec/matcher/have_subscription_filter'
|
59
|
+
require 'awspec/matcher/have_metric_filter'
|
56
60
|
|
57
61
|
# DynamoDB
|
58
62
|
require 'awspec/matcher/have_attribute_definition'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
RSpec::Matchers.define :belong_to_subnets do |*subnets|
|
2
|
+
match do |nodegroup|
|
3
|
+
superset = Set.new(subnets)
|
4
|
+
nodegroup.subnets.subset?(superset)
|
5
|
+
end
|
6
|
+
failure_message { |nodegroup| super() + failure_reason(nodegroup) }
|
7
|
+
failure_message_when_negated { |nodegroup| super() + failure_reason(nodegroup) }
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def failure_reason(nodegroup)
|
13
|
+
", but the nodes are allocated to the subnets #{nodegroup.subnets.to_a}"
|
14
|
+
end
|
data/lib/awspec/setup.rb
CHANGED
@@ -9,8 +9,68 @@ Aws.config[:eks] = {
|
|
9
9
|
nodegroup_arn: 'arn:aws:eks:us-west-2:012345678910:nodegroup/my-cluster/my-nodegroup/08bd000a',
|
10
10
|
created_at: Time.parse('2018-10-28 00:23:32 -0400'),
|
11
11
|
node_role: 'arn:aws:iam::012345678910:role/eks-nodegroup-role',
|
12
|
-
status: 'ACTIVE'
|
12
|
+
status: 'ACTIVE',
|
13
|
+
scaling_config: { min_size: 1, desired_size: 2, max_size: 3 }
|
13
14
|
}
|
14
15
|
}
|
15
16
|
}
|
16
17
|
}
|
18
|
+
|
19
|
+
Aws.config[:ec2] = {
|
20
|
+
stub_responses: {
|
21
|
+
describe_instances: {
|
22
|
+
reservations: [
|
23
|
+
{
|
24
|
+
instances: [
|
25
|
+
{
|
26
|
+
instance_id: 'i-ec12345a',
|
27
|
+
image_id: 'ami-abc12def',
|
28
|
+
vpc_id: 'vpc-ab123cde',
|
29
|
+
subnet_id: 'subnet-1234a567',
|
30
|
+
public_ip_address: '123.0.456.789',
|
31
|
+
private_ip_address: '10.0.1.1',
|
32
|
+
instance_type: 't2.small',
|
33
|
+
state: {
|
34
|
+
name: 'running'
|
35
|
+
},
|
36
|
+
security_groups: [
|
37
|
+
{
|
38
|
+
group_id: 'sg-1a2b3cd4',
|
39
|
+
group_name: 'my-security-group-name'
|
40
|
+
}
|
41
|
+
],
|
42
|
+
iam_instance_profile: {
|
43
|
+
arn: 'arn:aws:iam::123456789012:instance-profile/Ec2IamProfileName',
|
44
|
+
id: 'ABCDEFGHIJKLMNOPQRSTU'
|
45
|
+
},
|
46
|
+
block_device_mappings: [
|
47
|
+
{
|
48
|
+
device_name: '/dev/sda',
|
49
|
+
ebs: {
|
50
|
+
volume_id: 'vol-123a123b'
|
51
|
+
}
|
52
|
+
}
|
53
|
+
],
|
54
|
+
network_interfaces: [
|
55
|
+
{
|
56
|
+
network_interface_id: 'eni-12ab3cde',
|
57
|
+
subnet_id: 'subnet-1234a567',
|
58
|
+
vpc_id: 'vpc-ab123cde',
|
59
|
+
attachment: {
|
60
|
+
device_index: 1
|
61
|
+
}
|
62
|
+
}
|
63
|
+
],
|
64
|
+
tags: [
|
65
|
+
{
|
66
|
+
key: 'Name',
|
67
|
+
value: 'my-ec2'
|
68
|
+
}
|
69
|
+
]
|
70
|
+
}
|
71
|
+
]
|
72
|
+
}
|
73
|
+
]
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
@@ -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)
|
18
|
-
|
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,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
|
data/lib/awspec/version.rb
CHANGED
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.
|
4
|
+
version: 1.24.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- k1LoW
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-09 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.
|
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.
|
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
|
@@ -539,6 +539,7 @@ files:
|
|
539
539
|
- lib/awspec/matcher/belong_to_nlb.rb
|
540
540
|
- lib/awspec/matcher/belong_to_replication_group.rb
|
541
541
|
- lib/awspec/matcher/belong_to_subnet.rb
|
542
|
+
- lib/awspec/matcher/belong_to_subnets.rb
|
542
543
|
- lib/awspec/matcher/belong_to_vpc.rb
|
543
544
|
- lib/awspec/matcher/have_attribute_definition.rb
|
544
545
|
- lib/awspec/matcher/have_cluster_parameter_group.rb
|
@@ -550,6 +551,7 @@ files:
|
|
550
551
|
- lib/awspec/matcher/have_inline_policy.rb
|
551
552
|
- lib/awspec/matcher/have_key_policy.rb
|
552
553
|
- lib/awspec/matcher/have_key_schema.rb
|
554
|
+
- lib/awspec/matcher/have_metric_filter.rb
|
553
555
|
- lib/awspec/matcher/have_network_interface.rb
|
554
556
|
- lib/awspec/matcher/have_option_group.rb
|
555
557
|
- lib/awspec/matcher/have_origin.rb
|
@@ -750,7 +752,7 @@ homepage: https://github.com/k1LoW/awspec
|
|
750
752
|
licenses:
|
751
753
|
- MIT
|
752
754
|
metadata: {}
|
753
|
-
post_install_message:
|
755
|
+
post_install_message:
|
754
756
|
rdoc_options: []
|
755
757
|
require_paths:
|
756
758
|
- lib
|
@@ -765,8 +767,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
765
767
|
- !ruby/object:Gem::Version
|
766
768
|
version: '0'
|
767
769
|
requirements: []
|
768
|
-
rubygems_version: 3.
|
769
|
-
signing_key:
|
770
|
+
rubygems_version: 3.0.3
|
771
|
+
signing_key:
|
770
772
|
specification_version: 4
|
771
773
|
summary: RSpec tests for your AWS resources.
|
772
774
|
test_files: []
|
data/.tachikoma.yml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
strategy: 'bundler'
|
data/.travis.yml
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
---
|
2
|
-
language: ruby
|
3
|
-
env:
|
4
|
-
global:
|
5
|
-
DISABLE_AWS_CLIENT_CHECK: true
|
6
|
-
matrix:
|
7
|
-
include:
|
8
|
-
- rvm: 2.7.3
|
9
|
-
env: RUBYGEMS_VERSION=
|
10
|
-
- rvm: 2.6.2
|
11
|
-
env: RUBYGEMS_VERSION=
|
12
|
-
- rvm: 2.5.3
|
13
|
-
env: RUBYGEMS_VERSION=
|
14
|
-
- rvm: 2.4.5
|
15
|
-
env: RUBYGEMS_VERSION=
|
16
|
-
- rvm: 2.3.8
|
17
|
-
env: RUBYGEMS_VERSION=
|
18
|
-
- rvm: 2.2.10
|
19
|
-
env: RUBYGEMS_VERSION=2.7.8
|
20
|
-
- rvm: 2.1.10
|
21
|
-
env: RUBYGEMS_VERSION=2.7.8
|
22
|
-
before_install:
|
23
|
-
- gem update --system ${RUBYGEMS_VERSION}
|
24
|
-
- gem pristine bundler
|
25
|
-
|
26
|
-
script:
|
27
|
-
- bundle exec rake spec
|