awspec 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Gem](https://img.shields.io/gem/v/awspec.svg)](https://rubygems.org/gems/awspec) [![Travis](https://img.shields.io/travis/k1LoW/awspec.svg)](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
|