awspec 0.1.1 → 0.2.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 +4 -4
- data/README.md +25 -5
- data/Rakefile +5 -1
- data/lib/awspec.rb +2 -1
- data/lib/awspec/cli.rb +6 -1
- data/lib/awspec/command/generate.rb +32 -0
- data/lib/awspec/ext.rb +2 -0
- data/lib/awspec/ext/struct.rb +8 -0
- data/lib/awspec/generator.rb +4 -0
- data/lib/awspec/generator/spec/ec2.rb +63 -0
- data/lib/awspec/generator/spec/rds.rb +62 -0
- data/lib/awspec/generator/spec/security_group.rb +78 -0
- data/lib/awspec/generator/spec/vpc.rb +57 -0
- data/lib/awspec/helper.rb +1 -0
- data/lib/awspec/helper/finder.rb +27 -0
- data/lib/awspec/helper/finder/ec2.rb +86 -0
- data/lib/awspec/helper/finder/rds.rb +21 -0
- data/lib/awspec/helper/finder/route53.rb +25 -0
- data/lib/awspec/helper/finder/s3.rb +12 -0
- data/lib/awspec/helper/finder/security_group.rb +30 -0
- data/lib/awspec/helper/finder/vpc.rb +52 -0
- data/lib/awspec/matcher/belong_to_subnet.rb +7 -9
- data/lib/awspec/setup.rb +1 -0
- data/lib/awspec/type/base.rb +4 -87
- data/lib/awspec/type/ec2.rb +3 -2
- data/lib/awspec/type/rds.rb +1 -6
- data/lib/awspec/type/rds_db_parameter_group.rb +1 -2
- data/lib/awspec/type/route53_hosted_zone.rb +3 -24
- data/lib/awspec/type/s3.rb +9 -14
- data/lib/awspec/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb7c243a9fcad6c31ac22a4f8d66f1bff11e6b66
|
4
|
+
data.tar.gz: 6af37940f727d37bbde405cde5973b4364f5fc19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19de496aad11f977031078076db13d590ed151c22ca363157c4feec97dee1555ec26d8ff01709aa02081aecd3491145fac1b8b925eef891ad71a981df9fe5454
|
7
|
+
data.tar.gz: e9a60c8719d3585f7dbd058bc4f3b2d940e6803093a9de060f9ba8f709dc4e440cfaeb2835130ae6e2a52282157b8e028826691f1d707b208eab2682a8302ed5
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# awspec [](https://rubygems.org/gems/awspec) [](https://travis-ci.org/k1LoW/awspec)
|
2
2
|
|
3
|
-
RSpec tests for your AWS resources
|
3
|
+
RSpec tests for your AWS resources.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -20,11 +20,21 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
### 1. Generate awspec
|
23
|
+
### 1. Generate awspec init files
|
24
24
|
|
25
25
|
$ awspec init
|
26
26
|
|
27
|
-
### 2.
|
27
|
+
### 2. Set AWS region/aws_access_key_id/aws_secret_access_key
|
28
|
+
|
29
|
+
```sh
|
30
|
+
$ cat <<EOF > spec/secrets.yml
|
31
|
+
region: ap-northeast-1
|
32
|
+
aws_access_key_id: XXXXXXXXXXXXXXXXXXXX
|
33
|
+
aws_secret_access_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
34
|
+
EOF
|
35
|
+
```
|
36
|
+
|
37
|
+
### 3. Write spec/*_spec.rb
|
28
38
|
|
29
39
|
```ruby
|
30
40
|
describe ec2('my-ec2-tag-name') do
|
@@ -39,6 +49,14 @@ describe ec2('my-ec2-tag-name') do
|
|
39
49
|
end
|
40
50
|
```
|
41
51
|
|
52
|
+
### Advanced Usage: Spec generate command
|
53
|
+
|
54
|
+
Generate spec from AWS resources already exists.
|
55
|
+
|
56
|
+
```sh
|
57
|
+
$ awspec generate ec2 vpc-ab123cde >> spec/ec2_spec.rb
|
58
|
+
```
|
59
|
+
|
42
60
|
## Support AWS Resources
|
43
61
|
|
44
62
|
- [X] EC2 (`ec2`)
|
@@ -58,7 +76,7 @@ end
|
|
58
76
|
## TODO
|
59
77
|
|
60
78
|
- [ ] Comment format for Document generation
|
61
|
-
- [
|
79
|
+
- [X] Spec generate command
|
62
80
|
|
63
81
|
## Contributing
|
64
82
|
|
@@ -70,6 +88,8 @@ end
|
|
70
88
|
|
71
89
|
## References
|
72
90
|
|
91
|
+
awspec is inspired by Serverspec.
|
92
|
+
|
73
93
|
- Original idea (code / architecture) -> [Serverspec](https://github.com/serverspec/serverspec)
|
74
|
-
-
|
94
|
+
- `AWS + Serverspec` original concept -> https://github.com/marcy-terui/awspec
|
75
95
|
- [Serverspec book](http://www.oreilly.co.jp/books/9784873117096/)
|
data/Rakefile
CHANGED
@@ -7,10 +7,14 @@ end
|
|
7
7
|
if defined?(RSpec)
|
8
8
|
task spec: 'spec:all'
|
9
9
|
namespace :spec do
|
10
|
-
task all: ['spec:type']
|
10
|
+
task all: ['spec:type', 'spec:generator']
|
11
11
|
|
12
12
|
RSpec::Core::RakeTask.new(:type) do |t|
|
13
13
|
t.pattern = 'spec/type/*_spec.rb'
|
14
14
|
end
|
15
|
+
|
16
|
+
RSpec::Core::RakeTask.new(:generator) do |t|
|
17
|
+
t.pattern = 'spec/generator/*_spec.rb'
|
18
|
+
end
|
15
19
|
end
|
16
20
|
end
|
data/lib/awspec.rb
CHANGED
data/lib/awspec/cli.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'awspec/setup'
|
3
|
+
require 'awspec/command/generate'
|
3
4
|
|
4
5
|
module Awspec
|
5
6
|
class CLI < Thor
|
6
|
-
desc 'awspec init', 'Generate
|
7
|
+
desc 'awspec init', 'Generate init files'
|
7
8
|
def init
|
8
9
|
Awspec::Setup.run
|
9
10
|
end
|
11
|
+
|
12
|
+
desc 'awspec generate [vpc_id]', 'Generate *_spec.rb from VPC ID (or VPC "Name" tag)'
|
13
|
+
subcommand 'generate', Generate
|
14
|
+
map 'g' => 'generate'
|
10
15
|
end
|
11
16
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'awspec/setup'
|
3
|
+
|
4
|
+
module Awspec
|
5
|
+
class Generate < Thor
|
6
|
+
types = %w(
|
7
|
+
vpc ec2 rds security_group
|
8
|
+
)
|
9
|
+
|
10
|
+
types.each do |type|
|
11
|
+
desc type + ' [vpc_id]', 'Generate VPC spec from VPC ID (or VPC "Name" tag)'
|
12
|
+
define_method type do |*args|
|
13
|
+
load_secrets
|
14
|
+
vpc_id = args.first
|
15
|
+
eval "puts Awspec::Generator::Spec::#{type.to_camel_case}.new.generate_from_vpc(vpc_id)"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
no_commands do
|
20
|
+
def load_secrets
|
21
|
+
creds = YAML.load_file('spec/secrets.yml') if File.exist?('spec/secrets.yml')
|
22
|
+
creds = YAML.load_file('secrets.yml') if File.exist?('secrets.yml')
|
23
|
+
Aws.config.update({
|
24
|
+
region: creds['region'],
|
25
|
+
credentials: Aws::Credentials.new(
|
26
|
+
creds['aws_access_key_id'],
|
27
|
+
creds['aws_secret_access_key'])
|
28
|
+
}) if creds
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/awspec/ext.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module Awspec::Generator
|
2
|
+
module Spec
|
3
|
+
class Ec2
|
4
|
+
include Awspec::Helper::Finder
|
5
|
+
def generate_from_vpc(vpc_id)
|
6
|
+
describes = %w(
|
7
|
+
instance_id image_id private_dns_name public_dns_name
|
8
|
+
instance_type private_ip_address public_ip_address
|
9
|
+
)
|
10
|
+
vpc = find_vpc(vpc_id)
|
11
|
+
fail 'Not Found VPC' unless vpc
|
12
|
+
@vpc_id = vpc[:vpc_id]
|
13
|
+
@vpc_tag_name = vpc.tag_name
|
14
|
+
instances = select_ec2_by_vpc_id(@vpc_id)
|
15
|
+
specs = instances.map do |instance|
|
16
|
+
instance_id = instance[:instance_id]
|
17
|
+
instance_tag_name = instance.tag_name
|
18
|
+
subnet = find_subnet(instance.subnet_id)
|
19
|
+
subnet_tag_name = subnet.tag_name
|
20
|
+
eips = select_eip_by_instance_id(instance_id)
|
21
|
+
content = ERB.new(ec2_spec_template, nil, '-').result(binding).gsub(/^\n/, '')
|
22
|
+
end
|
23
|
+
specs.join("\n")
|
24
|
+
end
|
25
|
+
|
26
|
+
# rubocop:disable all
|
27
|
+
def ec2_spec_template
|
28
|
+
template = <<-'EOF'
|
29
|
+
<%- if instance_tag_name -%>
|
30
|
+
describe ec2('<%= instance_tag_name %>') do
|
31
|
+
<%- else -%>
|
32
|
+
describe ec2('<%= instance_id %>') do
|
33
|
+
<%- end -%>
|
34
|
+
it { should exist }
|
35
|
+
it { should be_<%= instance.state.name %> }
|
36
|
+
<% describes.each do |describe| %>
|
37
|
+
<%- if instance.key?(describe) -%>
|
38
|
+
<%- if instance[describe].is_a?(TrueClass) || instance[describe].is_a?(FalseClass) -%>
|
39
|
+
its(:<%= describe %>) { should eq <%= instance[describe] %> }
|
40
|
+
<%- else -%>
|
41
|
+
its(:<%= describe %>) { should eq '<%= instance[describe] %>' }
|
42
|
+
<%- end -%>
|
43
|
+
<%- end -%>
|
44
|
+
<% end %>
|
45
|
+
<% instance.security_groups.each do |sg| %>
|
46
|
+
it { should have_security_group('<%= sg.group_name %>') }
|
47
|
+
<% end %>
|
48
|
+
<%- if @vpc_tag_name -%>
|
49
|
+
it { should belong_to_vpc('<%= @vpc_tag_name %>') }
|
50
|
+
<%- else -%>
|
51
|
+
it { should belong_to_vpc('<%= @vpc_id %>') }
|
52
|
+
<%- end -%>
|
53
|
+
it { should belong_to_subnet('<%= subnet_tag_name %>') }
|
54
|
+
<% eips.each do |eip| %>
|
55
|
+
it { should have_eip('<%= eip.public_ip %>') }
|
56
|
+
<% end %>
|
57
|
+
end
|
58
|
+
EOF
|
59
|
+
template
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Awspec::Generator
|
2
|
+
module Spec
|
3
|
+
class Rds
|
4
|
+
include Awspec::Helper::Finder
|
5
|
+
def generate_from_vpc(vpc_id)
|
6
|
+
describes = %w(
|
7
|
+
db_instance_identifier db_instance_class multi_az availability_zone
|
8
|
+
)
|
9
|
+
vpc = find_vpc(vpc_id)
|
10
|
+
fail 'Not Found VPC' unless vpc
|
11
|
+
@vpc_id = vpc[:vpc_id]
|
12
|
+
@vpc_tag_name = vpc.tag_name
|
13
|
+
db_instances = select_rds_by_vpc_id(@vpc_id)
|
14
|
+
specs = db_instances.map do |db_instance|
|
15
|
+
instance_id = db_instance[:db_instance_identifier]
|
16
|
+
sg_group_names = db_instance[:vpc_security_groups].map do |sg|
|
17
|
+
sg_id = sg.vpc_security_group_id
|
18
|
+
ret = find_security_group(sg_id)
|
19
|
+
ret[:group_name]
|
20
|
+
end
|
21
|
+
content = ERB.new(rds_spec_template, nil, '-').result(binding).gsub(/^\n/, '')
|
22
|
+
end
|
23
|
+
specs.join("\n")
|
24
|
+
end
|
25
|
+
|
26
|
+
# rubocop:disable all
|
27
|
+
def rds_spec_template
|
28
|
+
template = <<-'EOF'
|
29
|
+
describe rds('<%= instance_id %>') do
|
30
|
+
it { should exist }
|
31
|
+
it { should be_<%= db_instance.db_instance_status %> }
|
32
|
+
<% describes.each do |describe| %>
|
33
|
+
<%- if db_instance.key?(describe) -%>
|
34
|
+
<%- if db_instance[describe].is_a?(TrueClass) || db_instance[describe].is_a?(FalseClass) -%>
|
35
|
+
its(:<%= describe %>) { should eq <%= db_instance[describe] %> }
|
36
|
+
<%- else -%>
|
37
|
+
its(:<%= describe %>) { should eq '<%= db_instance[describe] %>' }
|
38
|
+
<%- end -%>
|
39
|
+
<%- end -%>
|
40
|
+
<% end %>
|
41
|
+
<% sg_group_names.each do |sg_group_name| %>
|
42
|
+
it { should have_security_group('<%= sg_group_name %>') }
|
43
|
+
<% end %>
|
44
|
+
<%- if @vpc_tag_name -%>
|
45
|
+
it { should belong_to_vpc('<%= @vpc_tag_name %>') }
|
46
|
+
<%- else -%>
|
47
|
+
it { should belong_to_vpc('<%= @vpc_id %>') }
|
48
|
+
<%- end -%>
|
49
|
+
it { should belong_to_db_subnet_group('<%= db_instance.db_subnet_group.db_subnet_group_name %>') }
|
50
|
+
<% db_instance.db_parameter_groups.each do |pg| %>
|
51
|
+
it { should have_db_parameter_group('<%= pg.db_parameter_group_name %>') }
|
52
|
+
<% end %>
|
53
|
+
<% db_instance.option_group_memberships.each do |og| %>
|
54
|
+
it { should have_option_group('<%= og.option_group_name %>') }
|
55
|
+
<% end %>
|
56
|
+
end
|
57
|
+
EOF
|
58
|
+
template
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Awspec::Generator
|
2
|
+
module Spec
|
3
|
+
class SecurityGroup
|
4
|
+
include Awspec::Helper::Finder
|
5
|
+
def generate_from_vpc(vpc_id)
|
6
|
+
describes = %w(
|
7
|
+
group_id
|
8
|
+
)
|
9
|
+
vpc = find_vpc(vpc_id)
|
10
|
+
fail 'Not Found VPC' unless vpc
|
11
|
+
@vpc_id = vpc[:vpc_id]
|
12
|
+
@vpc_tag_name = vpc.tag_name
|
13
|
+
sgs = select_security_group_by_vpc_id(@vpc_id)
|
14
|
+
|
15
|
+
specs = sgs.map do |sg|
|
16
|
+
linespecs = generate_linespecs(sg)
|
17
|
+
content = ERB.new(security_group_spec_template, nil, '-').result(binding).gsub(/^\n/, '')
|
18
|
+
end
|
19
|
+
specs.join("\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_linespecs(sg)
|
23
|
+
linespecs = []
|
24
|
+
permissions = { 'inbound' => sg.ip_permissions, 'outbound' => sg.ip_permissions_egress }
|
25
|
+
%w(inbound outbound).each do |inout|
|
26
|
+
permissions[inout].each do |permission|
|
27
|
+
if permission.ip_protocol.to_i < 0 || permission.from_port.nil?
|
28
|
+
linespecs.push('its(:' + inout + ') { should be_opened }')
|
29
|
+
next
|
30
|
+
end
|
31
|
+
port = permission.from_port
|
32
|
+
protocol = permission.ip_protocol
|
33
|
+
permission.ip_ranges.each do |ip_range|
|
34
|
+
target = ip_range.cidr_ip
|
35
|
+
linespecs.push(ERB.new(security_group_spec_linetemplate, nil, '-').result(binding))
|
36
|
+
end
|
37
|
+
permission.user_id_group_pairs.each do |group|
|
38
|
+
target = group.group_name
|
39
|
+
linespecs.push(ERB.new(security_group_spec_linetemplate, nil, '-').result(binding))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
linespecs
|
44
|
+
end
|
45
|
+
|
46
|
+
def security_group_spec_linetemplate
|
47
|
+
template = <<-'EOF'
|
48
|
+
its(:<%= inout %>) { should be_opened(<%= port %>).protocol('<%= protocol %>').for('<%= target %>') }
|
49
|
+
EOF
|
50
|
+
template
|
51
|
+
end
|
52
|
+
|
53
|
+
def security_group_spec_template
|
54
|
+
template = <<-'EOF'
|
55
|
+
describe security_group('<%= sg.group_name %>') do
|
56
|
+
it { should exist }
|
57
|
+
<% describes.each do |describe| %>
|
58
|
+
<%- if sg.key?(describe) -%>
|
59
|
+
its(:<%= describe %>) { should eq '<%= sg[describe] %>' }
|
60
|
+
<%- end -%>
|
61
|
+
<% end %>
|
62
|
+
<% linespecs.each do |line| %>
|
63
|
+
<%= line %>
|
64
|
+
<% end %>
|
65
|
+
its(:outbound_permissions_count) { should eq <%= sg.ip_permissions.count %> }
|
66
|
+
its(:inbound_permissions_count) { should eq <%= sg.ip_permissions_egress.count %> }
|
67
|
+
<%- if @vpc_tag_name -%>
|
68
|
+
it { should belong_to_vpc('<%= @vpc_tag_name %>') }
|
69
|
+
<%- else -%>
|
70
|
+
it { should belong_to_vpc('<%= @vpc_id %>') }
|
71
|
+
<%- end -%>
|
72
|
+
end
|
73
|
+
EOF
|
74
|
+
template
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Awspec::Generator
|
2
|
+
module Spec
|
3
|
+
class Vpc
|
4
|
+
include Awspec::Helper::Finder
|
5
|
+
def generate_from_vpc(vpc_id)
|
6
|
+
describes = %w(
|
7
|
+
vpc_id cidr_block
|
8
|
+
)
|
9
|
+
vpc = find_vpc(vpc_id)
|
10
|
+
fail 'Not Found VPC' unless vpc
|
11
|
+
@vpc_id = vpc[:vpc_id]
|
12
|
+
@vpc_tag_name = vpc.tag_name
|
13
|
+
route_tables = select_route_table_by_vpc_id(@vpc_id)
|
14
|
+
network_acls = select_network_acl_by_vpc_id(@vpc_id)
|
15
|
+
spec = ERB.new(vpc_spec_template, nil, '-').result(binding).gsub(/^\n/, '')
|
16
|
+
end
|
17
|
+
|
18
|
+
# rubocop:disable all
|
19
|
+
def vpc_spec_template
|
20
|
+
template = <<-'EOF'
|
21
|
+
<%- if @vpc_tag_name -%>
|
22
|
+
describe vpc('<%= @vpc_tag_name %>') do
|
23
|
+
<%- else -%>
|
24
|
+
describe vpc('<%= @vpc_id %>') do
|
25
|
+
<%- end -%>
|
26
|
+
it { should exist }
|
27
|
+
it { should be_<%= vpc.state %> }
|
28
|
+
<% describes.each do |describe| %>
|
29
|
+
<%- if vpc.key?(describe) -%>
|
30
|
+
<%- if vpc[describe].is_a?(TrueClass) || vpc[describe].is_a?(FalseClass) -%>
|
31
|
+
its(:<%= describe %>) { should eq <%= vpc[describe] %> }
|
32
|
+
<%- else -%>
|
33
|
+
its(:<%= describe %>) { should eq '<%= vpc[describe] %>' }
|
34
|
+
<%- end -%>
|
35
|
+
<%- end -%>
|
36
|
+
<% end %>
|
37
|
+
<% route_tables.each do |route_table| %>
|
38
|
+
<%- if route_table.tag_name -%>
|
39
|
+
it { should have_route_table('<%= route_table.tag_name %>') }
|
40
|
+
<%- else -%>
|
41
|
+
it { should have_route_table('<%= route_table.route_table_id %>') }
|
42
|
+
<%- end -%>
|
43
|
+
<% end %>
|
44
|
+
<% network_acls.each do |network_acl| %>
|
45
|
+
<%- if network_acl.tag_name -%>
|
46
|
+
it { should have_network_acl('<%= network_acl.tag_name %>') }
|
47
|
+
<%- else -%>
|
48
|
+
it { should have_network_acl('<%= network_acl.network_acl_id %>') }
|
49
|
+
<%- end -%>
|
50
|
+
<% end %>
|
51
|
+
end
|
52
|
+
EOF
|
53
|
+
template
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/awspec/helper.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'awspec/helper/finder/vpc'
|
3
|
+
require 'awspec/helper/finder/ec2'
|
4
|
+
require 'awspec/helper/finder/security_group'
|
5
|
+
require 'awspec/helper/finder/rds'
|
6
|
+
require 'awspec/helper/finder/route53'
|
7
|
+
require 'awspec/helper/finder/s3'
|
8
|
+
|
9
|
+
module Awspec::Helper
|
10
|
+
module Finder
|
11
|
+
attr_reader :ec2_client
|
12
|
+
include Awspec::Helper::Finder::Vpc
|
13
|
+
include Awspec::Helper::Finder::Ec2
|
14
|
+
include Awspec::Helper::Finder::SecurityGroup
|
15
|
+
include Awspec::Helper::Finder::Rds
|
16
|
+
include Awspec::Helper::Finder::Route53
|
17
|
+
include Awspec::Helper::Finder::S3
|
18
|
+
|
19
|
+
# rubocop:disable all
|
20
|
+
def initialize(id = nil)
|
21
|
+
@ec2_client = Aws::EC2::Client.new
|
22
|
+
@rds_client = Aws::RDS::Client.new
|
23
|
+
@route53_client = Aws::Route53::Client.new
|
24
|
+
@s3_client = Aws::S3::Client.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Awspec::Helper
|
2
|
+
module Finder
|
3
|
+
module Ec2
|
4
|
+
def find_ec2(id)
|
5
|
+
if id.is_a?(Array)
|
6
|
+
# Aws::EC2::Client.describe_instances native filters format
|
7
|
+
res = @ec2_client.describe_instances({
|
8
|
+
filters: id
|
9
|
+
})
|
10
|
+
elsif id.is_a?(Hash)
|
11
|
+
# syntax sugar
|
12
|
+
filters = []
|
13
|
+
id.each do |k, v|
|
14
|
+
filters.push({ name: k, values: Array(v) })
|
15
|
+
end
|
16
|
+
res = @ec2_client.describe_instances({
|
17
|
+
filters: filters
|
18
|
+
})
|
19
|
+
else
|
20
|
+
# instance_id or tag:Name
|
21
|
+
begin
|
22
|
+
res = @ec2_client.describe_instances({
|
23
|
+
instance_ids: [id]
|
24
|
+
})
|
25
|
+
rescue
|
26
|
+
# Aws::EC2::Errors::InvalidInstanceIDMalformed
|
27
|
+
# Aws::EC2::Errors::InvalidInstanceIDNotFound
|
28
|
+
res = @ec2_client.describe_instances({
|
29
|
+
filters: [{ name: 'tag:Name', values: [id] }]
|
30
|
+
})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return res[:reservations][0][:instances][0] if res[:reservations].count == 1 && \
|
34
|
+
res[:reservations][0][:instances].count == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_subnet(subnet_id)
|
38
|
+
res = @ec2_client.describe_subnets({
|
39
|
+
filters: [{ name: 'subnet-id', values: [subnet_id] }]
|
40
|
+
})
|
41
|
+
return res[:subnets][0] if res[:subnets].count == 1
|
42
|
+
res = @ec2_client.describe_subnets({
|
43
|
+
filters: [{ name: 'tag:Name', values: [subnet_id] }]
|
44
|
+
})
|
45
|
+
return res[:subnets][0] if res[:subnets].count == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_security_group(sg_id)
|
49
|
+
res = @ec2_client.describe_security_groups({
|
50
|
+
filters: [{ name: 'group-id', values: [sg_id] }]
|
51
|
+
})
|
52
|
+
return res[:security_groups][0] if res[:security_groups].count == 1
|
53
|
+
res = @ec2_client.describe_security_groups({
|
54
|
+
filters: [{ name: 'group-name', values: [sg_id] }]
|
55
|
+
})
|
56
|
+
return res[:security_groups][0] if res[:security_groups].count == 1
|
57
|
+
res = @ec2_client.describe_security_groups({
|
58
|
+
filters: [{ name: 'tag:Name', values: [sg_id] }]
|
59
|
+
})
|
60
|
+
return res[:security_groups][0] if res[:security_groups].count == 1
|
61
|
+
end
|
62
|
+
|
63
|
+
def select_ec2_by_vpc_id(vpc_id)
|
64
|
+
res = @ec2_client.describe_instances({
|
65
|
+
filters: [{ name: 'vpc-id', values: [vpc_id] }]
|
66
|
+
})
|
67
|
+
instances = []
|
68
|
+
return instances unless res[:reservations].count > 0
|
69
|
+
res[:reservations].each do |reservation|
|
70
|
+
reservation.instances.each do |instance|
|
71
|
+
instances.push(instance)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
instances
|
75
|
+
end
|
76
|
+
|
77
|
+
def select_eip_by_instance_id(id)
|
78
|
+
res = @ec2_client.describe_addresses({
|
79
|
+
filters: [{ name: 'instance-id', values: [id] }]
|
80
|
+
})
|
81
|
+
return [] unless res[:addresses].count > 0
|
82
|
+
res[:addresses]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Awspec::Helper
|
2
|
+
module Finder
|
3
|
+
module Rds
|
4
|
+
def find_rds(id)
|
5
|
+
# db_instance_identifier
|
6
|
+
res = @rds_client.describe_db_instances({
|
7
|
+
db_instance_identifier: id
|
8
|
+
})
|
9
|
+
return res[:db_instances][0] if res[:db_instances].count == 1
|
10
|
+
end
|
11
|
+
|
12
|
+
def select_rds_by_vpc_id(vpc_id)
|
13
|
+
res = @rds_client.describe_db_instances
|
14
|
+
db_instances = res[:db_instances].select do |db_instance|
|
15
|
+
db_instance.db_subnet_group.vpc_id == vpc_id
|
16
|
+
end
|
17
|
+
db_instances
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Awspec::Helper
|
2
|
+
module Finder
|
3
|
+
module Route53
|
4
|
+
def find_hosted_zone(id)
|
5
|
+
hosted_zones = {}
|
6
|
+
marker = nil
|
7
|
+
loop do
|
8
|
+
res = @route53_client.list_hosted_zones({
|
9
|
+
marker: marker
|
10
|
+
})
|
11
|
+
marker = res.marker
|
12
|
+
break if res.hosted_zones.empty?
|
13
|
+
res.hosted_zones.each do |hosted_zone|
|
14
|
+
hosted_zones[hosted_zone[:name]] = hosted_zones
|
15
|
+
if hosted_zone[:name] == id || hosted_zone[:id] == '/hostedzone/' + id || hosted_zone[:id] == id
|
16
|
+
return hosted_zone
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
break if marker.nil?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Awspec::Helper
|
2
|
+
module Finder
|
3
|
+
module SecurityGroup
|
4
|
+
def find_security_group(id)
|
5
|
+
res = @ec2_client.describe_security_groups({
|
6
|
+
filters: [{ name: 'group-id', values: [id] }]
|
7
|
+
})
|
8
|
+
|
9
|
+
return res[:security_groups][0] if res[:security_groups].count == 1
|
10
|
+
res = @ec2_client.describe_security_groups({
|
11
|
+
filters: [{ name: 'group-name', values: [id] }]
|
12
|
+
})
|
13
|
+
|
14
|
+
return res[:security_groups][0] if res[:security_groups].count == 1
|
15
|
+
res = @ec2_client.describe_security_groups({
|
16
|
+
filters: [{ name: 'tag:Name', values: [id] }]
|
17
|
+
})
|
18
|
+
|
19
|
+
return res[:security_groups][0] if res[:security_groups].count == 1
|
20
|
+
end
|
21
|
+
|
22
|
+
def select_security_group_by_vpc_id(vpc_id)
|
23
|
+
res = @ec2_client.describe_security_groups({
|
24
|
+
filters: [{ name: 'vpc-id', values: [vpc_id] }]
|
25
|
+
})
|
26
|
+
res[:security_groups]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Awspec::Helper
|
2
|
+
module Finder
|
3
|
+
module Vpc
|
4
|
+
def find_vpc(id)
|
5
|
+
res = @ec2_client.describe_vpcs({
|
6
|
+
filters: [{ name: 'vpc-id', values: [id] }]
|
7
|
+
})
|
8
|
+
return res[:vpcs][0] if res[:vpcs].count == 1
|
9
|
+
res = @ec2_client.describe_vpcs({
|
10
|
+
filters: [{ name: 'tag:Name', values: [id] }]
|
11
|
+
})
|
12
|
+
return res[:vpcs][0] if res[:vpcs].count == 1
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_route_table(id)
|
16
|
+
res = @ec2_client.describe_route_tables({
|
17
|
+
filters: [{ name: 'route-table-id', values: [id] }]
|
18
|
+
})
|
19
|
+
return res[:route_tables][0] if res[:route_tables].count == 1
|
20
|
+
res = @ec2_client.describe_route_tables({
|
21
|
+
filters: [{ name: 'tag:Name', values: [id] }]
|
22
|
+
})
|
23
|
+
return res[:route_tables][0] if res[:route_tables].count == 1
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_network_acl(id)
|
27
|
+
res = @ec2_client.describe_network_acls({
|
28
|
+
filters: [{ name: 'network-acl-id', values: [id] }]
|
29
|
+
})
|
30
|
+
return res[:network_acls][0] if res[:network_acls].count == 1
|
31
|
+
res = @ec2_client.describe_network_acls({
|
32
|
+
filters: [{ name: 'tag:Name', values: [id] }]
|
33
|
+
})
|
34
|
+
return res[:network_acls][0] if res[:network_acls].count == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def select_route_table_by_vpc_id(vpc_id)
|
38
|
+
res = @ec2_client.describe_route_tables({
|
39
|
+
filters: [{ name: 'vpc-id', values: [vpc_id] }]
|
40
|
+
})
|
41
|
+
res[:route_tables]
|
42
|
+
end
|
43
|
+
|
44
|
+
def select_network_acl_by_vpc_id(vpc_id)
|
45
|
+
res = @ec2_client.describe_network_acls({
|
46
|
+
filters: [{ name: 'vpc-id', values: [vpc_id] }]
|
47
|
+
})
|
48
|
+
res[:network_acls]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -3,18 +3,16 @@ RSpec::Matchers.define :belong_to_subnet do |subnet_id|
|
|
3
3
|
# EC2
|
4
4
|
if resource.instance_of?(Awspec::Type::Ec2)
|
5
5
|
return true if resource.subnet_id == subnet_id
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
return false unless ret
|
10
|
-
return ret[:subnets][0][:subnet_id] == resource.subnet_id
|
6
|
+
subnet = resource.find_subnet(subnet_id)
|
7
|
+
return false unless subnet
|
8
|
+
return subnet[:subnet_id] == resource.subnet_id
|
11
9
|
end
|
12
10
|
|
13
11
|
# RDS
|
14
12
|
if resource.instance_of?(Awspec::Type::Rds)
|
15
13
|
subnets = resource.instance[:db_subnet_group][:subnets]
|
16
|
-
ret = subnets.find do |
|
17
|
-
|
14
|
+
ret = subnets.find do |s|
|
15
|
+
s[:subnet_identifier] == subnet_id
|
18
16
|
end
|
19
17
|
|
20
18
|
return ret[:subnet_availability_zone][:name] == resource.availability_zone if ret
|
@@ -23,8 +21,8 @@ RSpec::Matchers.define :belong_to_subnet do |subnet_id|
|
|
23
21
|
filters: [{ name: 'tag:Name', values: [subnet_id] }]
|
24
22
|
})
|
25
23
|
return false unless res
|
26
|
-
ret = subnets.find do |
|
27
|
-
|
24
|
+
ret = subnets.find do |s|
|
25
|
+
s[:subnet_identifier] == res[:subnets][0][:subnet_id]
|
28
26
|
end
|
29
27
|
|
30
28
|
return ret[:subnet_availability_zone][:name] == resource.availability_zone if ret
|
data/lib/awspec/setup.rb
CHANGED
data/lib/awspec/type/base.rb
CHANGED
@@ -1,101 +1,18 @@
|
|
1
1
|
require 'aws-sdk'
|
2
|
+
require 'awspec/helper/finder'
|
2
3
|
|
3
4
|
module Awspec::Type
|
4
5
|
class Base
|
5
|
-
|
6
|
+
include Awspec::Helper::Finder
|
7
|
+
attr_reader :id
|
6
8
|
|
7
|
-
# rubocop:disable all
|
8
9
|
def initialize(id = nil)
|
10
|
+
super
|
9
11
|
@id = nil
|
10
|
-
@ec2_client = Aws::EC2::Client.new
|
11
12
|
end
|
12
|
-
# rubocop:enable all
|
13
13
|
|
14
14
|
def exists?
|
15
15
|
@id
|
16
16
|
end
|
17
|
-
|
18
|
-
def find_vpc(id)
|
19
|
-
res = @ec2_client.describe_vpcs({
|
20
|
-
filters: [{ name: 'vpc-id', values: [id] }]
|
21
|
-
})
|
22
|
-
return res[:vpcs][0] if res[:vpcs].count == 1
|
23
|
-
res = @ec2_client.describe_vpcs({
|
24
|
-
filters: [{ name: 'tag:Name', values: [id] }]
|
25
|
-
})
|
26
|
-
return res[:vpcs][0] if res[:vpcs].count == 1
|
27
|
-
end
|
28
|
-
|
29
|
-
def find_route_table(id)
|
30
|
-
res = @ec2_client.describe_route_tables({
|
31
|
-
filters: [{ name: 'route-table-id', values: [id] }]
|
32
|
-
})
|
33
|
-
return res[:route_tables][0] if res[:route_tables].count == 1
|
34
|
-
res = @ec2_client.describe_route_tables({
|
35
|
-
filters: [{ name: 'tag:Name', values: [id] }]
|
36
|
-
})
|
37
|
-
return res[:route_tables][0] if res[:route_tables].count == 1
|
38
|
-
end
|
39
|
-
|
40
|
-
def find_network_acl(id)
|
41
|
-
res = @ec2_client.describe_network_acls({
|
42
|
-
filters: [{ name: 'network-acl-id', values: [id] }]
|
43
|
-
})
|
44
|
-
return res[:network_acls][0] if res[:network_acls].count == 1
|
45
|
-
res = @ec2_client.describe_network_acls({
|
46
|
-
filters: [{ name: 'tag:Name', values: [id] }]
|
47
|
-
})
|
48
|
-
return res[:network_acls][0] if res[:network_acls].count == 1
|
49
|
-
end
|
50
|
-
|
51
|
-
def find_security_group(id)
|
52
|
-
res = @ec2_client.describe_security_groups({
|
53
|
-
filters: [{ name: 'group-id', values: [id] }]
|
54
|
-
})
|
55
|
-
|
56
|
-
return res[:security_groups][0] if res[:security_groups].count == 1
|
57
|
-
res = @ec2_client.describe_security_groups({
|
58
|
-
filters: [{ name: 'group-name', values: [id] }]
|
59
|
-
})
|
60
|
-
|
61
|
-
return res[:security_groups][0] if res[:security_groups].count == 1
|
62
|
-
res = @ec2_client.describe_security_groups({
|
63
|
-
filters: [{ name: 'tag:Name', values: [id] }]
|
64
|
-
})
|
65
|
-
|
66
|
-
return res[:security_groups][0] if res[:security_groups].count == 1
|
67
|
-
end
|
68
|
-
|
69
|
-
def find_ec2(id)
|
70
|
-
if id.is_a?(Array)
|
71
|
-
# Aws::EC2::Client.describe_instances native filters format
|
72
|
-
res = @client.describe_instances({
|
73
|
-
filters: id
|
74
|
-
})
|
75
|
-
elsif id.is_a?(Hash)
|
76
|
-
# syntax sugar
|
77
|
-
filters = []
|
78
|
-
id.each do |k, v|
|
79
|
-
filters.push({ name: k, values: Array(v) })
|
80
|
-
end
|
81
|
-
res = @client.describe_instances({
|
82
|
-
filters: filters
|
83
|
-
})
|
84
|
-
else
|
85
|
-
# instance_id or tag:Name
|
86
|
-
begin
|
87
|
-
res = @client.describe_instances({
|
88
|
-
instance_ids: [id]
|
89
|
-
})
|
90
|
-
rescue
|
91
|
-
# Aws::EC2::Errors::InvalidInstanceIDMalformed
|
92
|
-
# Aws::EC2::Errors::InvalidInstanceIDNotFound
|
93
|
-
res = @client.describe_instances({
|
94
|
-
filters: [{ name: 'tag:Name', values: [id] }]
|
95
|
-
})
|
96
|
-
end
|
97
|
-
end
|
98
|
-
return res[:reservations][0][:instances][0] if res[:reservations][0][:instances].count == 1
|
99
|
-
end
|
100
17
|
end
|
101
18
|
end
|
data/lib/awspec/type/ec2.rb
CHANGED
@@ -34,8 +34,9 @@ module Awspec::Type
|
|
34
34
|
filters: [{ name: 'instance-id', values: [@id] }]
|
35
35
|
}
|
36
36
|
option[:public_ips] = [ip_address] if ip_address
|
37
|
-
ret = @
|
38
|
-
ret[:addresses].count == 1
|
37
|
+
ret = @ec2_client.describe_addresses(option)
|
38
|
+
return ret[:addresses].count == 1 if ip_address
|
39
|
+
return ret[:addresses].count > 0 unless ip_address
|
39
40
|
end
|
40
41
|
|
41
42
|
def has_security_group?(sg_id)
|
data/lib/awspec/type/rds.rb
CHANGED
@@ -4,12 +4,7 @@ module Awspec::Type
|
|
4
4
|
|
5
5
|
def initialize(id)
|
6
6
|
super
|
7
|
-
@
|
8
|
-
# db_instance_identifier
|
9
|
-
res = @client.describe_db_instances({
|
10
|
-
db_instance_identifier: id
|
11
|
-
})
|
12
|
-
@instance = res[:db_instances][0] if res[:db_instances].count == 1
|
7
|
+
@instance = find_rds(id)
|
13
8
|
@id = @instance[:db_instance_identifier] if @instance
|
14
9
|
end
|
15
10
|
|
@@ -4,12 +4,11 @@ module Awspec::Type
|
|
4
4
|
|
5
5
|
def initialize(name)
|
6
6
|
super
|
7
|
-
@client = Aws::RDS::Client.new
|
8
7
|
@parameters = {}
|
9
8
|
|
10
9
|
marker = nil
|
11
10
|
while @parameters.empty? || !marker.nil?
|
12
|
-
res = @
|
11
|
+
res = @rds_client.describe_db_parameters(
|
13
12
|
db_parameter_group_name: name,
|
14
13
|
marker: marker)
|
15
14
|
marker = res.marker
|
@@ -4,13 +4,12 @@ module Awspec::Type
|
|
4
4
|
|
5
5
|
def initialize(id)
|
6
6
|
super
|
7
|
-
@client = Aws::Route53::Client.new
|
8
7
|
@hosted_zone = find_hosted_zone(id)
|
9
8
|
@id = @hosted_zone[:id] if @hosted_zone
|
10
9
|
return unless @id
|
11
|
-
res = @
|
12
|
-
|
13
|
-
|
10
|
+
res = @route53_client.list_resource_record_sets({
|
11
|
+
hosted_zone_id: @id
|
12
|
+
})
|
14
13
|
@resource_record_sets = res.resource_record_sets
|
15
14
|
end
|
16
15
|
|
@@ -32,26 +31,6 @@ module Awspec::Type
|
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
|
-
def find_hosted_zone(id)
|
36
|
-
hosted_zones = {}
|
37
|
-
marker = nil
|
38
|
-
loop do
|
39
|
-
res = @client.list_hosted_zones({
|
40
|
-
marker: marker
|
41
|
-
})
|
42
|
-
marker = res.marker
|
43
|
-
break if res.hosted_zones.empty?
|
44
|
-
res.hosted_zones.each do |hosted_zone|
|
45
|
-
hosted_zones[hosted_zone[:name]] = hosted_zones
|
46
|
-
if hosted_zone[:name] == id || hosted_zone[:id] == '/hostedzone/' + id || hosted_zone[:id] == id
|
47
|
-
return hosted_zone
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
break if marker.nil?
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
34
|
def method_missing(name)
|
56
35
|
describe = name.to_s
|
57
36
|
if @hosted_zone.key?(describe)
|
data/lib/awspec/type/s3.rb
CHANGED
@@ -1,26 +1,21 @@
|
|
1
1
|
module Awspec::Type
|
2
2
|
class S3 < Base
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :s3_client, :bucket
|
4
4
|
|
5
5
|
def initialize(id)
|
6
6
|
super
|
7
|
-
@
|
8
|
-
|
9
|
-
ret = @client.list_buckets[:buckets].find do |bucket|
|
10
|
-
bucket.name == id
|
11
|
-
end
|
12
|
-
@id = id if ret
|
13
|
-
@bucket = ret
|
7
|
+
@bucket = find_bucket(id)
|
8
|
+
@id = id if @bucket
|
14
9
|
end
|
15
10
|
|
16
11
|
def has_object?(key)
|
17
|
-
res = @
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
res = @s3_client.head_object({
|
13
|
+
bucket: @id,
|
14
|
+
key: key.sub(%r(\A/), '')
|
15
|
+
})
|
21
16
|
res
|
22
|
-
|
23
|
-
|
17
|
+
rescue
|
18
|
+
false
|
24
19
|
end
|
25
20
|
end
|
26
21
|
end
|
data/lib/awspec/version.rb
CHANGED
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: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- k1LoW
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -127,8 +127,23 @@ files:
|
|
127
127
|
- bin/awspec
|
128
128
|
- lib/awspec.rb
|
129
129
|
- lib/awspec/cli.rb
|
130
|
+
- lib/awspec/command/generate.rb
|
131
|
+
- lib/awspec/ext.rb
|
130
132
|
- lib/awspec/ext/string.rb
|
133
|
+
- lib/awspec/ext/struct.rb
|
134
|
+
- lib/awspec/generator.rb
|
135
|
+
- lib/awspec/generator/spec/ec2.rb
|
136
|
+
- lib/awspec/generator/spec/rds.rb
|
137
|
+
- lib/awspec/generator/spec/security_group.rb
|
138
|
+
- lib/awspec/generator/spec/vpc.rb
|
131
139
|
- lib/awspec/helper.rb
|
140
|
+
- lib/awspec/helper/finder.rb
|
141
|
+
- lib/awspec/helper/finder/ec2.rb
|
142
|
+
- lib/awspec/helper/finder/rds.rb
|
143
|
+
- lib/awspec/helper/finder/route53.rb
|
144
|
+
- lib/awspec/helper/finder/s3.rb
|
145
|
+
- lib/awspec/helper/finder/security_group.rb
|
146
|
+
- lib/awspec/helper/finder/vpc.rb
|
132
147
|
- lib/awspec/helper/type.rb
|
133
148
|
- lib/awspec/matcher.rb
|
134
149
|
- lib/awspec/matcher/be_opened.rb
|