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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: df207790f4376bc443bf955cd3431d61a5944f0e
4
- data.tar.gz: 2318f61037e3b4b1133f79ffcb75840ce61595fe
3
+ metadata.gz: eb7c243a9fcad6c31ac22a4f8d66f1bff11e6b66
4
+ data.tar.gz: 6af37940f727d37bbde405cde5973b4364f5fc19
5
5
  SHA512:
6
- metadata.gz: 2efb966dd21639c1dc2fb8d1e909430e5b1250fcc626897eea88031fba0cbe9423d646ae64b144caec88da1d5183eb22ae70cb8eefc6d8c7f3d8ca37cab9f28d
7
- data.tar.gz: 4864b9b8d31aa4d4224b8b8ae4510e3650ff238c5ac0411a03443135b6d313b095d084e8358727d621b5261a86dae0c09050478d3b22e8cde90cc9de3c1161c3
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 inspired by Serverspec.
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 template
23
+ ### 1. Generate awspec init files
24
24
 
25
25
  $ awspec init
26
26
 
27
- ### 2. Write *_spec.rb
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
- - [ ] Spec generator
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
- - awspec original concept -> https://github.com/marcy-terui/awspec
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
@@ -5,7 +5,8 @@ require 'awspec/version'
5
5
  require 'awspec/cli'
6
6
  require 'awspec/matcher'
7
7
  require 'awspec/helper'
8
- require 'awspec/ext/string'
8
+ require 'awspec/ext'
9
+ require 'awspec/generator'
9
10
 
10
11
  module Awspec
11
12
  end
@@ -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 awspec spec_helper.rb'
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
@@ -0,0 +1,2 @@
1
+ require 'awspec/ext/string'
2
+ require 'awspec/ext/struct'
@@ -0,0 +1,8 @@
1
+ class Struct
2
+ def tag_name
3
+ tag = self[:tags].find do |t|
4
+ t[:key] == 'Name'
5
+ end
6
+ tag[:value] if tag
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ require 'awspec/generator/spec/ec2'
2
+ require 'awspec/generator/spec/rds'
3
+ require 'awspec/generator/spec/vpc'
4
+ require 'awspec/generator/spec/security_group'
@@ -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
@@ -1,4 +1,5 @@
1
1
  require 'awspec/helper/type'
2
+ require 'awspec/helper/finder'
2
3
  extend Awspec::Helper::Type
3
4
  class RSpec::Core::ExampleGroup
4
5
  extend Awspec::Helper::Type
@@ -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,12 @@
1
+ module Awspec::Helper
2
+ module Finder
3
+ module S3
4
+ def find_bucket(id)
5
+ res = @s3_client.list_buckets
6
+ ret = @s3_client.list_buckets[:buckets].find do |bucket|
7
+ bucket.name == id
8
+ end
9
+ end
10
+ end
11
+ end
12
+ 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
- ret = resource.client.describe_subnets({
7
- filters: [{ name: 'tag:Name', values: [subnet_id] }]
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 |subnet|
17
- subnet[:subnet_identifier] == subnet_id
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 |subnet|
27
- subnet[:subnet_identifier] == res[:subnets][0][:subnet_id]
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
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'yaml'
2
3
 
3
4
  module Awspec
4
5
  class Setup
@@ -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
- attr_reader :id, :ec2_client
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
@@ -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 = @client.describe_addresses(option)
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)
@@ -4,12 +4,7 @@ module Awspec::Type
4
4
 
5
5
  def initialize(id)
6
6
  super
7
- @client = Aws::RDS::Client.new
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 = @client.describe_db_parameters(
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 = @client.list_resource_record_sets({
12
- hosted_zone_id: @id
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)
@@ -1,26 +1,21 @@
1
1
  module Awspec::Type
2
2
  class S3 < Base
3
- attr_reader :client, :bucket
3
+ attr_reader :s3_client, :bucket
4
4
 
5
5
  def initialize(id)
6
6
  super
7
- @client = Aws::S3::Client.new
8
- res = @client.list_buckets
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 = @client.head_object({
18
- bucket: @id,
19
- key: key.sub(%r(\A/), '')
20
- })
12
+ res = @s3_client.head_object({
13
+ bucket: @id,
14
+ key: key.sub(%r(\A/), '')
15
+ })
21
16
  res
22
- rescue
23
- false
17
+ rescue
18
+ false
24
19
  end
25
20
  end
26
21
  end
@@ -1,3 +1,3 @@
1
1
  module Awspec
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
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-03 00:00:00.000000000 Z
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