ec2_hosts 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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +40 -0
- data/Rakefile +6 -0
- data/bin/ec2_hosts +6 -0
- data/ec2_hosts.gemspec +32 -0
- data/lib/ec2_hosts/hosts.rb +132 -0
- data/lib/ec2_hosts/options.rb +84 -0
- data/lib/ec2_hosts/runner.rb +37 -0
- data/lib/ec2_hosts/updater.rb +176 -0
- data/lib/ec2_hosts/version.rb +3 -0
- data/lib/ec2_hosts.rb +12 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f3d3a81641bffc23b95c18e6979f3847387c9f65
|
4
|
+
data.tar.gz: 4798f749b1729aae57c0fc72bba3a0a67a4ffa27
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0628070a21cf3c3cb8d4cf0429b77e68077d822cfa97978201b650d9a92abd316cc8f33056b398e4e86a980ed774ccf9b5de08ce3c72b9dba597c46c945062ea
|
7
|
+
data.tar.gz: c8a91a6e75de1ab71968ec13c62933471ec902cb1c6d2723681e0d66d118fe7b420c66f69ea9b2728c97f02e82159b237379c1194832a95bb6551967e3526448
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# ec2_hosts
|
2
|
+
|
3
|
+
Update your hosts file based on ec2 compute instances.
|
4
|
+
|
5
|
+
This is handy when used in conjunction with something like [sshuttle](https://github.com/sshuttle/sshuttle),
|
6
|
+
allowing you to have a "poor man's vpn".
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
```shell
|
11
|
+
$ gem install ec2_hosts
|
12
|
+
```
|
13
|
+
|
14
|
+
## Requirements
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
## Example
|
19
|
+
|
20
|
+
Update your hosts file using ec2_hosts:
|
21
|
+
|
22
|
+
```shell
|
23
|
+
$ sudo ec2_hosts -p my-cool-project --public bastion
|
24
|
+
|
25
|
+
```
|
26
|
+
Start sshuttle session:
|
27
|
+
|
28
|
+
```shell
|
29
|
+
$ sshuttle --remote=bastion01 --daemon --pidfile=/tmp/sshuttle.pid 192.168.1.0/24
|
30
|
+
```
|
31
|
+
|
32
|
+
Now your hosts file will contain entries for all compute instances in the project,
|
33
|
+
and you can ssh directly to them from your local machine.
|
34
|
+
|
35
|
+
Hosts matching the pattern passed in with the `--public` flag will have their public
|
36
|
+
IP address added to your host file instead of the their private internal IP address.
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/atongen/ec2_hosts](https://github.com/atongen/ec2_hosts).
|
data/Rakefile
ADDED
data/bin/ec2_hosts
ADDED
data/ec2_hosts.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ec2_hosts/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ec2_hosts"
|
8
|
+
spec.version = Ec2Hosts::VERSION
|
9
|
+
spec.authors = ["Andrew Tongen"]
|
10
|
+
spec.email = ["atongen@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Update your hosts file based on aws ec2 compute instances}
|
13
|
+
spec.description = %q{Update your hosts file based on aws ec2 compute instances}
|
14
|
+
spec.homepage = "https://github.com/atongen/ec2_hosts"
|
15
|
+
|
16
|
+
if spec.respond_to?(:metadata)
|
17
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
18
|
+
else
|
19
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
20
|
+
end
|
21
|
+
|
22
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
|
+
spec.bindir = "bin"
|
24
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
|
27
|
+
spec.add_dependency "aws-sdk-v1", "~> 1.60"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
30
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
31
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
32
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module Ec2Hosts
|
2
|
+
class Hosts
|
3
|
+
|
4
|
+
attr_reader :ec2,
|
5
|
+
:options
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
# Creds must be present in environment
|
9
|
+
@ec2 = AWS::EC2.new
|
10
|
+
@options = options
|
11
|
+
if @options[:tags]
|
12
|
+
@processed_tags = process_tags(@options[:tags])
|
13
|
+
elsif @options[:template]
|
14
|
+
@processed_template = process_template(@options[:template])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def vpc
|
19
|
+
return @vpc if instance_variable_defined?(:@vpc)
|
20
|
+
|
21
|
+
vpcs = ec2.vpcs.filter("tag:Name", options[:vpc]).map {|v|v}
|
22
|
+
|
23
|
+
if vpcs.length > 1
|
24
|
+
raise ArgumentError.new("Multiple VPCs with name '#{options[:vpc]}' found.")
|
25
|
+
elsif vpcs.length == 0
|
26
|
+
raise ArgumentError.new("VPC '#{options[:vpc]}' not found.")
|
27
|
+
end
|
28
|
+
|
29
|
+
@vpc = vpcs.first
|
30
|
+
end
|
31
|
+
|
32
|
+
def instances
|
33
|
+
return @instances if instance_variable_defined?(:@instances)
|
34
|
+
|
35
|
+
if options[:only_running]
|
36
|
+
@instances = vpc.instances.filter("instance-state-name", "running")
|
37
|
+
else
|
38
|
+
@instances = vpc.instances
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_a
|
43
|
+
raw = instances.inject({}) do |memo, inst|
|
44
|
+
hostname = ""
|
45
|
+
if @processed_tags
|
46
|
+
hostname = parse_tags_hostname(@processed_tags, inst.tags.map.to_a.to_h)
|
47
|
+
elsif @processed_template
|
48
|
+
hostname = parse_template_hostname(@processed_template, inst.tags.map.to_a.to_h)
|
49
|
+
else
|
50
|
+
hostname = inst.tags["Name"]
|
51
|
+
end
|
52
|
+
|
53
|
+
hostname = "" unless hostname_valid?(hostname)
|
54
|
+
|
55
|
+
if hostname == "" && !options[:ignore_missing]
|
56
|
+
hostname = inst.private_dns_name.split('.').first
|
57
|
+
end
|
58
|
+
|
59
|
+
if hostname != ""
|
60
|
+
memo[hostname] = inst
|
61
|
+
end
|
62
|
+
|
63
|
+
memo
|
64
|
+
end.sort.to_h
|
65
|
+
|
66
|
+
list = []
|
67
|
+
|
68
|
+
raw.each do |hostname, inst|
|
69
|
+
begin
|
70
|
+
if !options[:public].nil? && hostname.downcase.include?(options[:public])
|
71
|
+
if !options[:exclude_public]
|
72
|
+
# get public ip address
|
73
|
+
if ip = inst.public_ip_address
|
74
|
+
list << "#{ip} #{hostname}"
|
75
|
+
raise HostError.new
|
76
|
+
end
|
77
|
+
end
|
78
|
+
else
|
79
|
+
# get private ip address
|
80
|
+
if ip = inst.private_ip_address
|
81
|
+
list << "#{ip} #{hostname}"
|
82
|
+
raise HostError.new
|
83
|
+
end
|
84
|
+
end
|
85
|
+
rescue HostError; end
|
86
|
+
end
|
87
|
+
|
88
|
+
list
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def process_template(template)
|
94
|
+
template.split(/({\w+})/).select { |s| s != "" }.map do |snip|
|
95
|
+
if m = snip.match(/\A{(\w+)}\Z/)
|
96
|
+
->(tags) { tags[m[1]] }
|
97
|
+
else
|
98
|
+
snip
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse_template_hostname(template, instance_tags)
|
104
|
+
result = template.map do |snip|
|
105
|
+
if snip.is_a?(Proc)
|
106
|
+
snip.call(instance_tags)
|
107
|
+
else
|
108
|
+
snip
|
109
|
+
end
|
110
|
+
end
|
111
|
+
if result.any? { |r| r.nil? }
|
112
|
+
""
|
113
|
+
else
|
114
|
+
result.join.gsub('_', '-')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def process_tags(tags)
|
119
|
+
tags.split(",").select { |s| s != "" }
|
120
|
+
end
|
121
|
+
|
122
|
+
def parse_tags_hostname(tags, instance_tags)
|
123
|
+
tags.map do |tag|
|
124
|
+
instance_tags[tag]
|
125
|
+
end.compact.join("-").gsub('_', '-')
|
126
|
+
end
|
127
|
+
|
128
|
+
def hostname_valid?(hostname)
|
129
|
+
!!hostname.to_s.match(/\A[A-Za-z]+[0-9A-Za-z-]*\Z/)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Ec2Hosts
|
4
|
+
class Options
|
5
|
+
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
@options = {
|
10
|
+
vpc: nil,
|
11
|
+
tags: nil,
|
12
|
+
template: nil,
|
13
|
+
ignore_missing: true,
|
14
|
+
only_running: true,
|
15
|
+
public: nil,
|
16
|
+
exclude_public: false,
|
17
|
+
file: '/etc/hosts',
|
18
|
+
backup: nil,
|
19
|
+
dry_run: false,
|
20
|
+
delete: false,
|
21
|
+
clear: false
|
22
|
+
}
|
23
|
+
parser.parse!(args)
|
24
|
+
|
25
|
+
if @options[:backup].nil?
|
26
|
+
@options[:backup] = "#{@options[:file]}.bak"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def parser
|
33
|
+
@parser ||= begin
|
34
|
+
OptionParser.new do |opts|
|
35
|
+
opts.banner = "Usage: $ ec2_hosts [options]"
|
36
|
+
opts.on('-v', '--vpc VPC_NAME', "Name of VPC to use. Defaults to nil.") do |opt|
|
37
|
+
@options[:vpc] = opt
|
38
|
+
end
|
39
|
+
opts.on('--tags TAGS', "CSV of tag names used to build host name. Defaults to nil.") do |opt|
|
40
|
+
@options[:tags] = opt
|
41
|
+
end
|
42
|
+
opts.on('--template TEMPLATE', "Template string to build hostname from instance tags. Defaults to nil.") do |opt|
|
43
|
+
@options[:template] = opt
|
44
|
+
end
|
45
|
+
opts.on('-i', '--[no-]ignore-missing', "Ignore hosts with no matching tags, or invalid template. Defaults to true.") do |opt|
|
46
|
+
@options[:ignore_missing] = opt
|
47
|
+
end
|
48
|
+
opts.on('-r', '--[no-]only-running', "Only list running instances. Defaults to true.") do |opt|
|
49
|
+
@options[:only_running] = opt
|
50
|
+
end
|
51
|
+
opts.on('-p', '--public PUBLIC', "Pattern to match for public/bastion hosts. Use public IP for these. Defaults to nil") do |opt|
|
52
|
+
@options[:public] = opt
|
53
|
+
end
|
54
|
+
opts.on('--[no-]exclude-public', "Exclude public hosts from list when updating hosts file. Allows them to be managed manually. Defaults to false") do |opt|
|
55
|
+
@options[:exclude_public] = opt
|
56
|
+
end
|
57
|
+
opts.on('-f', '--file FILE', "Hosts file to update. Defaults to /etc/hosts") do |opt|
|
58
|
+
@options[:file] = opt
|
59
|
+
end
|
60
|
+
opts.on('-b', '--backup BACKUP', "Path to backup original hosts file to. Defaults to FILE with '.bak' extension appended.") do |opt|
|
61
|
+
@options[:file] = opt
|
62
|
+
end
|
63
|
+
opts.on('--[no-]dry-run', "Dry run, do not modify hosts file. Defaults to false") do |opt|
|
64
|
+
@options[:dry_run] = opt
|
65
|
+
end
|
66
|
+
opts.on('--[no-]delete', "Delete the VPC from hosts file. Defaults to false") do |opt|
|
67
|
+
@options[:delete] = opt
|
68
|
+
end
|
69
|
+
opts.on('--[no-]clear', "Clear all ec2 host entries from hosts file. Defaults to false") do |opt|
|
70
|
+
@options[:clear] = opt
|
71
|
+
end
|
72
|
+
opts.on_tail("--help", "Show this message") do
|
73
|
+
puts opts
|
74
|
+
exit
|
75
|
+
end
|
76
|
+
opts.on_tail("--version", "Show version") do
|
77
|
+
puts ::Ec2Hosts::VERSION
|
78
|
+
exit
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Ec2Hosts
|
2
|
+
class Runner
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
@options = Options.new(args).options
|
6
|
+
end
|
7
|
+
|
8
|
+
def run!
|
9
|
+
if @options[:vpc] && @options[:clear]
|
10
|
+
raise ArgumentError.new("Cannot specify 'clear' and 'vpc' at the same time.")
|
11
|
+
end
|
12
|
+
|
13
|
+
if @options[:tags] && @options[:template]
|
14
|
+
raise ArgumentError.new("Cannot specify 'tags' and 'template' at the same time.")
|
15
|
+
end
|
16
|
+
|
17
|
+
updater = Updater.new(@options)
|
18
|
+
|
19
|
+
if @options[:clear]
|
20
|
+
updater.clear
|
21
|
+
else
|
22
|
+
if @options[:vpc].nil?
|
23
|
+
raise ArgumentError.new("No ec2 vpc specified.")
|
24
|
+
end
|
25
|
+
|
26
|
+
if @options[:delete]
|
27
|
+
new_hosts_list = []
|
28
|
+
else
|
29
|
+
hosts = Hosts.new(@options)
|
30
|
+
new_hosts_list = hosts.to_a
|
31
|
+
end
|
32
|
+
|
33
|
+
updater.update(new_hosts_list)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module Ec2Hosts
|
2
|
+
# Updater implements a simple state machine which is used to update
|
3
|
+
# content between zero or more blocks of content which start and end
|
4
|
+
# with pre-defined "marker" lines.
|
5
|
+
class Updater
|
6
|
+
|
7
|
+
module Marker
|
8
|
+
BEFORE = 0
|
9
|
+
INSIDE = 1
|
10
|
+
AFTER = 2
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :options
|
14
|
+
|
15
|
+
def initialize(options = {})
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def update(new_hosts)
|
20
|
+
old_hosts = File.read(options[:file])
|
21
|
+
|
22
|
+
if old_hosts.include?(start_marker) && old_hosts.include?(end_marker)
|
23
|
+
# valid markers exists
|
24
|
+
if options[:delete]
|
25
|
+
new_content = delete_vpc_hosts(old_hosts)
|
26
|
+
else
|
27
|
+
new_content = gen_new_hosts(old_hosts, new_hosts)
|
28
|
+
end
|
29
|
+
|
30
|
+
# remove zero or more white space characters at end of file with
|
31
|
+
# a single new-line
|
32
|
+
new_content.gsub!(/\s+$/, "\n")
|
33
|
+
|
34
|
+
if options[:dry_run]
|
35
|
+
puts new_content
|
36
|
+
elsif new_content != old_hosts
|
37
|
+
# backup old host file
|
38
|
+
File.open(options[:backup], 'w') { |f| f << old_hosts }
|
39
|
+
# write new content
|
40
|
+
File.open(options[:file], 'w') { |f| f << new_content }
|
41
|
+
end
|
42
|
+
elsif old_hosts.include?(start_marker) || old_hosts.include?(end_marker)
|
43
|
+
raise UpdaterError.new("Invalid marker present in existing hosts content")
|
44
|
+
else
|
45
|
+
# marker doesn't exist
|
46
|
+
if options[:delete]
|
47
|
+
new_content = old_hosts
|
48
|
+
else
|
49
|
+
new_content = [old_hosts, start_marker, new_hosts, end_marker].join("\n")
|
50
|
+
end
|
51
|
+
# remove one or more white space characters at end of file with
|
52
|
+
# a single new-line
|
53
|
+
new_content.gsub!(/\s+$/, "\n")
|
54
|
+
|
55
|
+
if options[:dry_run]
|
56
|
+
puts new_content
|
57
|
+
elsif new_content != old_hosts
|
58
|
+
# backup old host file
|
59
|
+
File.open(options[:backup], 'w') { |f| f << old_hosts }
|
60
|
+
# write new content
|
61
|
+
File.open(options[:file], 'w') { |f| f << new_content }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
def clear
|
69
|
+
old_hosts = File.read(options[:file])
|
70
|
+
new_content = old_hosts.dup
|
71
|
+
|
72
|
+
markers = old_hosts.each_line.map do |line|
|
73
|
+
regex = "\# (START|END) EC2 HOSTS - (.+) \#"
|
74
|
+
if m = line.match(/^#{regex}$/)
|
75
|
+
m[2]
|
76
|
+
end
|
77
|
+
end.compact.uniq
|
78
|
+
|
79
|
+
markers.each do |project|
|
80
|
+
new_content = delete_vpc_hosts(new_content)
|
81
|
+
end
|
82
|
+
new_content.gsub!(/\s+$/, "\n")
|
83
|
+
|
84
|
+
if options[:dry_run]
|
85
|
+
puts new_content
|
86
|
+
elsif new_content != old_hosts
|
87
|
+
# backup old host file
|
88
|
+
File.open(options[:file], 'w') { |f| f << old_hosts }
|
89
|
+
# write new content
|
90
|
+
File.open(options[:file], 'w') { |f| f << new_content }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def gen_new_hosts(hosts, new_hosts)
|
97
|
+
new_content = ''
|
98
|
+
marker_state = Marker::BEFORE
|
99
|
+
hosts.split("\n").each do |line|
|
100
|
+
if line == start_marker
|
101
|
+
if marker_state == Marker::BEFORE
|
102
|
+
# transition to inside the marker
|
103
|
+
new_content << start_marker + "\n"
|
104
|
+
marker_state = Marker::INSIDE
|
105
|
+
# add new host content
|
106
|
+
new_hosts.split("\n").each do |host|
|
107
|
+
new_content << host + "\n"
|
108
|
+
end
|
109
|
+
else
|
110
|
+
raise UpdaterError.new("Invalid marker state")
|
111
|
+
end
|
112
|
+
elsif line == end_marker
|
113
|
+
if marker_state == Marker::INSIDE
|
114
|
+
# transition to after the marker
|
115
|
+
new_content << end_marker + "\n"
|
116
|
+
marker_state = Marker::AFTER
|
117
|
+
else
|
118
|
+
raise UpdaterError.new("Invalid marker state")
|
119
|
+
end
|
120
|
+
else
|
121
|
+
case marker_state
|
122
|
+
when Marker::BEFORE, Marker::AFTER
|
123
|
+
new_content << line + "\n"
|
124
|
+
when Marker::INSIDE
|
125
|
+
# skip everything between old markers
|
126
|
+
next
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
new_content
|
131
|
+
end
|
132
|
+
|
133
|
+
def delete_vpc_hosts(hosts)
|
134
|
+
new_content = ''
|
135
|
+
marker_state = Marker::BEFORE
|
136
|
+
hosts.split("\n").each do |line|
|
137
|
+
if line == start_marker
|
138
|
+
if marker_state == Marker::BEFORE
|
139
|
+
marker_state = Marker::INSIDE
|
140
|
+
# don't add any content, we're deleting this block
|
141
|
+
else
|
142
|
+
raise UpdaterError.new("Invalid marker state")
|
143
|
+
end
|
144
|
+
elsif line == end_marker
|
145
|
+
if marker_state == Marker::INSIDE
|
146
|
+
marker_state = Marker::AFTER
|
147
|
+
else
|
148
|
+
raise UpdaterError.new("Invalid marker state")
|
149
|
+
end
|
150
|
+
else
|
151
|
+
case marker_state
|
152
|
+
when Marker::BEFORE, Marker::AFTER
|
153
|
+
new_content << line + "\n"
|
154
|
+
when Marker::INSIDE
|
155
|
+
# skip everything between old markers
|
156
|
+
next
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
new_content
|
161
|
+
end
|
162
|
+
|
163
|
+
def start_marker
|
164
|
+
@start_marker ||= begin
|
165
|
+
"# START EC2 HOSTS - #{options[:vpc]} #"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def end_marker
|
170
|
+
@end_marker ||= begin
|
171
|
+
"# END EC2 HOSTS - #{options[:vpc]} #"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
data/lib/ec2_hosts.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'aws-sdk-v1'
|
2
|
+
|
3
|
+
require 'ec2_hosts/version'
|
4
|
+
require 'ec2_hosts/options'
|
5
|
+
require 'ec2_hosts/hosts'
|
6
|
+
require 'ec2_hosts/updater'
|
7
|
+
require 'ec2_hosts/runner'
|
8
|
+
|
9
|
+
module Ec2Hosts
|
10
|
+
class HostError < StandardError; end
|
11
|
+
class UpdaterError < StandardError; end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ec2_hosts
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Tongen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk-v1
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.60'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.60'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
description: Update your hosts file based on aws ec2 compute instances
|
70
|
+
email:
|
71
|
+
- atongen@gmail.com
|
72
|
+
executables:
|
73
|
+
- ec2_hosts
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- ".travis.yml"
|
80
|
+
- Gemfile
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- bin/ec2_hosts
|
84
|
+
- ec2_hosts.gemspec
|
85
|
+
- lib/ec2_hosts.rb
|
86
|
+
- lib/ec2_hosts/hosts.rb
|
87
|
+
- lib/ec2_hosts/options.rb
|
88
|
+
- lib/ec2_hosts/runner.rb
|
89
|
+
- lib/ec2_hosts/updater.rb
|
90
|
+
- lib/ec2_hosts/version.rb
|
91
|
+
homepage: https://github.com/atongen/ec2_hosts
|
92
|
+
licenses: []
|
93
|
+
metadata:
|
94
|
+
allowed_push_host: https://rubygems.org
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.5.1
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Update your hosts file based on aws ec2 compute instances
|
115
|
+
test_files: []
|