eipmap 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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