awsutils 1.4.3

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7e9c0c5ccbb5b28296e0ea15174e5ef48fda9e06
4
+ data.tar.gz: 919e54bb3529d58f2bab3a667a697be25709e1d6
5
+ SHA512:
6
+ metadata.gz: aab47d2180061d775aa6308b97716ffe6d2aede604660cc3930d2b52f0a1df9078a718ab6b5b68006b5a512caebd8e9d1ae641e004bc4c3b5a4ed0d4d092d97c
7
+ data.tar.gz: c777d93d7359b11ecfc214f99f2dacdc494d5ec069fd993ce31ec625e3e5d77788c41fdc61003d5111b5bd2576fc6fa7468de5907c2f31a22f91d275fa0ad894
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'gemfury'
7
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,58 @@
1
+ # Awsutils
2
+
3
+ A set of useful tools for interacting with Amazon Web Services (AWS)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'awsutils'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install awsutils
18
+
19
+ ## Usage
20
+
21
+ ec2listmachines
22
+ ---------------
23
+ Show a list of all EC2 instances in your account.
24
+
25
+ ec2info
26
+ -------
27
+ Display very detailed info about a single instance (-s/--short for a concise version).
28
+
29
+ ec2addsg
30
+ --------
31
+ Create an EC2 security group with a set of pre-defined (from a YAML file) rules. Here's an example YAML file:
32
+
33
+ ```YAML
34
+ ---
35
+ - source: 1.2.3.4/32
36
+ proto: tcp
37
+ port: !ruby/range
38
+ begin: 22
39
+ end: 22
40
+ source: sample_group
41
+ proto: tcp
42
+ port: !ruby/range
43
+ begin: 22
44
+ end: 22
45
+ - dest: eherot_test
46
+ proto: tcp
47
+ port: !ruby/range
48
+ begin: 22
49
+ end: 22
50
+ ```
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create new Pull Request
@@ -0,0 +1,11 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ RuboCop::RakeTask.new
8
+
9
+ RSpec::Core::RakeTask.new(:spec)
10
+
11
+ task default: [:rubocop, :spec]
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'awsutils/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'awsutils'
8
+ spec.version = AwsUtils::VERSION
9
+ spec.authors = ['Eric Herot']
10
+ spec.email = ['eric.rubygems@herot.com']
11
+ spec.description = %q{A set of tools for interacting with AWS}
12
+ spec.summary = %q{A set of tools for interacting with AWS (summary)}
13
+ spec.homepage = 'http://github.com/eherot'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($RS)
17
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'pry'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'rspec'
25
+ spec.add_development_dependency 'rubocop'
26
+ spec.add_development_dependency 'simplecov'
27
+ spec.add_development_dependency 'byebug'
28
+
29
+ spec.add_dependency 'facets', '~> 2.9'
30
+ spec.add_dependency 'rainbow', '~> 2.0'
31
+ spec.add_dependency 'fog-aws', '~> 0.7.6'
32
+ spec.add_dependency 'trollop'
33
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'ec2listmachines' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+ require 'awsutils/version'
11
+ require 'awsutils/ec2addsg'
12
+
13
+ sg = AwsUtils::Ec2AddSecurityGroup.new
14
+ sg.run
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'ec2listmachines' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+ require 'awsutils/version'
11
+ require 'awsutils/ec2delsg'
12
+
13
+ sg = AwsUtils::Ec2DeleteSecurityGroup.new( ARGV )
14
+ sg.run
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'ec2listmachines' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+ require 'awsutils/version'
11
+ require 'awsutils/ec2info'
12
+
13
+ AwsUtils::Ec2Info.new
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'ec2lsgrp' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'awsutils/version'
10
+ require 'awsutils/ec2latestimage'
11
+
12
+ AwsUtils::Ec2LatestImage.new.run
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'ec2listmachines' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+ require 'awsutils/version'
11
+ require 'awsutils/ec2listmachines'
12
+
13
+ AwsUtils::Ec2ListMachines.new
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'ec2lsgrp' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ begin
10
+ require 'rubygems'
11
+ require 'awsutils/version'
12
+ require 'awsutils/ec2lsgrp'
13
+
14
+ begin
15
+ AwsUtils::Ec2LsGrp.new.run
16
+ rescue AwsUtils::GroupDoesNotExist
17
+ puts 'No group found by that name/ID'
18
+ exit 2
19
+ rescue ArgumentError => e
20
+ puts "#{e.class}: #{e.message}"
21
+ exit 3
22
+ end
23
+ rescue Interrupt
24
+ exit 1
25
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'r53ls' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'awsutils/version'
10
+ require 'awsutils/elbls'
11
+
12
+ elbls = AwsUtils::ElbLs.new
13
+ elbls.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'r53ls' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+ require 'awsutils/version'
11
+ require 'awsutils/r53ls'
12
+
13
+ r = AwsUtils::Route53ListResourceRecord.new
14
+ r.run
@@ -0,0 +1 @@
1
+ require 'awsutils/version'
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'awsutils/ec2sg'
4
+ require 'trollop'
5
+
6
+ module AwsUtils
7
+ class Ec2AddSecurityGroup < Ec2SecurityGroup
8
+ def g_obj
9
+ @g_obj ||= begin
10
+ connection.security_groups.new(
11
+ name: @opts[:security_group],
12
+ description: "#{@opts[:description]}",
13
+ vpc_id: @opts[:vpc_id]
14
+ )
15
+ end
16
+ end
17
+
18
+ def generate_rule_hash(rule)
19
+ if rule['source']
20
+ if rule['dest']
21
+ fail 'One of the predefined rules has both a source ' \
22
+ 'and a destination already defined: ' + rule.inspect
23
+ end
24
+ if rule['source'] !~ /\./ &&
25
+ !current_groups.include?(rule['source'])
26
+ fail "Group #{rule['source']} specified as part of rule: " \
27
+ "#{rule.inspect} does not exist"
28
+ end
29
+ end
30
+
31
+ if !rule['dest']
32
+ rule['dest'] = @new_group_id
33
+ elsif !current_groups.include?(rule['dest'])
34
+ fail "Group #{rule['dest']} specified as part of rule: " \
35
+ "#{rule.inspect} does not exist"
36
+ end
37
+
38
+ ip_permissions = {}
39
+
40
+ ip_permissions['IpProtocol'] = rule['proto'] if rule['proto']
41
+
42
+ if rule['port']
43
+ ip_permissions['FromPort'] = rule['port'].first.to_s
44
+ ip_permissions['ToPort'] = rule['port'].last.to_s
45
+ end
46
+
47
+ if rule['source'] =~ /\./
48
+ ip_permissions['Groups'] = []
49
+ ip_permissions['IpRanges'] = [ 'CidrIp' => rule['source'] ]
50
+ elsif rule['source']
51
+ ip_permissions['Groups'] = [
52
+ {
53
+ 'GroupId' => rule['source'],
54
+ 'UserId' => @opts[:owner_group_id]
55
+ }
56
+ ]
57
+ ip_permissions['IpRanges'] = []
58
+ end
59
+
60
+ rule['IpPermissions'] = [ip_permissions]
61
+
62
+ rule
63
+ end
64
+
65
+ def add_rule_to_other_group(rule)
66
+ rule['IpPermissions'].each do |r|
67
+ r['Groups'] = [
68
+ {
69
+ 'GroupId' => g_obj.group_id,
70
+ 'UserId' => @opts[:owner_group_id]
71
+ }
72
+ ]
73
+ end
74
+
75
+ puts 'Adding Outbound Rule: ' + rule.inspect
76
+
77
+ connection.authorize_security_group_ingress(
78
+ nil,
79
+ 'GroupId' => rule['dest'],
80
+ 'IpPermissions' => rule['IpPermissions']
81
+ )
82
+ end
83
+
84
+ def add_rule_to_this_group(rule)
85
+ rule['IpPermissions'].each do |r|
86
+ r['Groups'] = [
87
+ {
88
+ 'GroupId' => rule['source'],
89
+ 'UserId' => @opts[:owner_group_id]
90
+ }
91
+ ]
92
+ r['dest'] = g_obj.group_id
93
+ end
94
+
95
+ puts 'Adding Inbound Rule: ' + rule.inspect
96
+
97
+ connection.authorize_security_group_ingress(
98
+ nil,
99
+ 'GroupId' => g_obj.group_id,
100
+ 'IpPermissions' => rule['IpPermissions']
101
+ )
102
+ end
103
+
104
+ def save(rules)
105
+ g_obj.save
106
+ puts "New group ID: #{g_obj.group_id}"
107
+
108
+ begin
109
+ rules.reject { |rule| rule['dest'] }.each do |rule|
110
+ add_rule_to_this_group(rule)
111
+ end
112
+
113
+ # Then process the outbound rules now that we have a group_id
114
+ rules.select { |rule| rule['dest'] }.each do |rule|
115
+ add_rule_to_other_group(rule)
116
+ end
117
+ rescue => e
118
+ connection.delete_security_group(nil, g_obj.group_id)
119
+ raise e
120
+ end
121
+ end
122
+
123
+ def initialize
124
+ @opts = parse_opts
125
+ end
126
+
127
+ def name
128
+ @opts[:security_group]
129
+ end
130
+
131
+ def compile_rules
132
+ rules_data = YAML.load_file(@opts[:base_rules_file])
133
+
134
+ if @opts[:environment]
135
+ if !rules_data['env']
136
+ fail "Environment #{@opts[:environment]} not present in rules file" \
137
+ " (#{@opts[:base_rules_file]})."
138
+ else
139
+ rules_env_data = rules_data['env'][@opts[:environment]]
140
+ end
141
+ elsif rules_data.class != Array
142
+ fail 'base_rules_file is an environment-keyed file but you did ' \
143
+ 'not specify an environment.'
144
+ else
145
+ rules_env_data = rules_data
146
+ end
147
+
148
+ rules_env_data.map do |rule|
149
+ generate_rule_hash(rule)
150
+ end
151
+ end
152
+
153
+ def run
154
+ unless File.exist?(@opts[:base_rules_file])
155
+ puts "File #{@opts[:base_rules_file]} does not exist!"
156
+ exit 1
157
+ end
158
+
159
+ if exist?
160
+ puts "Group #{@opts[:security_group]} already exists!"
161
+ exit 1
162
+ end
163
+
164
+ save(compile_rules)
165
+ end
166
+
167
+ def parse_opts
168
+ fail 'AWS_OWNER_ID is not set!' unless ENV['AWS_OWNER_ID']
169
+
170
+ @opts = Trollop.options do
171
+ opt :security_group,
172
+ 'New Security Group Name',
173
+ short: 'N',
174
+ type: String,
175
+ required: true
176
+ opt :vpc_id,
177
+ 'New Group VPC ID',
178
+ short: 'v',
179
+ type: String
180
+ opt :base_rules_file,
181
+ 'Base rules YAML file',
182
+ short: 'r',
183
+ default: ENV['EC2_BASE_RULES'] || "#{ENV['HOME']}/.ec2baserules.yml"
184
+ opt :description,
185
+ 'New Group Description',
186
+ short: 'd',
187
+ type: String,
188
+ required: true
189
+ opt :environment,
190
+ 'New Group Environment (e.g. stage/prod)',
191
+ short: 'E',
192
+ type: String
193
+ opt :owner_group_id,
194
+ 'Owner Group ID',
195
+ short: 'o',
196
+ default: ENV['AWS_OWNER_ID']
197
+ end
198
+ end
199
+ end
200
+ end