eipmap 0.0.1 → 0.1.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: a2f1c0b232fc62fb36c85f964b4d3f94c15180e4
4
- data.tar.gz: 97f4786d8f7e010c992f722c86f8c35bfd3bd649
3
+ metadata.gz: 1351fbe44fd9d8e912acd128d43ae4a121d8f9a3
4
+ data.tar.gz: a784a527ae399411c25cf5563784f9fc61c0adb9
5
5
  SHA512:
6
- metadata.gz: 210bd9e16c09a217d9fe01b975c4a17587772a197a1a36d3b2354d45a28a6317cc16492a4047c2746e1e3535d41cc9e5422c3ed1828b92872788b6f5c5f095b1
7
- data.tar.gz: 401a8d6b544f153daea65898a8d698ea6d090e2d25d2b5a3444fd6d539544aa525d0e0c2a154566f8305e5db46d4ae0a3c63310891fdff38d987661722557752
6
+ metadata.gz: bb29f18f62383b9dfb9157869324b0a8281c7bddf04cc6fbeebc8dd58a3a3560dff64208ca9d8cf14c48a3968c936ccbd8282d9d08233661f6d9c6dd35ca5893
7
+ data.tar.gz: 7caba6ba8454074e0c909b9c1ecee939d7898d1f2f1ce2a40c1929b1836896a5746ee65082d549586bc8cca1045630470be4e4b84de95cf7f187072c1444c5da
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --require rspec/instafail
2
+ --format RSpec::Instafail
3
+ --colour
4
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script:
5
+ - bundle install
6
+ - bundle exec rake
7
+ env:
8
+ global:
9
+ - secure: "aD9louz2hQ0gp47u2ScLLeQ7MiWQKlKNLR4Ux+U6KMO/sLMnktDcBGSi01lYt/+8yA6WyD3p/ceZv/e18enuRQU3ce5i3W8Xb11uAke0za44lTP5pllI13uTz0kHB9tmRS8MRSRtT2GV9HOcGJrW8td2YhImLwfc17pVOL2NnTc="
10
+ - secure: "ghKQZ8jbFpQnvRWnXO9eSNRjKOZJsGoq53Og5gH4KEdIEKIMBhnek7gOt34BfDFWSULJ7HRuuyIaftCy6r6rDJfV01zc88Pp+cRsf2LCfEpbEmXWBh8lBLYz0vneq6uoYpQ3y7FhedVkM89gQlbZ3snrykvr6j2FS6v/TUCgctc="
11
+ - EIPMAP_TEST_AWS_REGION=ap-southeast-1
data/README.md CHANGED
@@ -5,6 +5,8 @@ Eipmap is a tool to manage Elastic IP Addresses (EIP).
5
5
  It defines the state of EIP using DSL, and updates EIP according to DSL.
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/eipmap.svg)](http://badge.fury.io/rb/eipmap)
8
+ [![Build Status](https://travis-ci.org/winebarrel/eipmap.svg?branch=master)](https://travis-ci.org/winebarrel/eipmap)
9
+ [![Coverage Status](https://coveralls.io/repos/winebarrel/eipmap/badge.png?branch=master)](https://coveralls.io/r/winebarrel/eipmap?branch=master)
8
10
 
9
11
  ## Installation
10
12
 
@@ -28,10 +30,10 @@ Or install it yourself as:
28
30
  export AWS_ACCESS_KEY_ID='...'
29
31
  export AWS_SECRET_ACCESS_KEY='...'
30
32
  export AWS_REGION='us-east-1'
31
- eipmap -e -o EIPfile # export EIP
33
+ eipmap -e -o EIPfile # export EIP status
32
34
  vi EIPfile
33
35
  eipmap -a --dry-run
34
- eipmap -a # apply `EIPfile` to EIP
36
+ eipmap -a # apply `EIPfile`
35
37
  ```
36
38
 
37
39
  ## Help
data/Rakefile CHANGED
@@ -1,2 +1,5 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
2
3
 
4
+ RSpec::Core::RakeTask.new('spec')
5
+ task :default => :spec
data/eipmap.gemspec CHANGED
@@ -22,4 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency "term-ansicolor"
23
23
  spec.add_development_dependency 'bundler'
24
24
  spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '>= 3.0.0'
26
+ spec.add_development_dependency 'rspec-instafail'
27
+ spec.add_development_dependency 'coveralls'
25
28
  end
data/lib/eipmap/client.rb CHANGED
@@ -3,7 +3,8 @@ class Eipmap::Client
3
3
 
4
4
  def initialize(options = {})
5
5
  @options = options
6
- @ec2 = Aws::EC2::Client.new
6
+ aws_config = options.delete(:aws_config) || {}
7
+ @ec2 = Aws::EC2::Client.new(aws_config)
7
8
  @driver = Eipmap::Driver.new(@ec2, options)
8
9
  end
9
10
 
@@ -1,3 +1,3 @@
1
1
  module Eipmap
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -0,0 +1,119 @@
1
+ describe Eipmap do
2
+ let(:eips) do
3
+ eips = describe_addresses["vpc"].keys.zip(
4
+ describe_network_interface.map {|interface_id, private_ips|
5
+ { network_interface_id: interface_id,
6
+ private_ip_address: private_ips.first}})
7
+ Hash[*eips.flatten]
8
+ end
9
+
10
+ context "when no association" do
11
+ it do
12
+ dsl = <<-EOS
13
+ domain "vpc" do
14
+ <%- eips.each do |public_ip, attrs| -%>
15
+ ip "<%= public_ip %>"
16
+ <%- end -%>
17
+ end
18
+ EOS
19
+
20
+ result = apply { dsl }
21
+ expect(result).to be_falsey
22
+ expect(describe_addresses["vpc"].values).to match_array [{}, {}, {}]
23
+ end
24
+ end
25
+
26
+ context "when associate" do
27
+ it do
28
+ dsl = <<-EOS
29
+ domain "vpc" do
30
+ <%- eips.each do |public_ip, attrs| -%>
31
+ ip "<%= public_ip %>", <%= attrs.inspect %>
32
+ <%- end -%>
33
+ end
34
+ EOS
35
+
36
+ result = apply { dsl }
37
+ expect(result).to be_truthy
38
+ expect(describe_addresses["vpc"]).to eq eips
39
+ end
40
+ end
41
+
42
+ context "when disassociate" do
43
+ before do
44
+ apply {
45
+ <<-EOS
46
+ domain "vpc" do
47
+ <%- eips.each do |public_ip, attrs| -%>
48
+ ip "<%= public_ip %>", <%= attrs.inspect %>
49
+ <%- end -%>
50
+ end
51
+ EOS
52
+ }
53
+ end
54
+
55
+ it do
56
+ dsl = <<-EOS
57
+ domain "vpc" do
58
+ <%- eips.each do |public_ip, attrs| -%>
59
+ ip "<%= public_ip %>"
60
+ <%- end -%>
61
+ end
62
+ EOS
63
+
64
+ result = apply { dsl }
65
+ expect(result).to be_truthy
66
+ expect(describe_addresses["vpc"].values).to match_array [{}, {}, {}]
67
+ end
68
+ end
69
+
70
+ context "when swap association" do
71
+ let(:eips_with_one_assoc) do
72
+ eips.each_with_index do |(public_ip, attrs), i|
73
+ attrs.clear unless i.zero?
74
+ end
75
+
76
+ eips
77
+ end
78
+
79
+ let(:swapped_eips_with_one_assoc) do
80
+ public_ips = eips_with_one_assoc.keys
81
+ swapped = {}
82
+ mapping = {0 => 1, 1 => 0}
83
+
84
+ eips_with_one_assoc.each_with_index do |(public_ip, attrs), i|
85
+ ip_idx = mapping.fetch(i, i)
86
+ ip = public_ips[ip_idx]
87
+ swapped[public_ip] = eips_with_one_assoc[ip]
88
+ end
89
+
90
+ swapped
91
+ end
92
+
93
+ before do
94
+ apply {
95
+ <<-EOS
96
+ domain "vpc" do
97
+ <%- eips_with_one_assoc.each do |public_ip, attrs| -%>
98
+ ip "<%= public_ip %>", <%= attrs.inspect %>
99
+ <%- end -%>
100
+ end
101
+ EOS
102
+ }
103
+ end
104
+
105
+ it do
106
+ dsl = <<-EOS
107
+ domain "vpc" do
108
+ <%- swapped_eips_with_one_assoc.each do |public_ip, attrs| -%>
109
+ ip "<%= public_ip %>", <%= attrs.inspect %>
110
+ <%- end -%>
111
+ end
112
+ EOS
113
+
114
+ result = apply { dsl }
115
+ expect(result).to be_truthy
116
+ expect(describe_addresses["vpc"]).to eq swapped_eips_with_one_assoc
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,176 @@
1
+ if ENV['TRAVIS']
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
6
+ SimpleCov.start do
7
+ add_filter "spec/"
8
+ end
9
+ end
10
+
11
+ require 'erb'
12
+ require 'tempfile'
13
+ require 'eipmap'
14
+
15
+ # Amazon Linux AMI 2014.09 (HVM)
16
+ TEST_IMAGE_ID = 'ami-d6e1c584'
17
+
18
+ Aws.config.update(
19
+ access_key_id: ENV['EIPMAP_TEST_ACCESS_KEY_ID'],
20
+ secret_access_key: ENV['EIPMAP_TEST_AWS_SECRET_ACCESS_KEY'],
21
+ region: ENV['EIPMAP_TEST_AWS_REGION'])
22
+
23
+ $ec2 = Aws::EC2::Client.new
24
+
25
+ def run_instances(n)
26
+ resp = $ec2.run_instances(
27
+ image_id: TEST_IMAGE_ID,
28
+ min_count: n,
29
+ max_count: n,
30
+ instance_type: 't2.micro',
31
+ network_interfaces: [{
32
+ device_index: 0,
33
+ associate_public_ip_address: false}])
34
+
35
+ instance_ids = resp.instances.map(&:instance_id)
36
+ $ec2.wait_until(:instance_running, instance_ids: instance_ids)
37
+ $test_instances = resp.instances
38
+ end
39
+
40
+ def terminate_instances
41
+ instance_ids = $test_instances.map(&:instance_id)
42
+ $ec2.terminate_instances(instance_ids: instance_ids)
43
+ $ec2.wait_until(:instance_terminated, instance_ids: instance_ids)
44
+ end
45
+
46
+ def allocate_addresses(n)
47
+ $test_addresses = (1..n).map do
48
+ $ec2.allocate_address(domain: 'vpc')
49
+ end
50
+ end
51
+
52
+ def release_addresses
53
+ allocation_ids = $test_addresses.map(&:allocation_id)
54
+
55
+ allocation_ids.each do |allocation_id|
56
+ $ec2.release_address(allocation_id: allocation_id)
57
+ end
58
+ end
59
+
60
+ def disassociate_addresses
61
+ allocation_ids = $test_addresses.map(&:allocation_id)
62
+ resp = $ec2.describe_addresses(allocation_ids: allocation_ids)
63
+ association_ids = resp.addresses.map(&:association_id)
64
+
65
+ association_ids.each do |association_id|
66
+ next unless association_id
67
+ $ec2.disassociate_address(association_id: association_id)
68
+ end
69
+ end
70
+
71
+ def describe_network_interface
72
+ result = {}
73
+
74
+ $test_instances.each do |instance|
75
+ interface = instance.network_interfaces.first
76
+ interface_id = interface.network_interface_id
77
+ result[interface_id] = []
78
+
79
+ interface.private_ip_addresses.sort_by {|address|
80
+ address.primary ? '' : address.private_ip_address
81
+ }.each {|address|
82
+ result[interface_id] << address.private_ip_address
83
+ }
84
+ end
85
+
86
+ result
87
+ end
88
+
89
+ def describe_addresses
90
+ result = {}
91
+
92
+ $ec2.describe_addresses.each do |resp|
93
+ resp.addresses.each do |address|
94
+ domain = address.domain
95
+ public_ip = address.public_ip
96
+ result[domain] ||= {}
97
+ result[domain][public_ip] = {}
98
+
99
+ [:network_interface_id, :private_ip_address].each do |key|
100
+ value = address[key] || ''
101
+ result[domain][public_ip][key] = value unless value.empty?
102
+ end
103
+ end
104
+ end
105
+
106
+ result
107
+ end
108
+
109
+ def client(user_options = {})
110
+ options = {logger: Logger.new('/dev/null')}
111
+
112
+ if_debug do
113
+ logger = Eipmap::Logger.instance
114
+ logger.set_debug(true)
115
+ options.update(
116
+ debug: true,
117
+ logger: logger,
118
+ aws_config: {
119
+ http_wire_trace: true,
120
+ logger: logger})
121
+ end
122
+
123
+ options = options.merge(user_options)
124
+ Eipmap::Client.new(options)
125
+ end
126
+
127
+ def tempfile(content, options = {})
128
+ basename = "#{File.basename __FILE__}.#{$$}"
129
+ basename = [basename, options[:ext]] if options[:ext]
130
+
131
+ Tempfile.open(basename) do |f|
132
+ f.puts(content)
133
+ f.flush
134
+ f.rewind
135
+ yield(f)
136
+ end
137
+ end
138
+
139
+ def apply(cli = client)
140
+ elbfile = yield
141
+ elbfile = ERB.new(elbfile, nil, '-').result(binding)
142
+
143
+ if_debug do
144
+ puts <<-EOS
145
+ --- ELBfile ---
146
+ #{elbfile.strip}
147
+ ---------------
148
+ EOS
149
+ end
150
+
151
+ tempfile(elbfile) do |f|
152
+ cli.apply(f.path)
153
+ end
154
+ end
155
+
156
+ def if_debug
157
+ if ENV['DEBUG'] == '1'
158
+ yield
159
+ end
160
+ end
161
+
162
+ RSpec.configure do |config|
163
+ config.before(:all) do
164
+ run_instances(3)
165
+ allocate_addresses(3)
166
+ end
167
+
168
+ config.before(:each) do
169
+ disassociate_addresses
170
+ end
171
+
172
+ config.after(:all) do
173
+ terminate_instances
174
+ release_addresses
175
+ end
176
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eipmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Sugawara
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-12 00:00:00.000000000 Z
11
+ date: 2014-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-core
@@ -66,6 +66,48 @@ dependencies:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-instafail
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: coveralls
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
69
111
  description: Eipmap is a tool to manage Elastic IP Addresses (EIP). It defines the
70
112
  state of EIP using DSL, and updates EIP according to DSL.
71
113
  email:
@@ -76,6 +118,8 @@ extensions: []
76
118
  extra_rdoc_files: []
77
119
  files:
78
120
  - .gitignore
121
+ - .rspec
122
+ - .travis.yml
79
123
  - Gemfile
80
124
  - LICENSE.txt
81
125
  - README.md
@@ -93,6 +137,8 @@ files:
93
137
  - lib/eipmap/ext/string_ext.rb
94
138
  - lib/eipmap/logger.rb
95
139
  - lib/eipmap/version.rb
140
+ - spec/eipmap_spec.rb
141
+ - spec/spec_helper.rb
96
142
  homepage: https://github.com/winebarrel/eipmap
97
143
  licenses:
98
144
  - MIT
@@ -117,4 +163,6 @@ rubygems_version: 2.4.1
117
163
  signing_key:
118
164
  specification_version: 4
119
165
  summary: Eipmap is a tool to manage Elastic IP Addresses (EIP).
120
- test_files: []
166
+ test_files:
167
+ - spec/eipmap_spec.rb
168
+ - spec/spec_helper.rb