awsutils 2.0.3 → 2.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: 0f36e779b5b931a45339568e6ca14938acf904f7
4
- data.tar.gz: 2569db86afaf403fee076dc126f421c6fef32a46
3
+ metadata.gz: 5cd2972b98d1b03ecb9704dc58b10836697d9d9e
4
+ data.tar.gz: 1072bcfb550967e616027ecc9ebad509693c88de
5
5
  SHA512:
6
- metadata.gz: 9bfdc90b264970ab5023277cc8483a38655e7d717a1f08dbf8cff787b0cd3dd4b9383a6ed6365352835929740f8458aa26271ea3f1cd098531fb678235d5e98f
7
- data.tar.gz: 15ff775c7f3efae54eae92353a36b2d2a4c28d04486d8ef7be1c816b87ce7d659e935c698217d1697226f06355ccdd3c02a66e2b872e96a2b79f0eb537885a7f
6
+ metadata.gz: b58da8539855b7a01148655cab7fefad6d4d751bc066682aa85564267e82507f330c086c5033665c2a5ba888c968c117b1ebc9f28a85eb786b029cede28644ce
7
+ data.tar.gz: c2f60425d9c4f43c888850857604402b799e144d2e7eb163943b6a83b413e664c1498ca31ce713a60f74ac35db5b184142e2cbcfd4aeb29a070f0815fe50cece
data/README.md CHANGED
@@ -18,6 +18,10 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
+ awslogs
22
+ -------
23
+ Dumps logs from CloudWatch Logs for easy grepping (see `awslogs --help` for details).
24
+
21
25
  ec2listmachines
22
26
  ---------------
23
27
  Show a list of all EC2 instances in your account.
data/awsutils.gemspec CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_dependency 'facets', '~> 2.9'
30
30
  spec.add_dependency 'rainbow', '~> 2.0'
31
- spec.add_dependency 'fog-aws', '~> 0.9.1'
31
+ spec.add_dependency 'fog-aws', '~> 0.10.0'
32
32
  spec.add_dependency 'trollop'
33
+ spec.add_dependency 'aws-sdk'
33
34
  end
data/bin/awslogs ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Eric.
4
+ #
5
+ # The application 'awslogs' 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/awslogs'
12
+
13
+ awslogs = AwsUtils::AwsLogs.new
14
+ awslogs.print_events
@@ -0,0 +1,109 @@
1
+ require 'trollop'
2
+ require 'aws-sdk'
3
+ require 'time'
4
+
5
+ module AwsUtils
6
+ class AwsLogs
7
+ LOG_LEVELS = %w(TRACE DEBUG INFO NOTICE WARNING ERROR FATAL).freeze
8
+
9
+ def opts
10
+ @opts ||= Trollop.options do
11
+ opt :group,
12
+ 'Log group (e.g. /aws/lambda/sf-updater)',
13
+ required: true,
14
+ type: :string,
15
+ short: 'g'
16
+ opt :filter_pattern,
17
+ 'See: http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/FilterAndPatternSyntax.html',
18
+ short: 'f'
19
+ opt :streams_prefix,
20
+ 'E.g. 2016/08',
21
+ default: Time.now.strftime('%Y/%m/%d'),
22
+ short: 's'
23
+ opt :timestamp,
24
+ 'Include the timestamp from the event metadata in the output',
25
+ short: 't',
26
+ default: false
27
+ opt :show_request_id,
28
+ 'Show the request ID in every log message',
29
+ short: 'r',
30
+ default: false
31
+ opt :log_level,
32
+ 'Lowest log level to show',
33
+ default: 'INFO',
34
+ short: 'l'
35
+ opt :show_stream_name,
36
+ 'Include the name of the log stream on the output line',
37
+ default: false
38
+ end
39
+ end
40
+
41
+ def chunk_events(streams_chunk, token = nil)
42
+ parameters = {
43
+ log_group_name: opts[:group],
44
+ log_stream_names: streams_chunk,
45
+ next_token: token
46
+ }
47
+ parameters[:filter_pattern] = opts[:filter_pattern] if opts[:filter_pattern]
48
+ response = cloudwatchlogs.filter_log_events parameters
49
+ collector = response.events
50
+ collector += chunk_events(streams_chunk, response.next_token) if response.next_token
51
+ collector
52
+ end
53
+
54
+ def log_events
55
+ # puts "Filtering from #{streams.count} streams in #{streams.count / 50 + 1} chunks"
56
+ collector = []
57
+ streams.each_slice(50) { |streams_chunk| collector += chunk_events(streams_chunk) }
58
+
59
+ puts 'No events found' if collector.empty?
60
+
61
+ collector.sort_by(&:timestamp)
62
+ end
63
+
64
+ def print_events
65
+ log_events.each do |ev|
66
+ if ev.message !~ /^\[(INFO|DEBUG|WARNING|ERROR|NOTICE)\]/ # Check if the message is in the standard format
67
+ print "#{ev.log_stream_name}: " if opts[:show_stream_name]
68
+ print Time.at(ev.timestamp / 1e3).iso8601(3) + ' ' if opts[:timestamp]
69
+ print ev.message
70
+ next
71
+ end
72
+
73
+ msg_parts = ev.message.split("\t")
74
+ level = msg_parts[0].scan(/\[(\w*)\]/)[-1][0]
75
+ timestamp = msg_parts[1]
76
+ request_id = msg_parts[2]
77
+ message = msg_parts[3..-1].join("\t")
78
+
79
+ next unless show_logentry? level
80
+
81
+ print "#{ev.log_stream_name}: " if opts[:show_stream_name]
82
+ print Time.at(ev.timestamp / 1e3).iso8601(3) if opts[:timestamp]
83
+ printf('%-24s %-10s', timestamp, "[#{level}]")
84
+ printf('%-37s', request_id) if opts[:show_request_id]
85
+ print(message)
86
+ end
87
+ end
88
+
89
+ def show_logentry?(level)
90
+ return true unless LOG_LEVELS.include? level
91
+ LOG_LEVELS.index(level.upcase) >= LOG_LEVELS.index(opts[:log_level].upcase)
92
+ end
93
+
94
+ def streams(token = nil)
95
+ response = cloudwatchlogs.describe_log_streams(
96
+ log_group_name: opts[:group],
97
+ log_stream_name_prefix: opts[:streams_prefix],
98
+ next_token: token
99
+ )
100
+ collector = response.log_streams.map(&:log_stream_name)
101
+ collector += streams(response.next_token) if response.next_token
102
+ collector
103
+ end
104
+
105
+ def cloudwatchlogs
106
+ @cloudwatchlogs ||= Aws::CloudWatchLogs::Client.new
107
+ end
108
+ end
109
+ end
@@ -40,17 +40,32 @@ module AwsUtils
40
40
  end
41
41
 
42
42
  def run
43
- fail ArgumentError, 'Please specify a security group' unless search
43
+ raise ArgumentError, 'Please specify a security group' unless search
44
44
  unless group_o = group(search) # rubocop:disable Lint/AssignmentInCondition
45
- fail GroupDoesNotExist
45
+ raise GroupDoesNotExist
46
46
  end
47
47
  return group_details(group_o) unless opts[:list_refs]
48
48
  refs = references(group_o.group_id)
49
49
  if refs.empty?
50
50
  puts 'No references'
51
51
  else
52
- puts "References: #{refs.keys.join(', ')}"
53
- puts refs.to_yaml if opts[:verbose]
52
+ print_refs refs
53
+ end
54
+ end
55
+
56
+ def print_refs(refs)
57
+ refs.each do |grp, data|
58
+ print "#{grp} (#{data['groupId']}): "
59
+ perm_strings = data['references'].map do |perm|
60
+ if perm['ipProtocol'] == '-1'
61
+ 'all'
62
+ else
63
+ "#{perm['ipProtocol']}/#{perm['fromPort']}" +
64
+ (perm['fromPort'] != perm['toPort'] ? "-#{perm['toPort']}" : '')
65
+ end
66
+ end
67
+ print perm_strings.join ', '
68
+ puts ''
54
69
  end
55
70
  end
56
71
 
@@ -64,7 +79,7 @@ module AwsUtils
64
79
  def group_perm_string(group_perm)
65
80
  group_perm.map do |g|
66
81
  if g['userId'] == owner_id
67
- "#{g['groupId']} (#{group(g['groupId']).name})"
82
+ "#{g['groupId']} (#{group(g['groupId']).group_name})"
68
83
  else
69
84
  "#{g['groupId']} (#{g['groupName']}, owner: #{g['userId']})"
70
85
  end
@@ -1,46 +1,42 @@
1
- require 'rubygems'
2
1
  require 'fog/aws'
3
2
 
4
3
  module AwsUtils
5
4
  class Ec2SecurityGroup
6
5
  def connection
7
- @connection ||= begin
8
- options = {}
6
+ @connection ||= Fog::Compute::AWS.new
7
+ end
9
8
 
10
- if ENV['AWS_ACCESS_KEY']
11
- options = {
12
- aws_access_key_id: ENV['AWS_ACCESS_KEY'],
13
- aws_secret_access_key: ENV['AWS_SECRET_KEY']
9
+ def references(search_string)
10
+ search =
11
+ if search_string =~ /^sg-/
12
+ {
13
+ id: search_string,
14
+ name: groups.find { |gr| gr.group_id == search_string }.name
15
+ }
16
+ else
17
+ {
18
+ id: groups.find { |gr| gr.name == search_string }.group_id,
19
+ name: search_string
14
20
  }
15
21
  end
16
22
 
17
- Fog::Compute::AWS.new options
18
- end
19
- end
20
-
21
- def references(search)
22
- if search =~ /^sg-/
23
- search_id = search
24
- else
25
- search_id = groups.find { |g| g.name == search }.group_id
26
- end
27
-
28
23
  groups.each_with_object({}) do |grp, m|
29
- assoc_p = grp.ip_permissions.select do |ip_perm|
30
- !ip_perm['groups'].select { |src_grp|
31
- src_grp['groupName'] == search ||
32
- src_grp['groupId'] == search_id
33
- }.empty?
24
+ permission_references = grp.ip_permissions.select do |ip_perm|
25
+ ip_perm['groups'].find do |pair|
26
+ pair['groupId'] == search[:id] ||
27
+ pair['groupName'] == search[:name]
28
+ end
34
29
  end
35
- if assoc_p.empty?
36
- next
37
- else
38
- m[grp.name] = {
30
+
31
+ next if permission_references.empty?
32
+
33
+ m[grp.name] = { 'groupId' => grp.group_id }
34
+ m[grp.name]['references'] = permission_references.map do |pr|
35
+ {
39
36
  'groupId' => grp.group_id,
40
- 'ipPermissions' => assoc_p.map do |ap|
41
- ap.delete('ipRanges')
42
- ap
43
- end
37
+ 'ipProtocol' => pr['ipProtocol'],
38
+ 'fromPort' => pr['fromPort'],
39
+ 'toPort' => pr['toPort']
44
40
  }
45
41
  end
46
42
  end
@@ -57,7 +53,7 @@ module AwsUtils
57
53
  server.tags['Name'] ? server.tags['Name'] : server.id
58
54
  end.compact
59
55
 
60
- return false unless servers_using_group.length > 0
56
+ return false unless servers_using_group.empty?
61
57
  print 'The following servers are still using this group: '
62
58
  puts servers_using_group.join(',')
63
59
 
@@ -1,3 +1,3 @@
1
1
  module AwsUtils
2
- VERSION = '2.0.3'
2
+ VERSION = '2.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awsutils
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Herot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-25 00:00:00.000000000 Z
11
+ date: 2016-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 0.9.1
145
+ version: 0.10.0
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 0.9.1
152
+ version: 0.10.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: trollop
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -164,10 +164,25 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: aws-sdk
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: A set of tools for interacting with AWS
168
182
  email:
169
183
  - eric.rubygems@herot.com
170
184
  executables:
185
+ - awslogs
171
186
  - ec2addsg
172
187
  - ec2delsg
173
188
  - ec2info
@@ -185,6 +200,7 @@ files:
185
200
  - README.md
186
201
  - Rakefile
187
202
  - awsutils.gemspec
203
+ - bin/awslogs
188
204
  - bin/ec2addsg
189
205
  - bin/ec2delsg
190
206
  - bin/ec2info
@@ -194,6 +210,7 @@ files:
194
210
  - bin/elbls
195
211
  - bin/r53ls
196
212
  - lib/awsutils.rb
213
+ - lib/awsutils/awslogs.rb
197
214
  - lib/awsutils/ec2addsg.rb
198
215
  - lib/awsutils/ec2delsg.rb
199
216
  - lib/awsutils/ec2info.rb